From cd868df2617ca546ff8992f5047fb6fa26a477cc Mon Sep 17 00:00:00 2001 From: busya Date: Sun, 17 May 2026 14:18:02 +0300 Subject: [PATCH] fix(health): suppress 404 when health monitor disabled + fix audit test assertion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Sidebar.svelte: defer healthStore.refresh() until feature flags confirm health_monitor is enabled; skip entirely when disabled - health.js: remove throw error from catch block — log and return null instead, preventing 'Uncaught (in promise)' on expected 404 - test_report_audit_immutability.py: fix mock assertions — audit_service uses logger.reason/reflect/explore, not logger.info - HealthStore and Sidebar now produce zero network noise when FEATURES__HEALTH_MONITOR=false --- .axiom/semantic_index/index.json | 16840 +++++++--------- .../artifacts.json | 1 + .../bootstrap.json | 1 + .../test_tui_real_mode_bootstrap_icurrent | 1 + .axiom/temp/pytest-of-busya/pytest-current | 2 +- .opencode/agents/closure-gate.md | 2 +- .opencode/agents/fullstack-coder.md | 2 +- .opencode/agents/qa-tester.md | 2 +- .opencode/agents/reflection-agent.md | 2 +- .opencode/agents/semantic-curator.md | 26 +- .opencode/agents/speckit.md | 2 +- .opencode/agents/svelte-coder.md | 2 +- .opencode/agents/swarm-master.md | 2 +- .opencode/skills/semantics-belief/SKILL.md | 100 - backend/git_repos/remote/test-repo.git/HEAD | 1 + backend/git_repos/remote/test-repo.git/config | 4 + .../remote/test-repo.git/description | 1 + .../test-repo.git/hooks/applypatch-msg.sample | 15 + .../test-repo.git/hooks/commit-msg.sample | 24 + .../hooks/fsmonitor-watchman.sample | 174 + .../test-repo.git/hooks/post-update.sample | 8 + .../test-repo.git/hooks/pre-applypatch.sample | 14 + .../test-repo.git/hooks/pre-commit.sample | 49 + .../hooks/pre-merge-commit.sample | 13 + .../test-repo.git/hooks/pre-push.sample | 53 + .../test-repo.git/hooks/pre-rebase.sample | 169 + .../test-repo.git/hooks/pre-receive.sample | 24 + .../hooks/prepare-commit-msg.sample | 42 + .../hooks/push-to-checkout.sample | 78 + .../hooks/sendemail-validate.sample | 77 + .../remote/test-repo.git/hooks/update.sample | 128 + .../remote/test-repo.git/info/exclude | 6 + .../00/fcf77cecdf261aef91eda792ab3384a3339922 | Bin 0 -> 592 bytes .../17/66251d8cb2693136e09ea3def3e776559cb722 | 2 + .../22/91d2eb86d77accf7401f8952778809cd1aa4d4 | Bin 0 -> 33 bytes .../22/c0ea49cea7e5138fb91b25b1bc0e101ae6e017 | Bin 0 -> 395 bytes .../38/0395343915d386a8d58774cc6c6677205065e8 | Bin 0 -> 508 bytes .../3e/05ec6ef6504483c4bc7d00f0d0272c38ec661f | 1 + .../48/c3fde4d5fff5bf98e9bcaa5f328b199aa18292 | Bin 0 -> 396 bytes .../4e/227f4d8289ea657ae813b1460f979ae4b676b3 | Bin 0 -> 176 bytes .../4f/4e0958b3a42eff67a2b8cfd084d05c43e54716 | Bin 0 -> 1191 bytes .../52/ec4a78c629329b8b572ec9d5205271c111baac | Bin 0 -> 72 bytes .../59/3a37acec7d2bddce10df90ab17bc9ede52e523 | Bin 0 -> 380 bytes .../5a/82ef700fef88b69cd480e4025283809496ee20 | Bin 0 -> 168 bytes .../5d/9eb555c4cac2d3ffdba84c07682b154fe4180d | Bin 0 -> 133 bytes .../6a/f2b28e314c04fb4e03476c12d6491213591512 | 1 + .../6f/85e20ce3ef98cf07a2f102498b71b9462552c5 | Bin 0 -> 68 bytes .../71/47ad0836409b35c1650dddf5fa6329ba61a824 | Bin 0 -> 58 bytes .../79/b070ad8af7bbc12169f7660d2a7a72ec7a889a | Bin 0 -> 407 bytes .../8c/4ea7958b7a7e140d27e1e7d8d1f9912fdf5992 | Bin 0 -> 517 bytes .../93/9cc583a18267406014c57617ccb557569f6aaf | Bin 0 -> 50 bytes .../99/38d17c3f4199e53e4d4ebc253fe9c840caa505 | Bin 0 -> 217 bytes .../a1/3525f5f44e26d8fbec3226bd488d14793575a2 | 1 + .../a7/49f11fad695dff77faf1708c7320867d0be1df | Bin 0 -> 217 bytes .../aa/ea042a37c6f7bd010d91db93951328da7f01cc | Bin 0 -> 54 bytes .../ae/8d2f5dec5d421b2d6cc1eebaad6d2ef901a90d | 2 + .../c2/491dfd8c841bacd5f491510f6334aa4a626f00 | Bin 0 -> 91 bytes .../c5/b992984fe856bd81206304a881faa3087937cf | Bin 0 -> 188 bytes .../cf/d2dcbd55735b8cedf21e04e64ac627c6f9a458 | Bin 0 -> 210 bytes .../d5/0298a42699f39e4601c0aa23eab07bcb0703c7 | 1 + .../d8/3fe0db1279ef07c4c4f3de4156a629373b4057 | 4 + .../e9/1109abe29d5228675fecd6fc38a097147c090d | Bin 0 -> 10181 bytes .../ed/0432f88f5f7d95b26ecde34345abe741dd9db2 | Bin 0 -> 217 bytes .../ee/59553241ef084b83d3351ba4c33caf2ed9a840 | Bin 0 -> 199 bytes .../f7/6ee984d9d47c3cd0b362fdf60a47162bbc202d | Bin 0 -> 442 bytes .../remote/test-repo.git/refs/heads/dev | 1 + .../refs/heads/feature/e2e-update | 1 + .../test-repo.git/refs/heads/feature/test | 1 + .../remote/test-repo.git/refs/heads/main | 1 + .../remote/test-repo.git/refs/heads/master | 1 + .../remote/test-repo.git/refs/heads/preprod | 1 + .../api/routes/git/_repo_operations_routes.py | 10 +- backend/src/api/routes/translate/__init__.py | 21 +- .../routes/translate/_correction_routes.py | 18 +- .../routes/translate/_dictionary_routes.py | 26 +- backend/src/api/routes/translate/_helpers.py | 2 +- .../src/api/routes/translate/_job_routes.py | 25 +- .../api/routes/translate/_metrics_routes.py | 10 +- .../api/routes/translate/_preview_routes.py | 16 +- backend/src/api/routes/translate/_router.py | 1 + .../api/routes/translate/_run_list_routes.py | 12 +- .../src/api/routes/translate/_run_routes.py | 28 +- .../api/routes/translate/_schedule_routes.py | 18 +- backend/src/models/translate.py | 2 +- backend/src/plugins/git_plugin.py | 258 +- backend/src/plugins/translate/__init__.py | 1 - .../src/plugins/translate/_token_budget.py | 44 +- backend/src/plugins/translate/dictionary.py | 139 +- backend/src/plugins/translate/executor.py | 32 +- backend/src/plugins/translate/metrics.py | 27 +- backend/src/plugins/translate/orchestrator.py | 10 + backend/src/plugins/translate/plugin.py | 6 +- backend/src/plugins/translate/preview.py | 33 +- .../src/plugins/translate/prompt_builder.py | 7 +- backend/src/plugins/translate/scheduler.py | 12 +- backend/src/plugins/translate/service.py | 16 +- .../src/plugins/translate/sql_generator.py | 10 +- .../plugins/translate/superset_executor.py | 72 +- backend/src/schemas/translate.py | 4 +- backend/src/services/git/_base.py | 285 +- backend/src/services/git/_branch.py | 119 +- backend/src/services/git/_gitea.py | 42 +- backend/src/services/git/_merge.py | 147 +- backend/src/services/git/_remote_providers.py | 16 +- backend/src/services/git/_status.py | 31 +- backend/src/services/git/_sync.py | 22 +- .../test_report_audit_immutability.py | 16 +- docker-compose.yml | 2 +- e2e_final_dashboard.png | Bin 0 -> 144978 bytes e2e_profile_01.png | Bin 0 -> 104921 bytes e2e_settings_01_environments.png | Bin 0 -> 163726 bytes e2e_settings_02_edit_env.png | Bin 0 -> 197229 bytes e2e_settings_03_git.png | Bin 0 -> 172288 bytes e2e_settings_04_llm.png | Bin 0 -> 224435 bytes e2e_settings_05_storage.png | Bin 0 -> 146217 bytes e2e_settings_06_logging.png | Bin 0 -> 149604 bytes e2e_settings_07_connections.png | Bin 0 -> 139996 bytes e2e_settings_08_migration.png | Bin 0 -> 239096 bytes e2e_settings_09_features.png | Bin 0 -> 148260 bytes e2e_settings_10_automation.png | Bin 0 -> 146313 bytes e2e_settings_11_users.png | Bin 0 -> 136063 bytes e2e_settings_12_roles.png | Bin 0 -> 183328 bytes .../src/components/git/CommitModal.svelte | 2 + frontend/src/components/git/GitManager.svelte | 8 +- frontend/src/lib/api.js | 4 +- .../src/lib/components/layout/Sidebar.svelte | 21 +- .../translate/BulkCorrectionSidebar.svelte | 26 +- .../translate/ScheduleConfig.svelte | 23 +- .../translate/TermCorrectionPopup.svelte | 27 +- .../TranslationMetricsDashboard.svelte | 22 +- .../translate/TranslationPreview.svelte | 30 +- .../TranslationRunGlobalIndicator.svelte | 1 - .../translate/TranslationRunProgress.svelte | 34 +- .../translate/TranslationRunResult.svelte | 32 +- frontend/src/lib/stores/health.js | 2 +- frontend/src/lib/stores/translationRun.js | 19 +- frontend/src/routes/translate/+page.svelte | 22 - .../src/routes/translate/[id]/+page.svelte | 30 - .../translate/dictionaries/+page.svelte | 26 - .../translate/dictionaries/[id]/+page.svelte | 30 - .../src/routes/translate/history/+page.svelte | 14 - 141 files changed, 9631 insertions(+), 10165 deletions(-) create mode 100644 .axiom/temp/pytest-of-busya/pytest-2/test_tui_real_mode_bootstrap_i0/artifacts.json create mode 100644 .axiom/temp/pytest-of-busya/pytest-2/test_tui_real_mode_bootstrap_i0/bootstrap.json create mode 120000 .axiom/temp/pytest-of-busya/pytest-2/test_tui_real_mode_bootstrap_icurrent delete mode 100644 .opencode/skills/semantics-belief/SKILL.md create mode 100644 backend/git_repos/remote/test-repo.git/HEAD create mode 100644 backend/git_repos/remote/test-repo.git/config create mode 100644 backend/git_repos/remote/test-repo.git/description create mode 100755 backend/git_repos/remote/test-repo.git/hooks/applypatch-msg.sample create mode 100755 backend/git_repos/remote/test-repo.git/hooks/commit-msg.sample create mode 100755 backend/git_repos/remote/test-repo.git/hooks/fsmonitor-watchman.sample create mode 100755 backend/git_repos/remote/test-repo.git/hooks/post-update.sample create mode 100755 backend/git_repos/remote/test-repo.git/hooks/pre-applypatch.sample create mode 100755 backend/git_repos/remote/test-repo.git/hooks/pre-commit.sample create mode 100755 backend/git_repos/remote/test-repo.git/hooks/pre-merge-commit.sample create mode 100755 backend/git_repos/remote/test-repo.git/hooks/pre-push.sample create mode 100755 backend/git_repos/remote/test-repo.git/hooks/pre-rebase.sample create mode 100755 backend/git_repos/remote/test-repo.git/hooks/pre-receive.sample create mode 100755 backend/git_repos/remote/test-repo.git/hooks/prepare-commit-msg.sample create mode 100755 backend/git_repos/remote/test-repo.git/hooks/push-to-checkout.sample create mode 100755 backend/git_repos/remote/test-repo.git/hooks/sendemail-validate.sample create mode 100755 backend/git_repos/remote/test-repo.git/hooks/update.sample create mode 100644 backend/git_repos/remote/test-repo.git/info/exclude create mode 100644 backend/git_repos/remote/test-repo.git/objects/00/fcf77cecdf261aef91eda792ab3384a3339922 create mode 100644 backend/git_repos/remote/test-repo.git/objects/17/66251d8cb2693136e09ea3def3e776559cb722 create mode 100644 backend/git_repos/remote/test-repo.git/objects/22/91d2eb86d77accf7401f8952778809cd1aa4d4 create mode 100644 backend/git_repos/remote/test-repo.git/objects/22/c0ea49cea7e5138fb91b25b1bc0e101ae6e017 create mode 100644 backend/git_repos/remote/test-repo.git/objects/38/0395343915d386a8d58774cc6c6677205065e8 create mode 100644 backend/git_repos/remote/test-repo.git/objects/3e/05ec6ef6504483c4bc7d00f0d0272c38ec661f create mode 100644 backend/git_repos/remote/test-repo.git/objects/48/c3fde4d5fff5bf98e9bcaa5f328b199aa18292 create mode 100644 backend/git_repos/remote/test-repo.git/objects/4e/227f4d8289ea657ae813b1460f979ae4b676b3 create mode 100644 backend/git_repos/remote/test-repo.git/objects/4f/4e0958b3a42eff67a2b8cfd084d05c43e54716 create mode 100644 backend/git_repos/remote/test-repo.git/objects/52/ec4a78c629329b8b572ec9d5205271c111baac create mode 100644 backend/git_repos/remote/test-repo.git/objects/59/3a37acec7d2bddce10df90ab17bc9ede52e523 create mode 100644 backend/git_repos/remote/test-repo.git/objects/5a/82ef700fef88b69cd480e4025283809496ee20 create mode 100644 backend/git_repos/remote/test-repo.git/objects/5d/9eb555c4cac2d3ffdba84c07682b154fe4180d create mode 100644 backend/git_repos/remote/test-repo.git/objects/6a/f2b28e314c04fb4e03476c12d6491213591512 create mode 100644 backend/git_repos/remote/test-repo.git/objects/6f/85e20ce3ef98cf07a2f102498b71b9462552c5 create mode 100644 backend/git_repos/remote/test-repo.git/objects/71/47ad0836409b35c1650dddf5fa6329ba61a824 create mode 100644 backend/git_repos/remote/test-repo.git/objects/79/b070ad8af7bbc12169f7660d2a7a72ec7a889a create mode 100644 backend/git_repos/remote/test-repo.git/objects/8c/4ea7958b7a7e140d27e1e7d8d1f9912fdf5992 create mode 100644 backend/git_repos/remote/test-repo.git/objects/93/9cc583a18267406014c57617ccb557569f6aaf create mode 100644 backend/git_repos/remote/test-repo.git/objects/99/38d17c3f4199e53e4d4ebc253fe9c840caa505 create mode 100644 backend/git_repos/remote/test-repo.git/objects/a1/3525f5f44e26d8fbec3226bd488d14793575a2 create mode 100644 backend/git_repos/remote/test-repo.git/objects/a7/49f11fad695dff77faf1708c7320867d0be1df create mode 100644 backend/git_repos/remote/test-repo.git/objects/aa/ea042a37c6f7bd010d91db93951328da7f01cc create mode 100644 backend/git_repos/remote/test-repo.git/objects/ae/8d2f5dec5d421b2d6cc1eebaad6d2ef901a90d create mode 100644 backend/git_repos/remote/test-repo.git/objects/c2/491dfd8c841bacd5f491510f6334aa4a626f00 create mode 100644 backend/git_repos/remote/test-repo.git/objects/c5/b992984fe856bd81206304a881faa3087937cf create mode 100644 backend/git_repos/remote/test-repo.git/objects/cf/d2dcbd55735b8cedf21e04e64ac627c6f9a458 create mode 100644 backend/git_repos/remote/test-repo.git/objects/d5/0298a42699f39e4601c0aa23eab07bcb0703c7 create mode 100644 backend/git_repos/remote/test-repo.git/objects/d8/3fe0db1279ef07c4c4f3de4156a629373b4057 create mode 100644 backend/git_repos/remote/test-repo.git/objects/e9/1109abe29d5228675fecd6fc38a097147c090d create mode 100644 backend/git_repos/remote/test-repo.git/objects/ed/0432f88f5f7d95b26ecde34345abe741dd9db2 create mode 100644 backend/git_repos/remote/test-repo.git/objects/ee/59553241ef084b83d3351ba4c33caf2ed9a840 create mode 100644 backend/git_repos/remote/test-repo.git/objects/f7/6ee984d9d47c3cd0b362fdf60a47162bbc202d create mode 100644 backend/git_repos/remote/test-repo.git/refs/heads/dev create mode 100644 backend/git_repos/remote/test-repo.git/refs/heads/feature/e2e-update create mode 100644 backend/git_repos/remote/test-repo.git/refs/heads/feature/test create mode 100644 backend/git_repos/remote/test-repo.git/refs/heads/main create mode 100644 backend/git_repos/remote/test-repo.git/refs/heads/master create mode 100644 backend/git_repos/remote/test-repo.git/refs/heads/preprod create mode 100644 e2e_final_dashboard.png create mode 100644 e2e_profile_01.png create mode 100644 e2e_settings_01_environments.png create mode 100644 e2e_settings_02_edit_env.png create mode 100644 e2e_settings_03_git.png create mode 100644 e2e_settings_04_llm.png create mode 100644 e2e_settings_05_storage.png create mode 100644 e2e_settings_06_logging.png create mode 100644 e2e_settings_07_connections.png create mode 100644 e2e_settings_08_migration.png create mode 100644 e2e_settings_09_features.png create mode 100644 e2e_settings_10_automation.png create mode 100644 e2e_settings_11_users.png create mode 100644 e2e_settings_12_roles.png diff --git a/.axiom/semantic_index/index.json b/.axiom/semantic_index/index.json index c88b167a..4f323e7d 100644 --- a/.axiom/semantic_index/index.json +++ b/.axiom/semantic_index/index.json @@ -1,8 +1,8 @@ { - "generated_at": "2026-05-15T18:40:14.207110454Z", + "generated_at": "2026-05-17T09:53:01.679154203Z", "root_path": "/home/busya/dev/ss-tools", - "contract_count": 2479, - "edge_count": 1776, + "contract_count": 2483, + "edge_count": 1759, "file_count": 535, "contracts": [ { @@ -18429,7 +18429,7 @@ "contract_type": "Module", "file_path": "backend/src/api/routes/llm.py", "start_line": 1, - "end_line": 425, + "end_line": 430, "tier": "TIER_2", "complexity": 3, "metadata": { @@ -18484,7 +18484,7 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region LlmRoutes [C:3] [TYPE Module] [SEMANTICS fastapi, llm, api, provider]\n# @BRIEF API routes for LLM provider configuration and management.\n# @LAYER: UI (API)\n# @RELATION DEPENDS_ON -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\n# @RELATION DEPENDS_ON -> [get_current_user]\n# @RELATION DEPENDS_ON -> [get_db]\n\n\nfrom fastapi import APIRouter, Depends, HTTPException, status\nfrom pydantic import BaseModel, Field\nfrom sqlalchemy.orm import Session\n\nfrom ...core.database import get_db\nfrom ...core.logger import logger\nfrom ...dependencies import get_current_user as get_current_active_user\nfrom ...plugins.llm_analysis.models import LLMProviderConfig, LLMProviderType\nfrom ...schemas.auth import User\nfrom ...services.llm_provider import LLMProviderService\n\n\n# #region FetchModelsRequest [C:1] [TYPE Class]\n# @BRIEF Pydantic request model for the fetch-models endpoint.\nclass FetchModelsRequest(BaseModel):\n base_url: str | None = Field(None, description=\"LLM provider base URL\")\n provider_type: str | None = Field(None, description=\"Provider type (openai, anthropic, etc)\")\n api_key: str | None = Field(None, description=\"Direct API key (takes precedence over provider_id)\")\n provider_id: str | None = Field(None, description=\"Saved provider ID to look up stored API key\")\n\n\n# #endregion FetchModelsRequest\n\n# #region router [TYPE Global]\n# @BRIEF APIRouter instance for LLM routes.\nrouter = APIRouter(tags=[\"LLM\"])\n# #endregion router\n\n\n# #region _is_valid_runtime_api_key [TYPE Function]\n# @BRIEF Validate decrypted runtime API key presence/shape.\n# @PRE: value can be None.\n# @POST: Returns True only for non-placeholder key.\n# @RELATION BINDS_TO -> [LlmRoutes]\ndef _is_valid_runtime_api_key(value: str | None) -> bool:\n key = (value or \"\").strip()\n if not key:\n return False\n if key in {\"********\", \"EMPTY_OR_NONE\"}:\n return False\n return len(key) >= 16\n\n\n# #endregion _is_valid_runtime_api_key\n\n\n# #region get_providers [TYPE Function]\n# @BRIEF Retrieve all LLM provider configurations.\n# @PRE: User is authenticated.\n# @POST: Returns list of LLMProviderConfig.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\n@router.get(\"/providers\", response_model=list[LLMProviderConfig])\nasync def get_providers(\n current_user: User = Depends(get_current_active_user), db: Session = Depends(get_db)\n):\n \"\"\"\n Get all LLM provider configurations.\n \"\"\"\n logger.reason(\n f\"Fetching providers for user: {current_user.username}\",\n extra={\"src\": \"llm_routes.get_providers\"},\n )\n service = LLMProviderService(db)\n providers = service.get_all_providers()\n return [\n LLMProviderConfig(\n id=p.id,\n provider_type=LLMProviderType(p.provider_type),\n name=p.name,\n base_url=p.base_url,\n api_key=\"********\",\n default_model=p.default_model,\n is_active=p.is_active,\n )\n for p in providers\n ]\n\n\n# #endregion get_providers\n\n\n# #region fetch_models [TYPE Function]\n# @BRIEF Fetch available models from an LLM provider by base_url+provider_type, or by provider_id.\n# @PRE: User is authenticated. Either provider_id or base_url+provider_type must be provided.\n# @POST: Returns a list of available model IDs.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION CALLS -> [LLMClient]\n@router.post(\"/providers/fetch-models\")\nasync def fetch_models(\n payload: FetchModelsRequest,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n from ...plugins.llm_analysis.models import LLMProviderType\n from ...plugins.llm_analysis.service import LLMClient\n\n base_url = (payload.base_url or \"\").strip()\n provider_type_str = (payload.provider_type or \"\").strip()\n api_key = payload.api_key or \"\"\n provider_id = payload.provider_id or \"\"\n\n # Early validation: at least one of api_key or provider_id is required\n if not api_key and not provider_id:\n raise HTTPException(\n status_code=400,\n detail=\"api_key or provider_id is required\",\n )\n\n # Resolve provider_id to stored credentials if no direct api_key given\n if not api_key and provider_id:\n service = LLMProviderService(db)\n db_provider = service.get_provider(provider_id)\n if not db_provider:\n raise HTTPException(status_code=404, detail=\"Provider not found\")\n base_url = base_url or db_provider.base_url\n provider_type_str = provider_type_str or db_provider.provider_type\n stored_key = service.get_decrypted_api_key(provider_id)\n if stored_key:\n api_key = stored_key\n\n if not base_url:\n raise HTTPException(status_code=400, detail=\"base_url is required\")\n if not provider_type_str:\n raise HTTPException(status_code=400, detail=\"provider_type is required\")\n\n try:\n provider_type = LLMProviderType(provider_type_str)\n except ValueError:\n raise HTTPException(status_code=400, detail=f\"Invalid provider_type: {provider_type_str}\")\n\n # Release DB connection before the network call to avoid idle-in-transaction\n # blocking other queries while we wait for the LLM API response.\n db.close()\n\n client = LLMClient(\n provider_type=provider_type,\n api_key=api_key or \"sk-placeholder\",\n base_url=base_url,\n default_model=\"\",\n )\n\n try:\n models = await client.fetch_models()\n return {\"models\": models}\n except Exception as e:\n logger.error(\n f\"[llm_routes.fetch_models] Failed to fetch models: {e}\",\n extra={\"src\": \"llm_routes.fetch_models\"},\n )\n raise HTTPException(status_code=502, detail=str(e))\n\n\n# #endregion fetch_models\n\n\n# #region get_llm_status [TYPE Function]\n# @BRIEF Returns whether LLM runtime is configured for dashboard validation.\n# @PRE: User is authenticated.\n# @POST: configured=true only when an active provider with valid decrypted key exists.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION CALLS -> [_is_valid_runtime_api_key]\n@router.get(\"/status\")\nasync def get_llm_status(\n current_user: User = Depends(get_current_active_user), db: Session = Depends(get_db)\n):\n service = LLMProviderService(db)\n providers = service.get_all_providers()\n active_provider = next((p for p in providers if p.is_active), None)\n\n if not providers:\n return {\n \"configured\": False,\n \"reason\": \"no_providers_configured\",\n \"provider_count\": 0,\n \"active_provider_count\": 0,\n }\n\n if not active_provider:\n return {\n \"configured\": False,\n \"reason\": \"no_active_provider\",\n \"provider_count\": len(providers),\n \"active_provider_count\": 0,\n \"providers\": [\n {\n \"id\": provider.id,\n \"name\": provider.name,\n \"provider_type\": provider.provider_type,\n \"is_active\": bool(provider.is_active),\n }\n for provider in providers\n ],\n }\n\n api_key = service.get_decrypted_api_key(active_provider.id)\n if not _is_valid_runtime_api_key(api_key):\n return {\n \"configured\": False,\n \"reason\": \"invalid_api_key\",\n \"provider_count\": len(providers),\n \"active_provider_count\": len(\n [provider for provider in providers if provider.is_active]\n ),\n \"provider_id\": active_provider.id,\n \"provider_name\": active_provider.name,\n \"provider_type\": active_provider.provider_type,\n \"default_model\": active_provider.default_model,\n }\n\n return {\n \"configured\": True,\n \"reason\": \"ok\",\n \"provider_count\": len(providers),\n \"active_provider_count\": len(\n [provider for provider in providers if provider.is_active]\n ),\n \"provider_id\": active_provider.id,\n \"provider_name\": active_provider.name,\n \"provider_type\": active_provider.provider_type,\n \"default_model\": active_provider.default_model,\n }\n\n\n# #endregion get_llm_status\n\n\n# #region create_provider [TYPE Function]\n# @BRIEF Create a new LLM provider configuration.\n# @PRE: User is authenticated and has admin permissions.\n# @POST: Returns the created LLMProviderConfig.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\n@router.post(\n \"/providers\", response_model=LLMProviderConfig, status_code=status.HTTP_201_CREATED\n)\nasync def create_provider(\n config: LLMProviderConfig,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n \"\"\"\n Create a new LLM provider configuration.\n \"\"\"\n service = LLMProviderService(db)\n provider = service.create_provider(config)\n return LLMProviderConfig(\n id=provider.id,\n provider_type=LLMProviderType(provider.provider_type),\n name=provider.name,\n base_url=provider.base_url,\n api_key=\"********\",\n default_model=provider.default_model,\n is_active=provider.is_active,\n )\n\n\n# #endregion create_provider\n\n\n# #region update_provider [TYPE Function]\n# @BRIEF Update an existing LLM provider configuration.\n# @PRE: User is authenticated and has admin permissions.\n# @POST: Returns the updated LLMProviderConfig.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\n@router.put(\"/providers/{provider_id}\", response_model=LLMProviderConfig)\nasync def update_provider(\n provider_id: str,\n config: LLMProviderConfig,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n \"\"\"\n Update an existing LLM provider configuration.\n \"\"\"\n service = LLMProviderService(db)\n provider = service.update_provider(provider_id, config)\n if not provider:\n raise HTTPException(status_code=404, detail=\"Provider not found\")\n\n return LLMProviderConfig(\n id=provider.id,\n provider_type=LLMProviderType(provider.provider_type),\n name=provider.name,\n base_url=provider.base_url,\n api_key=\"********\",\n default_model=provider.default_model,\n is_active=provider.is_active,\n )\n\n\n# #endregion update_provider\n\n\n# #region delete_provider [TYPE Function]\n# @BRIEF Delete an LLM provider configuration.\n# @PRE: User is authenticated and has admin permissions.\n# @POST: Returns success status.\n# @RELATION CALLS -> [LLMProviderService]\n@router.delete(\"/providers/{provider_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_provider(\n provider_id: str,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n \"\"\"\n Delete an LLM provider configuration.\n \"\"\"\n service = LLMProviderService(db)\n if not service.delete_provider(provider_id):\n raise HTTPException(status_code=404, detail=\"Provider not found\")\n return\n\n\n# #endregion delete_provider\n\n\n# #region test_connection [TYPE Function]\n# @BRIEF Test connection to an LLM provider.\n# @PRE: User is authenticated.\n# @POST: Returns success status and message.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [LLMClient]\n@router.post(\"/providers/{provider_id}/test\")\nasync def test_connection(\n provider_id: str,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n logger.reason(\n f\"Testing connection for provider_id: {provider_id}\",\n extra={\"src\": \"llm_routes.test_connection\"},\n )\n \"\"\"\n Test connection to an LLM provider.\n \"\"\"\n from ...plugins.llm_analysis.service import LLMClient\n\n service = LLMProviderService(db)\n db_provider = service.get_provider(provider_id)\n if not db_provider:\n raise HTTPException(status_code=404, detail=\"Provider not found\")\n\n api_key = service.get_decrypted_api_key(provider_id)\n\n # Check if API key was successfully decrypted\n if not api_key:\n logger.error(\n f\"[llm_routes][test_connection] Failed to decrypt API key for provider {provider_id}\"\n )\n raise HTTPException(\n status_code=500,\n detail=\"Failed to decrypt API key. The provider may have been encrypted with a different encryption key. Please update the provider with a new API key.\",\n )\n\n client = LLMClient(\n provider_type=LLMProviderType(db_provider.provider_type),\n api_key=api_key,\n base_url=db_provider.base_url,\n default_model=db_provider.default_model,\n )\n\n try:\n await client.test_runtime_connection()\n return {\"success\": True, \"message\": \"Connection successful\"}\n except Exception as e:\n return {\"success\": False, \"error\": str(e)}\n\n\n# #endregion test_connection\n\n\n# #region test_provider_config [TYPE Function]\n# @BRIEF Test connection with a provided configuration (not yet saved).\n# @PRE: User is authenticated.\n# @POST: Returns success status and message.\n# @RELATION DEPENDS_ON -> [LLMClient]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\n@router.post(\"/providers/test\")\nasync def test_provider_config(\n config: LLMProviderConfig, current_user: User = Depends(get_current_active_user)\n):\n \"\"\"\n Test connection with a provided configuration.\n \"\"\"\n from ...plugins.llm_analysis.service import LLMClient\n\n logger.reason(\n f\"Testing config for {config.name}\",\n extra={\"src\": \"llm_routes.test_provider_config\"},\n )\n\n # Check if API key is provided\n if not config.api_key or config.api_key == \"********\":\n raise HTTPException(\n status_code=400, detail=\"API key is required for testing connection\"\n )\n\n client = LLMClient(\n provider_type=config.provider_type,\n api_key=config.api_key,\n base_url=config.base_url,\n default_model=config.default_model,\n )\n\n try:\n await client.test_runtime_connection()\n return {\"success\": True, \"message\": \"Connection successful\"}\n except Exception as e:\n return {\"success\": False, \"error\": str(e)}\n\n\n# #endregion test_provider_config\n\n# #endregion LlmRoutes\n" + "body": "# #region LlmRoutes [C:3] [TYPE Module] [SEMANTICS fastapi, llm, api, provider]\n# @BRIEF API routes for LLM provider configuration and management.\n# @LAYER: UI (API)\n# @RELATION DEPENDS_ON -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\n# @RELATION DEPENDS_ON -> [get_current_user]\n# @RELATION DEPENDS_ON -> [get_db]\n\n\nfrom fastapi import APIRouter, Depends, HTTPException, status\nfrom pydantic import BaseModel, Field\nfrom sqlalchemy.orm import Session\n\nfrom ...core.database import get_db\nfrom ...core.logger import logger\nfrom ...dependencies import get_current_user as get_current_active_user\nfrom ...plugins.llm_analysis.models import LLMProviderConfig, LLMProviderType\nfrom ...schemas.auth import User\nfrom ...services.llm_provider import LLMProviderService, is_masked_or_placeholder, mask_api_key\n\n\n# #region FetchModelsRequest [C:1] [TYPE Class]\n# @BRIEF Pydantic request model for the fetch-models endpoint.\nclass FetchModelsRequest(BaseModel):\n base_url: str | None = Field(None, description=\"LLM provider base URL\")\n provider_type: str | None = Field(None, description=\"Provider type (openai, anthropic, etc)\")\n api_key: str | None = Field(None, description=\"Direct API key (takes precedence over provider_id)\")\n provider_id: str | None = Field(None, description=\"Saved provider ID to look up stored API key\")\n\n\n# #endregion FetchModelsRequest\n\n# #region router [TYPE Global]\n# @BRIEF APIRouter instance for LLM routes.\nrouter = APIRouter(tags=[\"LLM\"])\n# #endregion router\n\n\n# #region _is_valid_runtime_api_key [C:4] [TYPE Function]\n# @BRIEF Validate decrypted runtime API key presence/shape.\n# @PRE: value can be None.\n# @POST: Returns True only for non-placeholder key.\n# @RELATION BINDS_TO -> [LlmRoutes]\ndef _is_valid_runtime_api_key(value: str | None) -> bool:\n key = (value or \"\").strip()\n if not key:\n return False\n if key in {\"********\", \"EMPTY_OR_NONE\"}:\n return False\n return len(key) >= 16\n\n\n# #endregion _is_valid_runtime_api_key\n\n\n# #region get_providers [C:4] [TYPE Function]\n# @BRIEF Retrieve all LLM provider configurations.\n# @PRE: User is authenticated.\n# @POST: Returns list of LLMProviderConfig.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\n@router.get(\"/providers\", response_model=list[LLMProviderConfig])\nasync def get_providers(\n current_user: User = Depends(get_current_active_user), db: Session = Depends(get_db)\n):\n \"\"\"\n Get all LLM provider configurations.\n \"\"\"\n logger.reason(\n f\"Fetching providers for user: {current_user.username}\",\n extra={\"src\": \"llm_routes.get_providers\"},\n )\n service = LLMProviderService(db)\n providers = service.get_all_providers()\n return [\n LLMProviderConfig(\n id=p.id,\n provider_type=LLMProviderType(p.provider_type),\n name=p.name,\n base_url=p.base_url,\n api_key=mask_api_key(service.get_decrypted_api_key(p.id)) if p.api_key else \"\",\n default_model=p.default_model,\n is_active=p.is_active,\n )\n for p in providers\n ]\n\n\n# #endregion get_providers\n\n\n# #region fetch_models [C:4] [TYPE Function]\n# @BRIEF Fetch available models from an LLM provider by base_url+provider_type, or by provider_id.\n# @PRE: User is authenticated. Either provider_id or base_url+provider_type must be provided.\n# @POST: Returns a list of available model IDs.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION CALLS -> [LLMClient]\n@router.post(\"/providers/fetch-models\")\nasync def fetch_models(\n payload: FetchModelsRequest,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n from ...plugins.llm_analysis.models import LLMProviderType\n from ...plugins.llm_analysis.service import LLMClient\n\n base_url = (payload.base_url or \"\").strip()\n provider_type_str = (payload.provider_type or \"\").strip()\n api_key = payload.api_key or \"\"\n provider_id = payload.provider_id or \"\"\n\n # Treat masked/placeholder API keys as if no api_key was provided;\n # they are display-only and cannot be used for real API calls.\n if is_masked_or_placeholder(api_key):\n api_key = \"\"\n\n # Early validation: at least one of api_key or provider_id is required\n if not api_key and not provider_id:\n raise HTTPException(\n status_code=400,\n detail=\"api_key or provider_id is required\",\n )\n\n # Resolve provider_id to stored credentials if no direct api_key given\n if not api_key and provider_id:\n service = LLMProviderService(db)\n db_provider = service.get_provider(provider_id)\n if not db_provider:\n raise HTTPException(status_code=404, detail=\"Provider not found\")\n base_url = base_url or db_provider.base_url\n provider_type_str = provider_type_str or db_provider.provider_type\n stored_key = service.get_decrypted_api_key(provider_id)\n if stored_key:\n api_key = stored_key\n\n if not base_url:\n raise HTTPException(status_code=400, detail=\"base_url is required\")\n if not provider_type_str:\n raise HTTPException(status_code=400, detail=\"provider_type is required\")\n\n try:\n provider_type = LLMProviderType(provider_type_str)\n except ValueError:\n raise HTTPException(status_code=400, detail=f\"Invalid provider_type: {provider_type_str}\")\n\n # Release DB connection before the network call to avoid idle-in-transaction\n # blocking other queries while we wait for the LLM API response.\n db.close()\n\n client = LLMClient(\n provider_type=provider_type,\n api_key=api_key or \"sk-placeholder\",\n base_url=base_url,\n default_model=\"\",\n )\n\n try:\n models = await client.fetch_models()\n return {\"models\": models}\n except Exception as e:\n logger.error(\n f\"[llm_routes.fetch_models] Failed to fetch models: {e}\",\n extra={\"src\": \"llm_routes.fetch_models\"},\n )\n raise HTTPException(status_code=502, detail=str(e))\n\n\n# #endregion fetch_models\n\n\n# #region get_llm_status [C:4] [TYPE Function]\n# @BRIEF Returns whether LLM runtime is configured for dashboard validation.\n# @PRE: User is authenticated.\n# @POST: configured=true only when an active provider with valid decrypted key exists.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION CALLS -> [_is_valid_runtime_api_key]\n@router.get(\"/status\")\nasync def get_llm_status(\n current_user: User = Depends(get_current_active_user), db: Session = Depends(get_db)\n):\n service = LLMProviderService(db)\n providers = service.get_all_providers()\n active_provider = next((p for p in providers if p.is_active), None)\n\n if not providers:\n return {\n \"configured\": False,\n \"reason\": \"no_providers_configured\",\n \"provider_count\": 0,\n \"active_provider_count\": 0,\n }\n\n if not active_provider:\n return {\n \"configured\": False,\n \"reason\": \"no_active_provider\",\n \"provider_count\": len(providers),\n \"active_provider_count\": 0,\n \"providers\": [\n {\n \"id\": provider.id,\n \"name\": provider.name,\n \"provider_type\": provider.provider_type,\n \"is_active\": bool(provider.is_active),\n }\n for provider in providers\n ],\n }\n\n api_key = service.get_decrypted_api_key(active_provider.id)\n if not _is_valid_runtime_api_key(api_key):\n return {\n \"configured\": False,\n \"reason\": \"invalid_api_key\",\n \"provider_count\": len(providers),\n \"active_provider_count\": len(\n [provider for provider in providers if provider.is_active]\n ),\n \"provider_id\": active_provider.id,\n \"provider_name\": active_provider.name,\n \"provider_type\": active_provider.provider_type,\n \"default_model\": active_provider.default_model,\n }\n\n return {\n \"configured\": True,\n \"reason\": \"ok\",\n \"provider_count\": len(providers),\n \"active_provider_count\": len(\n [provider for provider in providers if provider.is_active]\n ),\n \"provider_id\": active_provider.id,\n \"provider_name\": active_provider.name,\n \"provider_type\": active_provider.provider_type,\n \"default_model\": active_provider.default_model,\n }\n\n\n# #endregion get_llm_status\n\n\n# #region create_provider [C:4] [TYPE Function]\n# @BRIEF Create a new LLM provider configuration.\n# @PRE: User is authenticated and has admin permissions.\n# @POST: Returns the created LLMProviderConfig.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\n@router.post(\n \"/providers\", response_model=LLMProviderConfig, status_code=status.HTTP_201_CREATED\n)\nasync def create_provider(\n config: LLMProviderConfig,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n \"\"\"\n Create a new LLM provider configuration.\n \"\"\"\n service = LLMProviderService(db)\n provider = service.create_provider(config)\n return LLMProviderConfig(\n id=provider.id,\n provider_type=LLMProviderType(provider.provider_type),\n name=provider.name,\n base_url=provider.base_url,\n api_key=mask_api_key(config.api_key),\n default_model=provider.default_model,\n is_active=provider.is_active,\n )\n\n\n# #endregion create_provider\n\n\n# #region update_provider [C:4] [TYPE Function]\n# @BRIEF Update an existing LLM provider configuration.\n# @PRE: User is authenticated and has admin permissions.\n# @POST: Returns the updated LLMProviderConfig.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\n@router.put(\"/providers/{provider_id}\", response_model=LLMProviderConfig)\nasync def update_provider(\n provider_id: str,\n config: LLMProviderConfig,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n \"\"\"\n Update an existing LLM provider configuration.\n \"\"\"\n service = LLMProviderService(db)\n provider = service.update_provider(provider_id, config)\n if not provider:\n raise HTTPException(status_code=404, detail=\"Provider not found\")\n\n return LLMProviderConfig(\n id=provider.id,\n provider_type=LLMProviderType(provider.provider_type),\n name=provider.name,\n base_url=provider.base_url,\n api_key=mask_api_key(service.get_decrypted_api_key(provider.id)) if provider.api_key else \"\",\n default_model=provider.default_model,\n is_active=provider.is_active,\n )\n\n\n# #endregion update_provider\n\n\n# #region delete_provider [C:4] [TYPE Function]\n# @BRIEF Delete an LLM provider configuration.\n# @PRE: User is authenticated and has admin permissions.\n# @POST: Returns success status.\n# @RELATION CALLS -> [LLMProviderService]\n@router.delete(\"/providers/{provider_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_provider(\n provider_id: str,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n \"\"\"\n Delete an LLM provider configuration.\n \"\"\"\n service = LLMProviderService(db)\n if not service.delete_provider(provider_id):\n raise HTTPException(status_code=404, detail=\"Provider not found\")\n return\n\n\n# #endregion delete_provider\n\n\n# #region test_connection [C:4] [TYPE Function]\n# @BRIEF Test connection to an LLM provider.\n# @PRE: User is authenticated.\n# @POST: Returns success status and message.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [LLMClient]\n@router.post(\"/providers/{provider_id}/test\")\nasync def test_connection(\n provider_id: str,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n logger.reason(\n f\"Testing connection for provider_id: {provider_id}\",\n extra={\"src\": \"llm_routes.test_connection\"},\n )\n \"\"\"\n Test connection to an LLM provider.\n \"\"\"\n from ...plugins.llm_analysis.service import LLMClient\n\n service = LLMProviderService(db)\n db_provider = service.get_provider(provider_id)\n if not db_provider:\n raise HTTPException(status_code=404, detail=\"Provider not found\")\n\n api_key = service.get_decrypted_api_key(provider_id)\n\n # Check if API key was successfully decrypted\n if not api_key:\n logger.error(\n f\"[llm_routes][test_connection] Failed to decrypt API key for provider {provider_id}\"\n )\n raise HTTPException(\n status_code=500,\n detail=\"Failed to decrypt API key. The provider may have been encrypted with a different encryption key. Please update the provider with a new API key.\",\n )\n\n client = LLMClient(\n provider_type=LLMProviderType(db_provider.provider_type),\n api_key=api_key,\n base_url=db_provider.base_url,\n default_model=db_provider.default_model,\n )\n\n try:\n await client.test_runtime_connection()\n return {\"success\": True, \"message\": \"Connection successful\"}\n except Exception as e:\n return {\"success\": False, \"error\": str(e)}\n\n\n# #endregion test_connection\n\n\n# #region test_provider_config [C:4] [TYPE Function]\n# @BRIEF Test connection with a provided configuration (not yet saved).\n# @PRE: User is authenticated.\n# @POST: Returns success status and message.\n# @RELATION DEPENDS_ON -> [LLMClient]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\n@router.post(\"/providers/test\")\nasync def test_provider_config(\n config: LLMProviderConfig, current_user: User = Depends(get_current_active_user)\n):\n \"\"\"\n Test connection with a provided configuration.\n \"\"\"\n from ...plugins.llm_analysis.service import LLMClient\n\n logger.reason(\n f\"Testing config for {config.name}\",\n extra={\"src\": \"llm_routes.test_provider_config\"},\n )\n\n # Check if API key is provided (reject empty, placeholder, or masked keys)\n if is_masked_or_placeholder(config.api_key):\n raise HTTPException(\n status_code=400, detail=\"API key is required for testing connection\"\n )\n\n client = LLMClient(\n provider_type=config.provider_type,\n api_key=config.api_key,\n base_url=config.base_url,\n default_model=config.default_model,\n )\n\n try:\n await client.test_runtime_connection()\n return {\"success\": True, \"message\": \"Connection successful\"}\n except Exception as e:\n return {\"success\": False, \"error\": str(e)}\n\n\n# #endregion test_provider_config\n\n# #endregion LlmRoutes\n" }, { "contract_id": "FetchModelsRequest", @@ -18555,9 +18555,10 @@ "file_path": "backend/src/api/routes/llm.py", "start_line": 39, "end_line": 53, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns True only for non-placeholder key.", "PRE": "value can be None.", "PURPOSE": "Validate decrypted runtime API key presence/shape." @@ -18572,36 +18573,18 @@ ], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "RELATION", - "message": "@RELATION is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region _is_valid_runtime_api_key [TYPE Function]\n# @BRIEF Validate decrypted runtime API key presence/shape.\n# @PRE: value can be None.\n# @POST: Returns True only for non-placeholder key.\n# @RELATION BINDS_TO -> [LlmRoutes]\ndef _is_valid_runtime_api_key(value: str | None) -> bool:\n key = (value or \"\").strip()\n if not key:\n return False\n if key in {\"********\", \"EMPTY_OR_NONE\"}:\n return False\n return len(key) >= 16\n\n\n# #endregion _is_valid_runtime_api_key\n" + "body": "# #region _is_valid_runtime_api_key [C:4] [TYPE Function]\n# @BRIEF Validate decrypted runtime API key presence/shape.\n# @PRE: value can be None.\n# @POST: Returns True only for non-placeholder key.\n# @RELATION BINDS_TO -> [LlmRoutes]\ndef _is_valid_runtime_api_key(value: str | None) -> bool:\n key = (value or \"\").strip()\n if not key:\n return False\n if key in {\"********\", \"EMPTY_OR_NONE\"}:\n return False\n return len(key) >= 16\n\n\n# #endregion _is_valid_runtime_api_key\n" }, { "contract_id": "get_providers", @@ -18609,9 +18592,10 @@ "file_path": "backend/src/api/routes/llm.py", "start_line": 56, "end_line": 89, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns list of LLMProviderConfig.", "PRE": "User is authenticated.", "PURPOSE": "Retrieve all LLM provider configurations." @@ -18632,46 +18616,29 @@ ], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "RELATION", - "message": "@RELATION is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region get_providers [TYPE Function]\n# @BRIEF Retrieve all LLM provider configurations.\n# @PRE: User is authenticated.\n# @POST: Returns list of LLMProviderConfig.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\n@router.get(\"/providers\", response_model=list[LLMProviderConfig])\nasync def get_providers(\n current_user: User = Depends(get_current_active_user), db: Session = Depends(get_db)\n):\n \"\"\"\n Get all LLM provider configurations.\n \"\"\"\n logger.reason(\n f\"Fetching providers for user: {current_user.username}\",\n extra={\"src\": \"llm_routes.get_providers\"},\n )\n service = LLMProviderService(db)\n providers = service.get_all_providers()\n return [\n LLMProviderConfig(\n id=p.id,\n provider_type=LLMProviderType(p.provider_type),\n name=p.name,\n base_url=p.base_url,\n api_key=\"********\",\n default_model=p.default_model,\n is_active=p.is_active,\n )\n for p in providers\n ]\n\n\n# #endregion get_providers\n" + "body": "# #region get_providers [C:4] [TYPE Function]\n# @BRIEF Retrieve all LLM provider configurations.\n# @PRE: User is authenticated.\n# @POST: Returns list of LLMProviderConfig.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\n@router.get(\"/providers\", response_model=list[LLMProviderConfig])\nasync def get_providers(\n current_user: User = Depends(get_current_active_user), db: Session = Depends(get_db)\n):\n \"\"\"\n Get all LLM provider configurations.\n \"\"\"\n logger.reason(\n f\"Fetching providers for user: {current_user.username}\",\n extra={\"src\": \"llm_routes.get_providers\"},\n )\n service = LLMProviderService(db)\n providers = service.get_all_providers()\n return [\n LLMProviderConfig(\n id=p.id,\n provider_type=LLMProviderType(p.provider_type),\n name=p.name,\n base_url=p.base_url,\n api_key=mask_api_key(service.get_decrypted_api_key(p.id)) if p.api_key else \"\",\n default_model=p.default_model,\n is_active=p.is_active,\n )\n for p in providers\n ]\n\n\n# #endregion get_providers\n" }, { "contract_id": "fetch_models", "contract_type": "Function", "file_path": "backend/src/api/routes/llm.py", "start_line": 92, - "end_line": 163, - "tier": "TIER_1", - "complexity": 1, + "end_line": 168, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns a list of available model IDs.", "PRE": "User is authenticated. Either provider_id or base_url+provider_type must be provided.", "PURPOSE": "Fetch available models from an LLM provider by base_url+provider_type, or by provider_id." @@ -18692,46 +18659,29 @@ ], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "RELATION", - "message": "@RELATION is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region fetch_models [TYPE Function]\n# @BRIEF Fetch available models from an LLM provider by base_url+provider_type, or by provider_id.\n# @PRE: User is authenticated. Either provider_id or base_url+provider_type must be provided.\n# @POST: Returns a list of available model IDs.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION CALLS -> [LLMClient]\n@router.post(\"/providers/fetch-models\")\nasync def fetch_models(\n payload: FetchModelsRequest,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n from ...plugins.llm_analysis.models import LLMProviderType\n from ...plugins.llm_analysis.service import LLMClient\n\n base_url = (payload.base_url or \"\").strip()\n provider_type_str = (payload.provider_type or \"\").strip()\n api_key = payload.api_key or \"\"\n provider_id = payload.provider_id or \"\"\n\n # Early validation: at least one of api_key or provider_id is required\n if not api_key and not provider_id:\n raise HTTPException(\n status_code=400,\n detail=\"api_key or provider_id is required\",\n )\n\n # Resolve provider_id to stored credentials if no direct api_key given\n if not api_key and provider_id:\n service = LLMProviderService(db)\n db_provider = service.get_provider(provider_id)\n if not db_provider:\n raise HTTPException(status_code=404, detail=\"Provider not found\")\n base_url = base_url or db_provider.base_url\n provider_type_str = provider_type_str or db_provider.provider_type\n stored_key = service.get_decrypted_api_key(provider_id)\n if stored_key:\n api_key = stored_key\n\n if not base_url:\n raise HTTPException(status_code=400, detail=\"base_url is required\")\n if not provider_type_str:\n raise HTTPException(status_code=400, detail=\"provider_type is required\")\n\n try:\n provider_type = LLMProviderType(provider_type_str)\n except ValueError:\n raise HTTPException(status_code=400, detail=f\"Invalid provider_type: {provider_type_str}\")\n\n # Release DB connection before the network call to avoid idle-in-transaction\n # blocking other queries while we wait for the LLM API response.\n db.close()\n\n client = LLMClient(\n provider_type=provider_type,\n api_key=api_key or \"sk-placeholder\",\n base_url=base_url,\n default_model=\"\",\n )\n\n try:\n models = await client.fetch_models()\n return {\"models\": models}\n except Exception as e:\n logger.error(\n f\"[llm_routes.fetch_models] Failed to fetch models: {e}\",\n extra={\"src\": \"llm_routes.fetch_models\"},\n )\n raise HTTPException(status_code=502, detail=str(e))\n\n\n# #endregion fetch_models\n" + "body": "# #region fetch_models [C:4] [TYPE Function]\n# @BRIEF Fetch available models from an LLM provider by base_url+provider_type, or by provider_id.\n# @PRE: User is authenticated. Either provider_id or base_url+provider_type must be provided.\n# @POST: Returns a list of available model IDs.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION CALLS -> [LLMClient]\n@router.post(\"/providers/fetch-models\")\nasync def fetch_models(\n payload: FetchModelsRequest,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n from ...plugins.llm_analysis.models import LLMProviderType\n from ...plugins.llm_analysis.service import LLMClient\n\n base_url = (payload.base_url or \"\").strip()\n provider_type_str = (payload.provider_type or \"\").strip()\n api_key = payload.api_key or \"\"\n provider_id = payload.provider_id or \"\"\n\n # Treat masked/placeholder API keys as if no api_key was provided;\n # they are display-only and cannot be used for real API calls.\n if is_masked_or_placeholder(api_key):\n api_key = \"\"\n\n # Early validation: at least one of api_key or provider_id is required\n if not api_key and not provider_id:\n raise HTTPException(\n status_code=400,\n detail=\"api_key or provider_id is required\",\n )\n\n # Resolve provider_id to stored credentials if no direct api_key given\n if not api_key and provider_id:\n service = LLMProviderService(db)\n db_provider = service.get_provider(provider_id)\n if not db_provider:\n raise HTTPException(status_code=404, detail=\"Provider not found\")\n base_url = base_url or db_provider.base_url\n provider_type_str = provider_type_str or db_provider.provider_type\n stored_key = service.get_decrypted_api_key(provider_id)\n if stored_key:\n api_key = stored_key\n\n if not base_url:\n raise HTTPException(status_code=400, detail=\"base_url is required\")\n if not provider_type_str:\n raise HTTPException(status_code=400, detail=\"provider_type is required\")\n\n try:\n provider_type = LLMProviderType(provider_type_str)\n except ValueError:\n raise HTTPException(status_code=400, detail=f\"Invalid provider_type: {provider_type_str}\")\n\n # Release DB connection before the network call to avoid idle-in-transaction\n # blocking other queries while we wait for the LLM API response.\n db.close()\n\n client = LLMClient(\n provider_type=provider_type,\n api_key=api_key or \"sk-placeholder\",\n base_url=base_url,\n default_model=\"\",\n )\n\n try:\n models = await client.fetch_models()\n return {\"models\": models}\n except Exception as e:\n logger.error(\n f\"[llm_routes.fetch_models] Failed to fetch models: {e}\",\n extra={\"src\": \"llm_routes.fetch_models\"},\n )\n raise HTTPException(status_code=502, detail=str(e))\n\n\n# #endregion fetch_models\n" }, { "contract_id": "get_llm_status", "contract_type": "Function", "file_path": "backend/src/api/routes/llm.py", - "start_line": 166, - "end_line": 234, - "tier": "TIER_1", - "complexity": 1, + "start_line": 171, + "end_line": 239, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "configured=true only when an active provider with valid decrypted key exists.", "PRE": "User is authenticated.", "PURPOSE": "Returns whether LLM runtime is configured for dashboard validation." @@ -18752,46 +18702,29 @@ ], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "RELATION", - "message": "@RELATION is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region get_llm_status [TYPE Function]\n# @BRIEF Returns whether LLM runtime is configured for dashboard validation.\n# @PRE: User is authenticated.\n# @POST: configured=true only when an active provider with valid decrypted key exists.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION CALLS -> [_is_valid_runtime_api_key]\n@router.get(\"/status\")\nasync def get_llm_status(\n current_user: User = Depends(get_current_active_user), db: Session = Depends(get_db)\n):\n service = LLMProviderService(db)\n providers = service.get_all_providers()\n active_provider = next((p for p in providers if p.is_active), None)\n\n if not providers:\n return {\n \"configured\": False,\n \"reason\": \"no_providers_configured\",\n \"provider_count\": 0,\n \"active_provider_count\": 0,\n }\n\n if not active_provider:\n return {\n \"configured\": False,\n \"reason\": \"no_active_provider\",\n \"provider_count\": len(providers),\n \"active_provider_count\": 0,\n \"providers\": [\n {\n \"id\": provider.id,\n \"name\": provider.name,\n \"provider_type\": provider.provider_type,\n \"is_active\": bool(provider.is_active),\n }\n for provider in providers\n ],\n }\n\n api_key = service.get_decrypted_api_key(active_provider.id)\n if not _is_valid_runtime_api_key(api_key):\n return {\n \"configured\": False,\n \"reason\": \"invalid_api_key\",\n \"provider_count\": len(providers),\n \"active_provider_count\": len(\n [provider for provider in providers if provider.is_active]\n ),\n \"provider_id\": active_provider.id,\n \"provider_name\": active_provider.name,\n \"provider_type\": active_provider.provider_type,\n \"default_model\": active_provider.default_model,\n }\n\n return {\n \"configured\": True,\n \"reason\": \"ok\",\n \"provider_count\": len(providers),\n \"active_provider_count\": len(\n [provider for provider in providers if provider.is_active]\n ),\n \"provider_id\": active_provider.id,\n \"provider_name\": active_provider.name,\n \"provider_type\": active_provider.provider_type,\n \"default_model\": active_provider.default_model,\n }\n\n\n# #endregion get_llm_status\n" + "body": "# #region get_llm_status [C:4] [TYPE Function]\n# @BRIEF Returns whether LLM runtime is configured for dashboard validation.\n# @PRE: User is authenticated.\n# @POST: configured=true only when an active provider with valid decrypted key exists.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION CALLS -> [_is_valid_runtime_api_key]\n@router.get(\"/status\")\nasync def get_llm_status(\n current_user: User = Depends(get_current_active_user), db: Session = Depends(get_db)\n):\n service = LLMProviderService(db)\n providers = service.get_all_providers()\n active_provider = next((p for p in providers if p.is_active), None)\n\n if not providers:\n return {\n \"configured\": False,\n \"reason\": \"no_providers_configured\",\n \"provider_count\": 0,\n \"active_provider_count\": 0,\n }\n\n if not active_provider:\n return {\n \"configured\": False,\n \"reason\": \"no_active_provider\",\n \"provider_count\": len(providers),\n \"active_provider_count\": 0,\n \"providers\": [\n {\n \"id\": provider.id,\n \"name\": provider.name,\n \"provider_type\": provider.provider_type,\n \"is_active\": bool(provider.is_active),\n }\n for provider in providers\n ],\n }\n\n api_key = service.get_decrypted_api_key(active_provider.id)\n if not _is_valid_runtime_api_key(api_key):\n return {\n \"configured\": False,\n \"reason\": \"invalid_api_key\",\n \"provider_count\": len(providers),\n \"active_provider_count\": len(\n [provider for provider in providers if provider.is_active]\n ),\n \"provider_id\": active_provider.id,\n \"provider_name\": active_provider.name,\n \"provider_type\": active_provider.provider_type,\n \"default_model\": active_provider.default_model,\n }\n\n return {\n \"configured\": True,\n \"reason\": \"ok\",\n \"provider_count\": len(providers),\n \"active_provider_count\": len(\n [provider for provider in providers if provider.is_active]\n ),\n \"provider_id\": active_provider.id,\n \"provider_name\": active_provider.name,\n \"provider_type\": active_provider.provider_type,\n \"default_model\": active_provider.default_model,\n }\n\n\n# #endregion get_llm_status\n" }, { "contract_id": "create_provider", "contract_type": "Function", "file_path": "backend/src/api/routes/llm.py", - "start_line": 237, - "end_line": 267, - "tier": "TIER_1", - "complexity": 1, + "start_line": 242, + "end_line": 272, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns the created LLMProviderConfig.", "PRE": "User is authenticated and has admin permissions.", "PURPOSE": "Create a new LLM provider configuration." @@ -18812,46 +18745,29 @@ ], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "RELATION", - "message": "@RELATION is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region create_provider [TYPE Function]\n# @BRIEF Create a new LLM provider configuration.\n# @PRE: User is authenticated and has admin permissions.\n# @POST: Returns the created LLMProviderConfig.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\n@router.post(\n \"/providers\", response_model=LLMProviderConfig, status_code=status.HTTP_201_CREATED\n)\nasync def create_provider(\n config: LLMProviderConfig,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n \"\"\"\n Create a new LLM provider configuration.\n \"\"\"\n service = LLMProviderService(db)\n provider = service.create_provider(config)\n return LLMProviderConfig(\n id=provider.id,\n provider_type=LLMProviderType(provider.provider_type),\n name=provider.name,\n base_url=provider.base_url,\n api_key=\"********\",\n default_model=provider.default_model,\n is_active=provider.is_active,\n )\n\n\n# #endregion create_provider\n" + "body": "# #region create_provider [C:4] [TYPE Function]\n# @BRIEF Create a new LLM provider configuration.\n# @PRE: User is authenticated and has admin permissions.\n# @POST: Returns the created LLMProviderConfig.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\n@router.post(\n \"/providers\", response_model=LLMProviderConfig, status_code=status.HTTP_201_CREATED\n)\nasync def create_provider(\n config: LLMProviderConfig,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n \"\"\"\n Create a new LLM provider configuration.\n \"\"\"\n service = LLMProviderService(db)\n provider = service.create_provider(config)\n return LLMProviderConfig(\n id=provider.id,\n provider_type=LLMProviderType(provider.provider_type),\n name=provider.name,\n base_url=provider.base_url,\n api_key=mask_api_key(config.api_key),\n default_model=provider.default_model,\n is_active=provider.is_active,\n )\n\n\n# #endregion create_provider\n" }, { "contract_id": "update_provider", "contract_type": "Function", "file_path": "backend/src/api/routes/llm.py", - "start_line": 270, - "end_line": 302, - "tier": "TIER_1", - "complexity": 1, + "start_line": 275, + "end_line": 307, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns the updated LLMProviderConfig.", "PRE": "User is authenticated and has admin permissions.", "PURPOSE": "Update an existing LLM provider configuration." @@ -18872,46 +18788,29 @@ ], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "RELATION", - "message": "@RELATION is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region update_provider [TYPE Function]\n# @BRIEF Update an existing LLM provider configuration.\n# @PRE: User is authenticated and has admin permissions.\n# @POST: Returns the updated LLMProviderConfig.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\n@router.put(\"/providers/{provider_id}\", response_model=LLMProviderConfig)\nasync def update_provider(\n provider_id: str,\n config: LLMProviderConfig,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n \"\"\"\n Update an existing LLM provider configuration.\n \"\"\"\n service = LLMProviderService(db)\n provider = service.update_provider(provider_id, config)\n if not provider:\n raise HTTPException(status_code=404, detail=\"Provider not found\")\n\n return LLMProviderConfig(\n id=provider.id,\n provider_type=LLMProviderType(provider.provider_type),\n name=provider.name,\n base_url=provider.base_url,\n api_key=\"********\",\n default_model=provider.default_model,\n is_active=provider.is_active,\n )\n\n\n# #endregion update_provider\n" + "body": "# #region update_provider [C:4] [TYPE Function]\n# @BRIEF Update an existing LLM provider configuration.\n# @PRE: User is authenticated and has admin permissions.\n# @POST: Returns the updated LLMProviderConfig.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\n@router.put(\"/providers/{provider_id}\", response_model=LLMProviderConfig)\nasync def update_provider(\n provider_id: str,\n config: LLMProviderConfig,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n \"\"\"\n Update an existing LLM provider configuration.\n \"\"\"\n service = LLMProviderService(db)\n provider = service.update_provider(provider_id, config)\n if not provider:\n raise HTTPException(status_code=404, detail=\"Provider not found\")\n\n return LLMProviderConfig(\n id=provider.id,\n provider_type=LLMProviderType(provider.provider_type),\n name=provider.name,\n base_url=provider.base_url,\n api_key=mask_api_key(service.get_decrypted_api_key(provider.id)) if provider.api_key else \"\",\n default_model=provider.default_model,\n is_active=provider.is_active,\n )\n\n\n# #endregion update_provider\n" }, { "contract_id": "delete_provider", "contract_type": "Function", "file_path": "backend/src/api/routes/llm.py", - "start_line": 305, - "end_line": 325, - "tier": "TIER_1", - "complexity": 1, + "start_line": 310, + "end_line": 330, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns success status.", "PRE": "User is authenticated and has admin permissions.", "PURPOSE": "Delete an LLM provider configuration." @@ -18926,46 +18825,29 @@ ], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "RELATION", - "message": "@RELATION is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region delete_provider [TYPE Function]\n# @BRIEF Delete an LLM provider configuration.\n# @PRE: User is authenticated and has admin permissions.\n# @POST: Returns success status.\n# @RELATION CALLS -> [LLMProviderService]\n@router.delete(\"/providers/{provider_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_provider(\n provider_id: str,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n \"\"\"\n Delete an LLM provider configuration.\n \"\"\"\n service = LLMProviderService(db)\n if not service.delete_provider(provider_id):\n raise HTTPException(status_code=404, detail=\"Provider not found\")\n return\n\n\n# #endregion delete_provider\n" + "body": "# #region delete_provider [C:4] [TYPE Function]\n# @BRIEF Delete an LLM provider configuration.\n# @PRE: User is authenticated and has admin permissions.\n# @POST: Returns success status.\n# @RELATION CALLS -> [LLMProviderService]\n@router.delete(\"/providers/{provider_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_provider(\n provider_id: str,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n \"\"\"\n Delete an LLM provider configuration.\n \"\"\"\n service = LLMProviderService(db)\n if not service.delete_provider(provider_id):\n raise HTTPException(status_code=404, detail=\"Provider not found\")\n return\n\n\n# #endregion delete_provider\n" }, { "contract_id": "test_connection", "contract_type": "Function", "file_path": "backend/src/api/routes/llm.py", - "start_line": 328, - "end_line": 380, - "tier": "TIER_1", - "complexity": 1, + "start_line": 333, + "end_line": 385, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns success status and message.", "PRE": "User is authenticated.", "PURPOSE": "Test connection to an LLM provider." @@ -18986,46 +18868,29 @@ ], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "RELATION", - "message": "@RELATION is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region test_connection [TYPE Function]\n# @BRIEF Test connection to an LLM provider.\n# @PRE: User is authenticated.\n# @POST: Returns success status and message.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [LLMClient]\n@router.post(\"/providers/{provider_id}/test\")\nasync def test_connection(\n provider_id: str,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n logger.reason(\n f\"Testing connection for provider_id: {provider_id}\",\n extra={\"src\": \"llm_routes.test_connection\"},\n )\n \"\"\"\n Test connection to an LLM provider.\n \"\"\"\n from ...plugins.llm_analysis.service import LLMClient\n\n service = LLMProviderService(db)\n db_provider = service.get_provider(provider_id)\n if not db_provider:\n raise HTTPException(status_code=404, detail=\"Provider not found\")\n\n api_key = service.get_decrypted_api_key(provider_id)\n\n # Check if API key was successfully decrypted\n if not api_key:\n logger.error(\n f\"[llm_routes][test_connection] Failed to decrypt API key for provider {provider_id}\"\n )\n raise HTTPException(\n status_code=500,\n detail=\"Failed to decrypt API key. The provider may have been encrypted with a different encryption key. Please update the provider with a new API key.\",\n )\n\n client = LLMClient(\n provider_type=LLMProviderType(db_provider.provider_type),\n api_key=api_key,\n base_url=db_provider.base_url,\n default_model=db_provider.default_model,\n )\n\n try:\n await client.test_runtime_connection()\n return {\"success\": True, \"message\": \"Connection successful\"}\n except Exception as e:\n return {\"success\": False, \"error\": str(e)}\n\n\n# #endregion test_connection\n" + "body": "# #region test_connection [C:4] [TYPE Function]\n# @BRIEF Test connection to an LLM provider.\n# @PRE: User is authenticated.\n# @POST: Returns success status and message.\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [LLMClient]\n@router.post(\"/providers/{provider_id}/test\")\nasync def test_connection(\n provider_id: str,\n current_user: User = Depends(get_current_active_user),\n db: Session = Depends(get_db),\n):\n logger.reason(\n f\"Testing connection for provider_id: {provider_id}\",\n extra={\"src\": \"llm_routes.test_connection\"},\n )\n \"\"\"\n Test connection to an LLM provider.\n \"\"\"\n from ...plugins.llm_analysis.service import LLMClient\n\n service = LLMProviderService(db)\n db_provider = service.get_provider(provider_id)\n if not db_provider:\n raise HTTPException(status_code=404, detail=\"Provider not found\")\n\n api_key = service.get_decrypted_api_key(provider_id)\n\n # Check if API key was successfully decrypted\n if not api_key:\n logger.error(\n f\"[llm_routes][test_connection] Failed to decrypt API key for provider {provider_id}\"\n )\n raise HTTPException(\n status_code=500,\n detail=\"Failed to decrypt API key. The provider may have been encrypted with a different encryption key. Please update the provider with a new API key.\",\n )\n\n client = LLMClient(\n provider_type=LLMProviderType(db_provider.provider_type),\n api_key=api_key,\n base_url=db_provider.base_url,\n default_model=db_provider.default_model,\n )\n\n try:\n await client.test_runtime_connection()\n return {\"success\": True, \"message\": \"Connection successful\"}\n except Exception as e:\n return {\"success\": False, \"error\": str(e)}\n\n\n# #endregion test_connection\n" }, { "contract_id": "test_provider_config", "contract_type": "Function", "file_path": "backend/src/api/routes/llm.py", - "start_line": 383, - "end_line": 423, - "tier": "TIER_1", - "complexity": 1, + "start_line": 388, + "end_line": 428, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns success status and message.", "PRE": "User is authenticated.", "PURPOSE": "Test connection with a provided configuration (not yet saved)." @@ -19046,36 +18911,18 @@ ], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "RELATION", - "message": "@RELATION is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region test_provider_config [TYPE Function]\n# @BRIEF Test connection with a provided configuration (not yet saved).\n# @PRE: User is authenticated.\n# @POST: Returns success status and message.\n# @RELATION DEPENDS_ON -> [LLMClient]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\n@router.post(\"/providers/test\")\nasync def test_provider_config(\n config: LLMProviderConfig, current_user: User = Depends(get_current_active_user)\n):\n \"\"\"\n Test connection with a provided configuration.\n \"\"\"\n from ...plugins.llm_analysis.service import LLMClient\n\n logger.reason(\n f\"Testing config for {config.name}\",\n extra={\"src\": \"llm_routes.test_provider_config\"},\n )\n\n # Check if API key is provided\n if not config.api_key or config.api_key == \"********\":\n raise HTTPException(\n status_code=400, detail=\"API key is required for testing connection\"\n )\n\n client = LLMClient(\n provider_type=config.provider_type,\n api_key=config.api_key,\n base_url=config.base_url,\n default_model=config.default_model,\n )\n\n try:\n await client.test_runtime_connection()\n return {\"success\": True, \"message\": \"Connection successful\"}\n except Exception as e:\n return {\"success\": False, \"error\": str(e)}\n\n\n# #endregion test_provider_config\n" + "body": "# #region test_provider_config [C:4] [TYPE Function]\n# @BRIEF Test connection with a provided configuration (not yet saved).\n# @PRE: User is authenticated.\n# @POST: Returns success status and message.\n# @RELATION DEPENDS_ON -> [LLMClient]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\n@router.post(\"/providers/test\")\nasync def test_provider_config(\n config: LLMProviderConfig, current_user: User = Depends(get_current_active_user)\n):\n \"\"\"\n Test connection with a provided configuration.\n \"\"\"\n from ...plugins.llm_analysis.service import LLMClient\n\n logger.reason(\n f\"Testing config for {config.name}\",\n extra={\"src\": \"llm_routes.test_provider_config\"},\n )\n\n # Check if API key is provided (reject empty, placeholder, or masked keys)\n if is_masked_or_placeholder(config.api_key):\n raise HTTPException(\n status_code=400, detail=\"API key is required for testing connection\"\n )\n\n client = LLMClient(\n provider_type=config.provider_type,\n api_key=config.api_key,\n base_url=config.base_url,\n default_model=config.default_model,\n )\n\n try:\n await client.test_runtime_connection()\n return {\"success\": True, \"message\": \"Connection successful\"}\n except Exception as e:\n return {\"success\": False, \"error\": str(e)}\n\n\n# #endregion test_provider_config\n" }, { "contract_id": "MappingsApi", @@ -21868,52 +21715,55 @@ "contract_type": "Module", "file_path": "backend/src/api/routes/translate/__init__.py", "start_line": 1, - "end_line": 37, + "end_line": 40, "tier": "TIER_2", "complexity": 4, "metadata": { "COMPLEXITY": 4, - "LAYER": "UI (API)", + "LAYER": "API", + "POST": "Translation job, run, dictionary, correction, preview, and schedule CRUD operations are executed.", + "PRE": "API server is running, user is authenticated, database is accessible.", "PURPOSE": "API routes for LLM-based SQL/dashboard translation management including terminology dictionary CRUD and import.", "RATIONALE": "Snapshot isolation — in-progress runs use config snapshot; config edits affect future runs only.", - "REJECTED": "Invalidating in-progress runs on config edit would break scheduled run continuity." + "REJECTED": "Invalidating in-progress runs on config edit would break scheduled run continuity.", + "SIDE_EFFECT": "Creates/modifies DB rows; triggers background translation runs; queries Superset API." }, "relations": [ { "source_id": "TranslateRoutes", "relation_type": "DEPENDS_ON", - "target_id": "TranslateJobResponse", - "target_ref": "[TranslateJobResponse]" + "target_id": "SupersetClient", + "target_ref": "[SupersetClient]" }, { "source_id": "TranslateRoutes", "relation_type": "DEPENDS_ON", - "target_id": "DictionaryManager:Class", - "target_ref": "[DictionaryManager:Class]" + "target_id": "SupersetClient", + "target_ref": "[SupersetClient]" }, { "source_id": "TranslateRoutes", "relation_type": "DEPENDS_ON", - "target_id": "get_current_user", - "target_ref": "[get_current_user]" + "target_id": "SupersetClient", + "target_ref": "[SupersetClient]" }, { "source_id": "TranslateRoutes", "relation_type": "DEPENDS_ON", - "target_id": "get_db", - "target_ref": "[get_db]" + "target_id": "SupersetClient", + "target_ref": "[SupersetClient]" }, { "source_id": "TranslateRoutes", "relation_type": "DEPENDS_ON", - "target_id": "has_permission", - "target_ref": "[has_permission]" + "target_id": "SupersetClient", + "target_ref": "[SupersetClient]" }, { "source_id": "TranslateRoutes", "relation_type": "DEPENDS_ON", - "target_id": "ConfigManager", - "target_ref": "[ConfigManager]" + "target_id": "SupersetClient", + "target_ref": "[SupersetClient]" }, { "source_id": "TranslateRoutes", @@ -21922,62 +21772,17 @@ "target_ref": "[SupersetClient]" } ], - "schema_warnings": [ - { - "code": "invalid_enum_value", - "tag": "LAYER", - "message": "@LAYER value 'UI (API)' is not in allowed enum", - "detail": { - "allowed": [ - "Core", - "Domain", - "API", - "UI", - "Service", - "Infrastructure", - "Plugin" - ], - "value": "UI (API)" - } - }, - { - "code": "missing_required_tag", - "tag": "POST", - "message": "@POST is required for contract type 'Module' at C4", - "detail": { - "actual_complexity": 4, - "contract_type": "Module" - } - }, - { - "code": "missing_required_tag", - "tag": "PRE", - "message": "@PRE is required for contract type 'Module' at C4", - "detail": { - "actual_complexity": 4, - "contract_type": "Module" - } - }, - { - "code": "missing_required_tag", - "tag": "SIDE_EFFECT", - "message": "@SIDE_EFFECT is required for contract type 'Module' at C4", - "detail": { - "actual_complexity": 4, - "contract_type": "Module" - } - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslateRoutes [C:4] [TYPE Module] [SEMANTICS translate, api, package, schedule, dashboard, llm]\n# @BRIEF API routes for LLM-based SQL/dashboard translation management including terminology dictionary CRUD and import.\n# @LAYER: UI (API)\n# @RELATION DEPENDS_ON -> [TranslateJobResponse]\n# @RELATION DEPENDS_ON -> [DictionaryManager:Class]\n# @RELATION DEPENDS_ON -> [get_current_user]\n# @RELATION DEPENDS_ON -> [get_db]\n# @RELATION DEPENDS_ON -> [has_permission]\n# @RELATION DEPENDS_ON -> [ConfigManager]\n# @RELATION DEPENDS_ON -> [SupersetClient]\n# @RATIONALE: Snapshot isolation — in-progress runs use config snapshot; config edits affect future runs only.\n# @REJECTED: Invalidating in-progress runs on config edit would break scheduled run continuity.\n\n\"\"\"\nTranslate routes package.\n\nRe-exports the shared router and all route handler modules.\nAll sub-modules register their handlers on the router at import time.\n\"\"\"\n\nfrom . import (\n _correction_routes, # noqa: F401 — registers correction handlers\n _dictionary_routes, # noqa: F401 — registers dictionary handlers\n _job_routes, # noqa: F401 — registers job handlers\n _metrics_routes, # noqa: F401 — registers metrics handlers\n _preview_routes, # noqa: F401 — registers preview handlers\n _run_list_routes, # noqa: F401 — registers run list/detail/csv handlers\n _run_routes, # noqa: F401 — registers run handlers\n _schedule_routes, # noqa: F401 — registers schedule handlers\n)\nfrom ._router import router\n\n__all__ = [\n \"router\",\n]\n\n# #endregion TranslateRoutes\n" + "body": "# #region TranslateRoutes [C:4] [TYPE Module] [SEMANTICS translate, api, package, schedule, dashboard, llm]\n# @BRIEF API routes for LLM-based SQL/dashboard translation management including terminology dictionary CRUD and import.\n# @LAYER API\n# @RELATION DEPENDS_ON -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [SupersetClient]\n# @RATIONALE Snapshot isolation — in-progress runs use config snapshot; config edits affect future runs only.\n# @REJECTED Invalidating in-progress runs on config edit would break scheduled run continuity.\n# @POST Translation job, run, dictionary, correction, preview, and schedule CRUD operations are executed.\n# @PRE API server is running, user is authenticated, database is accessible.\n# @SIDE_EFFECT Creates/modifies DB rows; triggers background translation runs; queries Superset API.\n\n\"\"\"\nTranslate routes package.\n\nRe-exports the shared router and all route handler modules.\nAll sub-modules register their handlers on the router at import time.\n\"\"\"\n\nfrom . import (\n _correction_routes, # noqa: F401 — registers correction handlers\n _dictionary_routes, # noqa: F401 — registers dictionary handlers\n _job_routes, # noqa: F401 — registers job handlers\n _metrics_routes, # noqa: F401 — registers metrics handlers\n _preview_routes, # noqa: F401 — registers preview handlers\n _run_list_routes, # noqa: F401 — registers run list/detail/csv handlers\n _run_routes, # noqa: F401 — registers run handlers\n _schedule_routes, # noqa: F401 — registers schedule handlers\n)\nfrom ._router import router\n\n__all__ = [\n \"router\",\n]\n\n# #endregion TranslateRoutes\n" }, { "contract_id": "TranslateCorrectionRoutesModule", "contract_type": "Module", "file_path": "backend/src/api/routes/translate/_correction_routes.py", "start_line": 1, - "end_line": 94, + "end_line": 100, "tier": "TIER_1", "complexity": 2, "metadata": { @@ -21989,90 +21794,70 @@ "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslateCorrectionRoutesModule [C:2] [TYPE Module] [SEMANTICS fastapi, translate, api, search]\n# @BRIEF Term correction submission endpoints.\n# @LAYER: API\n\nfrom fastapi import Depends, HTTPException, status\nfrom sqlalchemy.orm import Session\n\nfrom ....core.database import get_db\nfrom ....core.logger import logger\nfrom ....dependencies import get_current_user, has_permission\nfrom ....plugins.translate.dictionary import DictionaryManager\nfrom ....schemas.auth import User\nfrom ....schemas.translate import (\n TermCorrectionBulkSubmit,\n TermCorrectionSubmit,\n)\nfrom ._router import router\n\n# ============================================================\n# Corrections\n# ============================================================\n\n# #region submit_correction [TYPE Function]\n# @BRIEF Submit a term correction from a run result review.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Correction applied with conflict detection.\n@router.post(\"/corrections\")\nasync def submit_correction(\n payload: TermCorrectionSubmit,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Submit a term correction from a run result review.\"\"\"\n logger.reason(f\"submit_correction — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n if not payload.dictionary_id:\n raise HTTPException(status_code=422, detail=\"dictionary_id is required\")\n try:\n result = DictionaryManager.submit_correction(\n db,\n dict_id=payload.dictionary_id,\n source_term=payload.source_term,\n incorrect_target_term=payload.incorrect_target_term,\n corrected_target_term=payload.corrected_target_term,\n origin_run_id=payload.origin_run_id,\n origin_row_key=payload.origin_row_key,\n origin_user_id=current_user.username,\n context_data=payload.context_data,\n usage_notes=payload.usage_notes,\n keep_context=payload.keep_context,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion submit_correction\n\n\n# #region submit_bulk_corrections [TYPE Function]\n# @BRIEF Submit multiple term corrections atomically.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: All corrections applied or none with conflict list.\n@router.post(\"/corrections/bulk\")\nasync def submit_bulk_corrections(\n payload: TermCorrectionBulkSubmit,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Submit multiple term corrections atomically.\"\"\"\n logger.reason(f\"submit_bulk_corrections — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n corr_list = []\n for c in payload.corrections:\n corr_list.append({\n \"source_term\": c.source_term,\n \"incorrect_target_term\": c.incorrect_target_term,\n \"corrected_target_term\": c.corrected_target_term,\n \"origin_run_id\": c.origin_run_id,\n \"origin_row_key\": c.origin_row_key,\n })\n result = DictionaryManager.submit_bulk_corrections(\n db,\n dict_id=payload.dictionary_id,\n corrections=corr_list,\n origin_user_id=current_user.username,\n )\n if result.get(\"status\") == \"conflicts\":\n raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=result)\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion submit_bulk_corrections\n\n# #endregion TranslateCorrectionRoutesModule\n" + "body": "# #region TranslateCorrectionRoutesModule [C:2] [TYPE Module] [SEMANTICS fastapi, translate, api, search]\n# @BRIEF Term correction submission endpoints.\n# @LAYER: API\n\nfrom fastapi import Depends, HTTPException, status\nfrom sqlalchemy.orm import Session\n\nfrom ....core.database import get_db\nfrom ....core.logger import logger\nfrom ....dependencies import get_current_user, has_permission\nfrom ....plugins.translate.dictionary import DictionaryManager\nfrom ....schemas.auth import User\nfrom ....schemas.translate import (\n TermCorrectionBulkSubmit,\n TermCorrectionSubmit,\n)\nfrom ._router import router\n\n# ============================================================\n# Corrections\n# ============================================================\n\n# #region submit_correction [C:4] [TYPE Function]\n# @BRIEF Submit a term correction from a run result review.\n# @PRE User has translate.dictionary.edit permission.\n# @POST Correction applied with conflict detection.\n# @SIDE_EFFECT Creates/updates DictionaryEntry row; commits.\n# @RELATION DEPENDS_ON -> [DictionaryManager]\n@router.post(\"/corrections\")\nasync def submit_correction(\n payload: TermCorrectionSubmit,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Submit a term correction from a run result review.\"\"\"\n logger.reason(f\"submit_correction — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n if not payload.dictionary_id:\n raise HTTPException(status_code=422, detail=\"dictionary_id is required\")\n try:\n result = DictionaryManager.submit_correction(\n db,\n dict_id=payload.dictionary_id,\n source_term=payload.source_term,\n incorrect_target_term=payload.incorrect_target_term,\n corrected_target_term=payload.corrected_target_term,\n origin_run_id=payload.origin_run_id,\n origin_row_key=payload.origin_row_key,\n origin_user_id=current_user.username,\n context_data=payload.context_data,\n usage_notes=payload.usage_notes,\n keep_context=payload.keep_context,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion submit_correction\n\n\n# #region submit_bulk_corrections [C:4] [TYPE Function]\n# @BRIEF Submit multiple term corrections atomically.\n# @PRE User has translate.dictionary.edit permission.\n# @POST All corrections applied or none with conflict list.\n# @SIDE_EFFECT Creates/updates DictionaryEntry rows; commits once.\n# @RELATION DEPENDS_ON -> [DictionaryManager]\n# @COMPLEXITY 4\n\n@router.post(\"/corrections/bulk\")\nasync def submit_bulk_corrections(\n payload: TermCorrectionBulkSubmit,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Submit multiple term corrections atomically.\"\"\"\n logger.reason(f\"submit_bulk_corrections — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n corr_list = []\n for c in payload.corrections:\n corr_list.append({\n \"source_term\": c.source_term,\n \"incorrect_target_term\": c.incorrect_target_term,\n \"corrected_target_term\": c.corrected_target_term,\n \"origin_run_id\": c.origin_run_id,\n \"origin_row_key\": c.origin_row_key,\n })\n result = DictionaryManager.submit_bulk_corrections(\n db,\n dict_id=payload.dictionary_id,\n corrections=corr_list,\n origin_user_id=current_user.username,\n )\n if result.get(\"status\") == \"conflicts\":\n raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=result)\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion submit_bulk_corrections\n\n# #endregion TranslateCorrectionRoutesModule\n" }, { "contract_id": "submit_correction", "contract_type": "Function", "file_path": "backend/src/api/routes/translate/_correction_routes.py", "start_line": 23, - "end_line": 55, - "tier": "TIER_1", - "complexity": 1, + "end_line": 57, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Correction applied with conflict detection.", "PRE": "User has translate.dictionary.edit permission.", - "PURPOSE": "Submit a term correction from a run result review." + "PURPOSE": "Submit a term correction from a run result review.", + "SIDE_EFFECT": "Creates/updates DictionaryEntry row; commits." }, - "relations": [], - "schema_warnings": [ + "relations": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } + "source_id": "submit_correction", + "relation_type": "DEPENDS_ON", + "target_id": "DictionaryManager", + "target_ref": "[DictionaryManager]" } ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region submit_correction [TYPE Function]\n# @BRIEF Submit a term correction from a run result review.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Correction applied with conflict detection.\n@router.post(\"/corrections\")\nasync def submit_correction(\n payload: TermCorrectionSubmit,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Submit a term correction from a run result review.\"\"\"\n logger.reason(f\"submit_correction — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n if not payload.dictionary_id:\n raise HTTPException(status_code=422, detail=\"dictionary_id is required\")\n try:\n result = DictionaryManager.submit_correction(\n db,\n dict_id=payload.dictionary_id,\n source_term=payload.source_term,\n incorrect_target_term=payload.incorrect_target_term,\n corrected_target_term=payload.corrected_target_term,\n origin_run_id=payload.origin_run_id,\n origin_row_key=payload.origin_row_key,\n origin_user_id=current_user.username,\n context_data=payload.context_data,\n usage_notes=payload.usage_notes,\n keep_context=payload.keep_context,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion submit_correction\n" + "body": "# #region submit_correction [C:4] [TYPE Function]\n# @BRIEF Submit a term correction from a run result review.\n# @PRE User has translate.dictionary.edit permission.\n# @POST Correction applied with conflict detection.\n# @SIDE_EFFECT Creates/updates DictionaryEntry row; commits.\n# @RELATION DEPENDS_ON -> [DictionaryManager]\n@router.post(\"/corrections\")\nasync def submit_correction(\n payload: TermCorrectionSubmit,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Submit a term correction from a run result review.\"\"\"\n logger.reason(f\"submit_correction — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n if not payload.dictionary_id:\n raise HTTPException(status_code=422, detail=\"dictionary_id is required\")\n try:\n result = DictionaryManager.submit_correction(\n db,\n dict_id=payload.dictionary_id,\n source_term=payload.source_term,\n incorrect_target_term=payload.incorrect_target_term,\n corrected_target_term=payload.corrected_target_term,\n origin_run_id=payload.origin_run_id,\n origin_row_key=payload.origin_row_key,\n origin_user_id=current_user.username,\n context_data=payload.context_data,\n usage_notes=payload.usage_notes,\n keep_context=payload.keep_context,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion submit_correction\n" }, { "contract_id": "submit_bulk_corrections", "contract_type": "Function", "file_path": "backend/src/api/routes/translate/_correction_routes.py", - "start_line": 58, - "end_line": 92, - "tier": "TIER_1", - "complexity": 1, + "start_line": 60, + "end_line": 98, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": "4", "POST": "All corrections applied or none with conflict list.", "PRE": "User has translate.dictionary.edit permission.", - "PURPOSE": "Submit multiple term corrections atomically." + "PURPOSE": "Submit multiple term corrections atomically.", + "SIDE_EFFECT": "Creates/updates DictionaryEntry rows; commits once." }, - "relations": [], - "schema_warnings": [ + "relations": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } + "source_id": "submit_bulk_corrections", + "relation_type": "DEPENDS_ON", + "target_id": "DictionaryManager", + "target_ref": "[DictionaryManager]" } ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region submit_bulk_corrections [TYPE Function]\n# @BRIEF Submit multiple term corrections atomically.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: All corrections applied or none with conflict list.\n@router.post(\"/corrections/bulk\")\nasync def submit_bulk_corrections(\n payload: TermCorrectionBulkSubmit,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Submit multiple term corrections atomically.\"\"\"\n logger.reason(f\"submit_bulk_corrections — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n corr_list = []\n for c in payload.corrections:\n corr_list.append({\n \"source_term\": c.source_term,\n \"incorrect_target_term\": c.incorrect_target_term,\n \"corrected_target_term\": c.corrected_target_term,\n \"origin_run_id\": c.origin_run_id,\n \"origin_row_key\": c.origin_row_key,\n })\n result = DictionaryManager.submit_bulk_corrections(\n db,\n dict_id=payload.dictionary_id,\n corrections=corr_list,\n origin_user_id=current_user.username,\n )\n if result.get(\"status\") == \"conflicts\":\n raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=result)\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion submit_bulk_corrections\n" + "body": "# #region submit_bulk_corrections [C:4] [TYPE Function]\n# @BRIEF Submit multiple term corrections atomically.\n# @PRE User has translate.dictionary.edit permission.\n# @POST All corrections applied or none with conflict list.\n# @SIDE_EFFECT Creates/updates DictionaryEntry rows; commits once.\n# @RELATION DEPENDS_ON -> [DictionaryManager]\n# @COMPLEXITY 4\n\n@router.post(\"/corrections/bulk\")\nasync def submit_bulk_corrections(\n payload: TermCorrectionBulkSubmit,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Submit multiple term corrections atomically.\"\"\"\n logger.reason(f\"submit_bulk_corrections — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n corr_list = []\n for c in payload.corrections:\n corr_list.append({\n \"source_term\": c.source_term,\n \"incorrect_target_term\": c.incorrect_target_term,\n \"corrected_target_term\": c.corrected_target_term,\n \"origin_run_id\": c.origin_run_id,\n \"origin_row_key\": c.origin_row_key,\n })\n result = DictionaryManager.submit_bulk_corrections(\n db,\n dict_id=payload.dictionary_id,\n corrections=corr_list,\n origin_user_id=current_user.username,\n )\n if result.get(\"status\") == \"conflicts\":\n raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=result)\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion submit_bulk_corrections\n" }, { "contract_id": "TranslateDictionaryRoutesModule", "contract_type": "Module", "file_path": "backend/src/api/routes/translate/_dictionary_routes.py", "start_line": 1, - "end_line": 389, + "end_line": 391, "tier": "TIER_2", "complexity": 3, "metadata": { @@ -22094,7 +21879,7 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslateDictionaryRoutesModule [C:3] [TYPE Module] [SEMANTICS fastapi, translate, api, search]\n# @BRIEF Terminology Dictionary CRUD, entries management, and import routes.\n# @LAYER: API\n\nfrom fastapi import Depends, HTTPException, Query, status\nfrom sqlalchemy.orm import Session\n\nfrom ....core.database import get_db\nfrom ....core.logger import belief_scope, logger\nfrom ....dependencies import get_current_user, has_permission\nfrom ....plugins.translate.dictionary import DictionaryManager\nfrom ....schemas.auth import User\nfrom ....schemas.translate import (\n DictionaryCreate,\n DictionaryEntryCreate,\n DictionaryImport,\n)\nfrom ._helpers import _dict_to_response, _get_dictionary_entry_counts\nfrom ._router import router\n\n# ============================================================\n# Terminology Dictionaries\n# ============================================================\n\n# #region list_dictionaries [TYPE Function]\n# @BRIEF List all terminology dictionaries.\n# @PRE: User has translate.dictionary.view permission.\n# @POST: Returns list of dictionaries with total count.\n@router.get(\"/dictionaries\")\nasync def list_dictionaries(\n page: int = Query(1, ge=1),\n page_size: int = Query(20, ge=1, le=100),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"List all terminology dictionaries.\"\"\"\n with belief_scope(\"list_dictionaries\"):\n logger.reason(f\"User: {current_user.username}\")\n dicts, total = DictionaryManager.list_dictionaries(db, page=page, page_size=page_size)\n dict_ids = [d.id for d in dicts]\n counts = _get_dictionary_entry_counts(db, dict_ids) if dict_ids else {}\n items = [_dict_to_response(d, counts.get(d.id, 0)) for d in dicts]\n logger.reflect(\"Dictionaries listed\", {\"total\": total, \"returned\": len(items)})\n return {\"items\": items, \"total\": total, \"page\": page, \"page_size\": page_size}\n# #endregion list_dictionaries\n\n\n# #region get_dictionary [TYPE Function]\n# @BRIEF Get a single terminology dictionary by ID.\n# @PRE: User has translate.dictionary.view permission.\n# @POST: Returns the dictionary with entry_count.\n@router.get(\"/dictionaries/{dictionary_id}\")\nasync def get_dictionary(\n dictionary_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get a terminology dictionary by ID.\"\"\"\n with belief_scope(\"get_dictionary\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n d = DictionaryManager.get_dictionary(db, dictionary_id)\n from ....models.translate import DictionaryEntry\n entry_count = db.query(DictionaryEntry.id).filter(DictionaryEntry.dictionary_id == dictionary_id).count()\n logger.reflect(\"Dictionary found\", {\"id\": dictionary_id})\n return _dict_to_response(d, entry_count)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_dictionary\n\n\n# #region create_dictionary [TYPE Function]\n# @BRIEF Create a new terminology dictionary.\n# @PRE: User has translate.dictionary.create permission.\n# @POST: Returns the created dictionary.\n@router.post(\"/dictionaries\", status_code=status.HTTP_201_CREATED)\nasync def create_dictionary(\n payload: DictionaryCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"CREATE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Create a new terminology dictionary.\"\"\"\n with belief_scope(\"create_dictionary\"):\n logger.reason(f\"User: {current_user.username}\")\n d = DictionaryManager.create_dictionary(\n db,\n name=payload.name,\n source_dialect=payload.source_dialect,\n target_dialect=payload.target_dialect,\n created_by=current_user.username,\n description=payload.description,\n is_active=payload.is_active,\n )\n logger.reflect(\"Dictionary created\", {\"id\": d.id})\n return _dict_to_response(d, 0)\n# #endregion create_dictionary\n\n\n# #region update_dictionary [TYPE Function]\n# @BRIEF Update an existing terminology dictionary.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Returns the updated dictionary.\n@router.put(\"/dictionaries/{dictionary_id}\")\nasync def update_dictionary(\n dictionary_id: str,\n payload: DictionaryCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Update a terminology dictionary.\"\"\"\n with belief_scope(\"update_dictionary\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n d = DictionaryManager.update_dictionary(\n db,\n dict_id=dictionary_id,\n name=payload.name,\n description=payload.description,\n source_dialect=payload.source_dialect,\n target_dialect=payload.target_dialect,\n is_active=payload.is_active,\n )\n from ....models.translate import DictionaryEntry\n entry_count = db.query(DictionaryEntry.id).filter(DictionaryEntry.dictionary_id == dictionary_id).count()\n logger.reflect(\"Dictionary updated\", {\"id\": dictionary_id})\n return _dict_to_response(d, entry_count)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion update_dictionary\n\n\n# #region delete_dictionary [TYPE Function]\n# @BRIEF Delete a terminology dictionary, blocked if attached to active/scheduled jobs.\n# @PRE: User has translate.dictionary.delete permission.\n# @POST: Dictionary is deleted.\n@router.delete(\"/dictionaries/{dictionary_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_dictionary(\n dictionary_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"DELETE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Delete a terminology dictionary.\"\"\"\n with belief_scope(\"delete_dictionary\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n DictionaryManager.delete_dictionary(db, dictionary_id)\n logger.reflect(\"Dictionary deleted\", {\"id\": dictionary_id})\n return None\n except ValueError as e:\n if \"active/scheduled\" in str(e):\n raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(e))\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion delete_dictionary\n\n\n# ============================================================\n# Dictionary Entries CRUD\n# ============================================================\n\n# #region list_dictionary_entries [TYPE Function]\n# @BRIEF List entries for a dictionary, optionally filtered by language pair.\n# @PRE: User has translate.dictionary.view permission.\n# @POST: Returns paginated list of entries with language pair fields.\n@router.get(\"/dictionaries/{dictionary_id}/entries\")\nasync def list_dictionary_entries(\n dictionary_id: str,\n page: int = Query(1, ge=1),\n page_size: int = Query(50, ge=1, le=500),\n source_language: str | None = Query(None, description=\"Filter by BCP-47 source language\"),\n target_language: str | None = Query(None, description=\"Filter by BCP-47 target language\"),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"List entries for a dictionary.\"\"\"\n with belief_scope(\"list_dictionary_entries\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n entries, total = DictionaryManager.list_entries(db, dictionary_id, page=page, page_size=page_size)\n # Apply language pair filtering\n if source_language or target_language:\n filtered = []\n for e in entries:\n if source_language and e.source_language != source_language and e.source_language != \"und\":\n continue\n if target_language and e.target_language != target_language:\n continue\n filtered.append(e)\n entries = filtered\n total = len(filtered)\n items = [\n {\n \"id\": e.id,\n \"dictionary_id\": e.dictionary_id,\n \"source_term\": e.source_term,\n \"source_term_normalized\": e.source_term_normalized,\n \"target_term\": e.target_term,\n \"source_language\": e.source_language,\n \"target_language\": e.target_language,\n \"context_notes\": e.context_notes,\n \"context_data\": e.context_data,\n \"usage_notes\": e.usage_notes,\n \"has_context\": e.has_context,\n \"context_source\": e.context_source,\n \"origin_source_language\": e.origin_source_language,\n \"created_at\": e.created_at,\n \"updated_at\": e.updated_at,\n }\n for e in entries\n ]\n logger.reflect(\"Entries listed\", {\"dict_id\": dictionary_id, \"total\": total, \"source_language\": source_language, \"target_language\": target_language})\n return {\"items\": items, \"total\": total, \"page\": page, \"page_size\": page_size}\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion list_dictionary_entries\n\n\n# #region add_dictionary_entry [TYPE Function]\n# @BRIEF Add a new entry to a dictionary.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Entry is created.\n@router.post(\"/dictionaries/{dictionary_id}/entries\", status_code=status.HTTP_201_CREATED)\nasync def add_dictionary_entry(\n dictionary_id: str,\n payload: DictionaryEntryCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Add a new entry to a dictionary.\"\"\"\n with belief_scope(\"add_dictionary_entry\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n entry = DictionaryManager.add_entry(\n db, dictionary_id,\n source_term=payload.source_term,\n target_term=payload.target_term,\n context_notes=payload.context_notes,\n source_language=payload.source_language,\n target_language=payload.target_language,\n )\n logger.reflect(\"Entry added\", {\"entry_id\": entry.id})\n return {\n \"id\": entry.id,\n \"dictionary_id\": entry.dictionary_id,\n \"source_term\": entry.source_term,\n \"source_term_normalized\": entry.source_term_normalized,\n \"target_term\": entry.target_term,\n \"source_language\": entry.source_language,\n \"target_language\": entry.target_language,\n \"context_notes\": entry.context_notes,\n \"context_data\": entry.context_data,\n \"usage_notes\": entry.usage_notes,\n \"has_context\": entry.has_context,\n \"context_source\": entry.context_source,\n \"origin_source_language\": entry.origin_source_language,\n \"created_at\": entry.created_at,\n \"updated_at\": entry.updated_at,\n }\n except ValueError as e:\n if \"already exists\" in str(e):\n raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(e))\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion add_dictionary_entry\n\n\n# #region edit_dictionary_entry [TYPE Function]\n# @BRIEF Update an existing dictionary entry.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Entry is updated.\n@router.put(\"/dictionaries/{dictionary_id}/entries/{entry_id}\")\nasync def edit_dictionary_entry(\n dictionary_id: str,\n entry_id: str,\n payload: DictionaryEntryCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Update an existing dictionary entry.\"\"\"\n with belief_scope(\"edit_dictionary_entry\"):\n logger.reason(f\"Entry: {entry_id}, User: {current_user.username}\")\n try:\n entry = DictionaryManager.edit_entry(\n db, entry_id,\n source_term=payload.source_term,\n target_term=payload.target_term,\n context_notes=payload.context_notes,\n source_language=payload.source_language,\n target_language=payload.target_language,\n )\n logger.reflect(\"Entry updated\", {\"entry_id\": entry_id})\n return {\n \"id\": entry.id,\n \"dictionary_id\": entry.dictionary_id,\n \"source_term\": entry.source_term,\n \"source_term_normalized\": entry.source_term_normalized,\n \"target_term\": entry.target_term,\n \"source_language\": entry.source_language,\n \"target_language\": entry.target_language,\n \"context_notes\": entry.context_notes,\n \"context_data\": entry.context_data,\n \"usage_notes\": entry.usage_notes,\n \"has_context\": entry.has_context,\n \"context_source\": entry.context_source,\n \"origin_source_language\": entry.origin_source_language,\n \"created_at\": entry.created_at,\n \"updated_at\": entry.updated_at,\n }\n except ValueError as e:\n if \"already exists\" in str(e):\n raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(e))\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion edit_dictionary_entry\n\n\n# #region delete_dictionary_entry [TYPE Function]\n# @BRIEF Delete a dictionary entry.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Entry is deleted.\n@router.delete(\"/dictionaries/{dictionary_id}/entries/{entry_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_dictionary_entry(\n dictionary_id: str,\n entry_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Delete a dictionary entry.\"\"\"\n with belief_scope(\"delete_dictionary_entry\"):\n logger.reason(f\"Entry: {entry_id}, User: {current_user.username}\")\n try:\n DictionaryManager.delete_entry(db, entry_id)\n logger.reflect(\"Entry deleted\", {\"entry_id\": entry_id})\n return None\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion delete_dictionary_entry\n\n\n# #region import_dictionary_entries [TYPE Function]\n# @BRIEF Import entries into a terminology dictionary from CSV/TSV content.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Entries are imported per conflict mode.\n@router.post(\"/dictionaries/{dictionary_id}/import\")\nasync def import_dictionary_entries(\n dictionary_id: str,\n payload: DictionaryImport,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Import entries into a terminology dictionary from CSV/TSV content.\"\"\"\n with belief_scope(\"import_dictionary_entries\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n\n if payload.on_conflict not in (\"overwrite\", \"keep_existing\", \"cancel\"):\n raise HTTPException(\n status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,\n detail=\"on_conflict must be 'overwrite', 'keep_existing', or 'cancel'\",\n )\n\n try:\n result = DictionaryManager.import_entries(\n db,\n dict_id=dictionary_id,\n content=payload.content,\n delimiter=payload.delimiter,\n on_conflict=payload.on_conflict,\n preview_only=payload.preview_only,\n default_source_language=payload.default_source_language,\n default_target_language=payload.default_target_language,\n )\n logger.reflect(\"Import completed\", {\n \"dict_id\": dictionary_id,\n \"total\": result[\"total\"],\n \"errors\": len(result[\"errors\"]),\n })\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion import_dictionary_entries\n\n# #endregion TranslateDictionaryRoutesModule\n" + "body": "# #region TranslateDictionaryRoutesModule [C:3] [TYPE Module] [SEMANTICS fastapi, translate, api, search]\n# @BRIEF Terminology Dictionary CRUD, entries management, and import routes.\n# @LAYER: API\n\nfrom fastapi import Depends, HTTPException, Query, status\nfrom sqlalchemy.orm import Session\n\nfrom ....core.database import get_db\nfrom ....core.logger import belief_scope, logger\nfrom ....dependencies import get_current_user, has_permission\nfrom ....plugins.translate.dictionary import DictionaryManager\nfrom ....schemas.auth import User\nfrom ....schemas.translate import (\n DictionaryCreate,\n DictionaryEntryCreate,\n DictionaryImport,\n)\nfrom ._helpers import _dict_to_response, _get_dictionary_entry_counts\nfrom ._router import router\n\n# ============================================================\n# Terminology Dictionaries\n# ============================================================\n\n# #region list_dictionaries [C:4] [TYPE Function]\n# @BRIEF List all terminology dictionaries.\n# @PRE: User has translate.dictionary.view permission.\n# @POST: Returns list of dictionaries with total count.\n@router.get(\"/dictionaries\")\nasync def list_dictionaries(\n page: int = Query(1, ge=1),\n page_size: int = Query(20, ge=1, le=100),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"List all terminology dictionaries.\"\"\"\n with belief_scope(\"list_dictionaries\"):\n logger.reason(f\"User: {current_user.username}\")\n dicts, total = DictionaryManager.list_dictionaries(db, page=page, page_size=page_size)\n dict_ids = [d.id for d in dicts]\n counts = _get_dictionary_entry_counts(db, dict_ids) if dict_ids else {}\n items = [_dict_to_response(d, counts.get(d.id, 0)) for d in dicts]\n logger.reflect(\"Dictionaries listed\", {\"total\": total, \"returned\": len(items)})\n return {\"items\": items, \"total\": total, \"page\": page, \"page_size\": page_size}\n# #endregion list_dictionaries\n\n\n# #region get_dictionary [C:4] [TYPE Function]\n# @BRIEF Get a single terminology dictionary by ID.\n# @PRE: User has translate.dictionary.view permission.\n# @POST: Returns the dictionary with entry_count.\n@router.get(\"/dictionaries/{dictionary_id}\")\nasync def get_dictionary(\n dictionary_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get a terminology dictionary by ID.\"\"\"\n with belief_scope(\"get_dictionary\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n d = DictionaryManager.get_dictionary(db, dictionary_id)\n from ....models.translate import DictionaryEntry\n entry_count = db.query(DictionaryEntry.id).filter(DictionaryEntry.dictionary_id == dictionary_id).count()\n logger.reflect(\"Dictionary found\", {\"id\": dictionary_id})\n return _dict_to_response(d, entry_count)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_dictionary\n\n\n# #region create_dictionary [C:4] [TYPE Function]\n# @BRIEF Create a new terminology dictionary.\n# @PRE: User has translate.dictionary.create permission.\n# @POST: Returns the created dictionary.\n@router.post(\"/dictionaries\", status_code=status.HTTP_201_CREATED)\nasync def create_dictionary(\n payload: DictionaryCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"CREATE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Create a new terminology dictionary.\"\"\"\n with belief_scope(\"create_dictionary\"):\n logger.reason(f\"User: {current_user.username}\")\n d = DictionaryManager.create_dictionary(\n db,\n name=payload.name,\n source_dialect=payload.source_dialect,\n target_dialect=payload.target_dialect,\n created_by=current_user.username,\n description=payload.description,\n is_active=payload.is_active,\n )\n logger.reflect(\"Dictionary created\", {\"id\": d.id})\n return _dict_to_response(d, 0)\n# #endregion create_dictionary\n\n\n# #region update_dictionary [C:4] [TYPE Function]\n# @BRIEF Update an existing terminology dictionary.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Returns the updated dictionary.\n@router.put(\"/dictionaries/{dictionary_id}\")\nasync def update_dictionary(\n dictionary_id: str,\n payload: DictionaryCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Update a terminology dictionary.\"\"\"\n with belief_scope(\"update_dictionary\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n d = DictionaryManager.update_dictionary(\n db,\n dict_id=dictionary_id,\n name=payload.name,\n description=payload.description,\n source_dialect=payload.source_dialect,\n target_dialect=payload.target_dialect,\n is_active=payload.is_active,\n )\n from ....models.translate import DictionaryEntry\n entry_count = db.query(DictionaryEntry.id).filter(DictionaryEntry.dictionary_id == dictionary_id).count()\n logger.reflect(\"Dictionary updated\", {\"id\": dictionary_id})\n return _dict_to_response(d, entry_count)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion update_dictionary\n\n\n# #region delete_dictionary [C:4] [TYPE Function]\n# @BRIEF Delete a terminology dictionary, blocked if attached to active/scheduled jobs.\n# @PRE: User has translate.dictionary.delete permission.\n# @POST: Dictionary is deleted.\n@router.delete(\"/dictionaries/{dictionary_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_dictionary(\n dictionary_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"DELETE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Delete a terminology dictionary.\"\"\"\n with belief_scope(\"delete_dictionary\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n DictionaryManager.delete_dictionary(db, dictionary_id)\n logger.reflect(\"Dictionary deleted\", {\"id\": dictionary_id})\n return None\n except ValueError as e:\n if \"active/scheduled\" in str(e):\n raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(e))\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion delete_dictionary\n\n\n# ============================================================\n# Dictionary Entries CRUD\n# ============================================================\n\n# #region list_dictionary_entries [C:4] [TYPE Function]\n# @BRIEF List entries for a dictionary, optionally filtered by language pair.\n# @PRE: User has translate.dictionary.view permission.\n# @POST: Returns paginated list of entries with language pair fields.\n@router.get(\"/dictionaries/{dictionary_id}/entries\")\nasync def list_dictionary_entries(\n dictionary_id: str,\n page: int = Query(1, ge=1),\n page_size: int = Query(50, ge=1, le=500),\n source_language: str | None = Query(None, description=\"Filter by BCP-47 source language\"),\n target_language: str | None = Query(None, description=\"Filter by BCP-47 target language\"),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"List entries for a dictionary.\"\"\"\n with belief_scope(\"list_dictionary_entries\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n entries, total = DictionaryManager.list_entries(db, dictionary_id, page=page, page_size=page_size)\n # Apply language pair filtering\n if source_language or target_language:\n filtered = []\n for e in entries:\n if source_language and e.source_language != source_language and e.source_language != \"und\":\n continue\n if target_language and e.target_language != target_language:\n continue\n filtered.append(e)\n entries = filtered\n total = len(filtered)\n items = [\n {\n \"id\": e.id,\n \"dictionary_id\": e.dictionary_id,\n \"source_term\": e.source_term,\n \"source_term_normalized\": e.source_term_normalized,\n \"target_term\": e.target_term,\n \"source_language\": e.source_language,\n \"target_language\": e.target_language,\n \"context_notes\": e.context_notes,\n \"context_data\": e.context_data,\n \"usage_notes\": e.usage_notes,\n \"has_context\": e.has_context,\n \"context_source\": e.context_source,\n \"origin_source_language\": e.origin_source_language,\n \"created_at\": e.created_at,\n \"updated_at\": e.updated_at,\n }\n for e in entries\n ]\n logger.reflect(\"Entries listed\", {\"dict_id\": dictionary_id, \"total\": total, \"source_language\": source_language, \"target_language\": target_language})\n return {\"items\": items, \"total\": total, \"page\": page, \"page_size\": page_size}\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion list_dictionary_entries\n\n\n# #region add_dictionary_entry [C:4] [TYPE Function]\n# @BRIEF Add a new entry to a dictionary.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Entry is created.\n@router.post(\"/dictionaries/{dictionary_id}/entries\", status_code=status.HTTP_201_CREATED)\nasync def add_dictionary_entry(\n dictionary_id: str,\n payload: DictionaryEntryCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Add a new entry to a dictionary.\"\"\"\n with belief_scope(\"add_dictionary_entry\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n entry = DictionaryManager.add_entry(\n db, dictionary_id,\n source_term=payload.source_term,\n target_term=payload.target_term,\n context_notes=payload.context_notes,\n source_language=payload.source_language,\n target_language=payload.target_language,\n )\n logger.reflect(\"Entry added\", {\"entry_id\": entry.id})\n return {\n \"id\": entry.id,\n \"dictionary_id\": entry.dictionary_id,\n \"source_term\": entry.source_term,\n \"source_term_normalized\": entry.source_term_normalized,\n \"target_term\": entry.target_term,\n \"source_language\": entry.source_language,\n \"target_language\": entry.target_language,\n \"context_notes\": entry.context_notes,\n \"context_data\": entry.context_data,\n \"usage_notes\": entry.usage_notes,\n \"has_context\": entry.has_context,\n \"context_source\": entry.context_source,\n \"origin_source_language\": entry.origin_source_language,\n \"created_at\": entry.created_at,\n \"updated_at\": entry.updated_at,\n }\n except ValueError as e:\n if \"already exists\" in str(e):\n raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(e))\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion add_dictionary_entry\n\n\n# #region edit_dictionary_entry [C:4] [TYPE Function]\n# @BRIEF Update an existing dictionary entry.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Entry is updated.\n@router.put(\"/dictionaries/{dictionary_id}/entries/{entry_id}\")\nasync def edit_dictionary_entry(\n dictionary_id: str,\n entry_id: str,\n payload: DictionaryEntryCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Update an existing dictionary entry.\"\"\"\n with belief_scope(\"edit_dictionary_entry\"):\n logger.reason(f\"Entry: {entry_id}, User: {current_user.username}\")\n try:\n entry = DictionaryManager.edit_entry(\n db, entry_id,\n source_term=payload.source_term,\n target_term=payload.target_term,\n context_notes=payload.context_notes,\n source_language=payload.source_language,\n target_language=payload.target_language,\n )\n logger.reflect(\"Entry updated\", {\"entry_id\": entry_id})\n return {\n \"id\": entry.id,\n \"dictionary_id\": entry.dictionary_id,\n \"source_term\": entry.source_term,\n \"source_term_normalized\": entry.source_term_normalized,\n \"target_term\": entry.target_term,\n \"source_language\": entry.source_language,\n \"target_language\": entry.target_language,\n \"context_notes\": entry.context_notes,\n \"context_data\": entry.context_data,\n \"usage_notes\": entry.usage_notes,\n \"has_context\": entry.has_context,\n \"context_source\": entry.context_source,\n \"origin_source_language\": entry.origin_source_language,\n \"created_at\": entry.created_at,\n \"updated_at\": entry.updated_at,\n }\n except ValueError as e:\n if \"already exists\" in str(e):\n raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(e))\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion edit_dictionary_entry\n\n\n# #region delete_dictionary_entry [C:4] [TYPE Function]\n# @BRIEF Delete a dictionary entry.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Entry is deleted.\n@router.delete(\"/dictionaries/{dictionary_id}/entries/{entry_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_dictionary_entry(\n dictionary_id: str,\n entry_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Delete a dictionary entry.\"\"\"\n with belief_scope(\"delete_dictionary_entry\"):\n logger.reason(f\"Entry: {entry_id}, User: {current_user.username}\")\n try:\n DictionaryManager.delete_entry(db, entry_id)\n logger.reflect(\"Entry deleted\", {\"entry_id\": entry_id})\n return None\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion delete_dictionary_entry\n\n\n# #region import_dictionary_entries [C:4] [TYPE Function]\n# @BRIEF Import entries into a terminology dictionary from CSV/TSV content.\n# @PRE User has translate.dictionary.edit permission.\n# @POST Entries are imported per conflict mode.\n# @COMPLEXITY 4\n\n@router.post(\"/dictionaries/{dictionary_id}/import\")\nasync def import_dictionary_entries(\n dictionary_id: str,\n payload: DictionaryImport,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Import entries into a terminology dictionary from CSV/TSV content.\"\"\"\n with belief_scope(\"import_dictionary_entries\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n\n if payload.on_conflict not in (\"overwrite\", \"keep_existing\", \"cancel\"):\n raise HTTPException(\n status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,\n detail=\"on_conflict must be 'overwrite', 'keep_existing', or 'cancel'\",\n )\n\n try:\n result = DictionaryManager.import_entries(\n db,\n dict_id=dictionary_id,\n content=payload.content,\n delimiter=payload.delimiter,\n on_conflict=payload.on_conflict,\n preview_only=payload.preview_only,\n default_source_language=payload.default_source_language,\n default_target_language=payload.default_target_language,\n )\n logger.reflect(\"Import completed\", {\n \"dict_id\": dictionary_id,\n \"total\": result[\"total\"],\n \"errors\": len(result[\"errors\"]),\n })\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion import_dictionary_entries\n\n# #endregion TranslateDictionaryRoutesModule\n" }, { "contract_id": "list_dictionaries", @@ -22102,9 +21887,10 @@ "file_path": "backend/src/api/routes/translate/_dictionary_routes.py", "start_line": 25, "end_line": 46, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns list of dictionaries with total count.", "PRE": "User has translate.dictionary.view permission.", "PURPOSE": "List all terminology dictionaries." @@ -22112,27 +21898,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region list_dictionaries [TYPE Function]\n# @BRIEF List all terminology dictionaries.\n# @PRE: User has translate.dictionary.view permission.\n# @POST: Returns list of dictionaries with total count.\n@router.get(\"/dictionaries\")\nasync def list_dictionaries(\n page: int = Query(1, ge=1),\n page_size: int = Query(20, ge=1, le=100),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"List all terminology dictionaries.\"\"\"\n with belief_scope(\"list_dictionaries\"):\n logger.reason(f\"User: {current_user.username}\")\n dicts, total = DictionaryManager.list_dictionaries(db, page=page, page_size=page_size)\n dict_ids = [d.id for d in dicts]\n counts = _get_dictionary_entry_counts(db, dict_ids) if dict_ids else {}\n items = [_dict_to_response(d, counts.get(d.id, 0)) for d in dicts]\n logger.reflect(\"Dictionaries listed\", {\"total\": total, \"returned\": len(items)})\n return {\"items\": items, \"total\": total, \"page\": page, \"page_size\": page_size}\n# #endregion list_dictionaries\n" + "body": "# #region list_dictionaries [C:4] [TYPE Function]\n# @BRIEF List all terminology dictionaries.\n# @PRE: User has translate.dictionary.view permission.\n# @POST: Returns list of dictionaries with total count.\n@router.get(\"/dictionaries\")\nasync def list_dictionaries(\n page: int = Query(1, ge=1),\n page_size: int = Query(20, ge=1, le=100),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"List all terminology dictionaries.\"\"\"\n with belief_scope(\"list_dictionaries\"):\n logger.reason(f\"User: {current_user.username}\")\n dicts, total = DictionaryManager.list_dictionaries(db, page=page, page_size=page_size)\n dict_ids = [d.id for d in dicts]\n counts = _get_dictionary_entry_counts(db, dict_ids) if dict_ids else {}\n items = [_dict_to_response(d, counts.get(d.id, 0)) for d in dicts]\n logger.reflect(\"Dictionaries listed\", {\"total\": total, \"returned\": len(items)})\n return {\"items\": items, \"total\": total, \"page\": page, \"page_size\": page_size}\n# #endregion list_dictionaries\n" }, { "contract_id": "get_dictionary", @@ -22140,9 +21926,10 @@ "file_path": "backend/src/api/routes/translate/_dictionary_routes.py", "start_line": 49, "end_line": 71, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns the dictionary with entry_count.", "PRE": "User has translate.dictionary.view permission.", "PURPOSE": "Get a single terminology dictionary by ID." @@ -22150,27 +21937,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region get_dictionary [TYPE Function]\n# @BRIEF Get a single terminology dictionary by ID.\n# @PRE: User has translate.dictionary.view permission.\n# @POST: Returns the dictionary with entry_count.\n@router.get(\"/dictionaries/{dictionary_id}\")\nasync def get_dictionary(\n dictionary_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get a terminology dictionary by ID.\"\"\"\n with belief_scope(\"get_dictionary\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n d = DictionaryManager.get_dictionary(db, dictionary_id)\n from ....models.translate import DictionaryEntry\n entry_count = db.query(DictionaryEntry.id).filter(DictionaryEntry.dictionary_id == dictionary_id).count()\n logger.reflect(\"Dictionary found\", {\"id\": dictionary_id})\n return _dict_to_response(d, entry_count)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_dictionary\n" + "body": "# #region get_dictionary [C:4] [TYPE Function]\n# @BRIEF Get a single terminology dictionary by ID.\n# @PRE: User has translate.dictionary.view permission.\n# @POST: Returns the dictionary with entry_count.\n@router.get(\"/dictionaries/{dictionary_id}\")\nasync def get_dictionary(\n dictionary_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get a terminology dictionary by ID.\"\"\"\n with belief_scope(\"get_dictionary\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n d = DictionaryManager.get_dictionary(db, dictionary_id)\n from ....models.translate import DictionaryEntry\n entry_count = db.query(DictionaryEntry.id).filter(DictionaryEntry.dictionary_id == dictionary_id).count()\n logger.reflect(\"Dictionary found\", {\"id\": dictionary_id})\n return _dict_to_response(d, entry_count)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_dictionary\n" }, { "contract_id": "create_dictionary", @@ -22178,9 +21965,10 @@ "file_path": "backend/src/api/routes/translate/_dictionary_routes.py", "start_line": 74, "end_line": 99, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns the created dictionary.", "PRE": "User has translate.dictionary.create permission.", "PURPOSE": "Create a new terminology dictionary." @@ -22188,27 +21976,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region create_dictionary [TYPE Function]\n# @BRIEF Create a new terminology dictionary.\n# @PRE: User has translate.dictionary.create permission.\n# @POST: Returns the created dictionary.\n@router.post(\"/dictionaries\", status_code=status.HTTP_201_CREATED)\nasync def create_dictionary(\n payload: DictionaryCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"CREATE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Create a new terminology dictionary.\"\"\"\n with belief_scope(\"create_dictionary\"):\n logger.reason(f\"User: {current_user.username}\")\n d = DictionaryManager.create_dictionary(\n db,\n name=payload.name,\n source_dialect=payload.source_dialect,\n target_dialect=payload.target_dialect,\n created_by=current_user.username,\n description=payload.description,\n is_active=payload.is_active,\n )\n logger.reflect(\"Dictionary created\", {\"id\": d.id})\n return _dict_to_response(d, 0)\n# #endregion create_dictionary\n" + "body": "# #region create_dictionary [C:4] [TYPE Function]\n# @BRIEF Create a new terminology dictionary.\n# @PRE: User has translate.dictionary.create permission.\n# @POST: Returns the created dictionary.\n@router.post(\"/dictionaries\", status_code=status.HTTP_201_CREATED)\nasync def create_dictionary(\n payload: DictionaryCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"CREATE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Create a new terminology dictionary.\"\"\"\n with belief_scope(\"create_dictionary\"):\n logger.reason(f\"User: {current_user.username}\")\n d = DictionaryManager.create_dictionary(\n db,\n name=payload.name,\n source_dialect=payload.source_dialect,\n target_dialect=payload.target_dialect,\n created_by=current_user.username,\n description=payload.description,\n is_active=payload.is_active,\n )\n logger.reflect(\"Dictionary created\", {\"id\": d.id})\n return _dict_to_response(d, 0)\n# #endregion create_dictionary\n" }, { "contract_id": "update_dictionary", @@ -22216,9 +22004,10 @@ "file_path": "backend/src/api/routes/translate/_dictionary_routes.py", "start_line": 102, "end_line": 133, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns the updated dictionary.", "PRE": "User has translate.dictionary.edit permission.", "PURPOSE": "Update an existing terminology dictionary." @@ -22226,27 +22015,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region update_dictionary [TYPE Function]\n# @BRIEF Update an existing terminology dictionary.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Returns the updated dictionary.\n@router.put(\"/dictionaries/{dictionary_id}\")\nasync def update_dictionary(\n dictionary_id: str,\n payload: DictionaryCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Update a terminology dictionary.\"\"\"\n with belief_scope(\"update_dictionary\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n d = DictionaryManager.update_dictionary(\n db,\n dict_id=dictionary_id,\n name=payload.name,\n description=payload.description,\n source_dialect=payload.source_dialect,\n target_dialect=payload.target_dialect,\n is_active=payload.is_active,\n )\n from ....models.translate import DictionaryEntry\n entry_count = db.query(DictionaryEntry.id).filter(DictionaryEntry.dictionary_id == dictionary_id).count()\n logger.reflect(\"Dictionary updated\", {\"id\": dictionary_id})\n return _dict_to_response(d, entry_count)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion update_dictionary\n" + "body": "# #region update_dictionary [C:4] [TYPE Function]\n# @BRIEF Update an existing terminology dictionary.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Returns the updated dictionary.\n@router.put(\"/dictionaries/{dictionary_id}\")\nasync def update_dictionary(\n dictionary_id: str,\n payload: DictionaryCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Update a terminology dictionary.\"\"\"\n with belief_scope(\"update_dictionary\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n d = DictionaryManager.update_dictionary(\n db,\n dict_id=dictionary_id,\n name=payload.name,\n description=payload.description,\n source_dialect=payload.source_dialect,\n target_dialect=payload.target_dialect,\n is_active=payload.is_active,\n )\n from ....models.translate import DictionaryEntry\n entry_count = db.query(DictionaryEntry.id).filter(DictionaryEntry.dictionary_id == dictionary_id).count()\n logger.reflect(\"Dictionary updated\", {\"id\": dictionary_id})\n return _dict_to_response(d, entry_count)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion update_dictionary\n" }, { "contract_id": "delete_dictionary", @@ -22254,9 +22043,10 @@ "file_path": "backend/src/api/routes/translate/_dictionary_routes.py", "start_line": 136, "end_line": 158, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Dictionary is deleted.", "PRE": "User has translate.dictionary.delete permission.", "PURPOSE": "Delete a terminology dictionary, blocked if attached to active/scheduled jobs." @@ -22264,27 +22054,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region delete_dictionary [TYPE Function]\n# @BRIEF Delete a terminology dictionary, blocked if attached to active/scheduled jobs.\n# @PRE: User has translate.dictionary.delete permission.\n# @POST: Dictionary is deleted.\n@router.delete(\"/dictionaries/{dictionary_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_dictionary(\n dictionary_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"DELETE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Delete a terminology dictionary.\"\"\"\n with belief_scope(\"delete_dictionary\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n DictionaryManager.delete_dictionary(db, dictionary_id)\n logger.reflect(\"Dictionary deleted\", {\"id\": dictionary_id})\n return None\n except ValueError as e:\n if \"active/scheduled\" in str(e):\n raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(e))\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion delete_dictionary\n" + "body": "# #region delete_dictionary [C:4] [TYPE Function]\n# @BRIEF Delete a terminology dictionary, blocked if attached to active/scheduled jobs.\n# @PRE: User has translate.dictionary.delete permission.\n# @POST: Dictionary is deleted.\n@router.delete(\"/dictionaries/{dictionary_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_dictionary(\n dictionary_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"DELETE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Delete a terminology dictionary.\"\"\"\n with belief_scope(\"delete_dictionary\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n DictionaryManager.delete_dictionary(db, dictionary_id)\n logger.reflect(\"Dictionary deleted\", {\"id\": dictionary_id})\n return None\n except ValueError as e:\n if \"active/scheduled\" in str(e):\n raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(e))\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion delete_dictionary\n" }, { "contract_id": "list_dictionary_entries", @@ -22292,9 +22082,10 @@ "file_path": "backend/src/api/routes/translate/_dictionary_routes.py", "start_line": 165, "end_line": 220, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns paginated list of entries with language pair fields.", "PRE": "User has translate.dictionary.view permission.", "PURPOSE": "List entries for a dictionary, optionally filtered by language pair." @@ -22302,27 +22093,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region list_dictionary_entries [TYPE Function]\n# @BRIEF List entries for a dictionary, optionally filtered by language pair.\n# @PRE: User has translate.dictionary.view permission.\n# @POST: Returns paginated list of entries with language pair fields.\n@router.get(\"/dictionaries/{dictionary_id}/entries\")\nasync def list_dictionary_entries(\n dictionary_id: str,\n page: int = Query(1, ge=1),\n page_size: int = Query(50, ge=1, le=500),\n source_language: str | None = Query(None, description=\"Filter by BCP-47 source language\"),\n target_language: str | None = Query(None, description=\"Filter by BCP-47 target language\"),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"List entries for a dictionary.\"\"\"\n with belief_scope(\"list_dictionary_entries\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n entries, total = DictionaryManager.list_entries(db, dictionary_id, page=page, page_size=page_size)\n # Apply language pair filtering\n if source_language or target_language:\n filtered = []\n for e in entries:\n if source_language and e.source_language != source_language and e.source_language != \"und\":\n continue\n if target_language and e.target_language != target_language:\n continue\n filtered.append(e)\n entries = filtered\n total = len(filtered)\n items = [\n {\n \"id\": e.id,\n \"dictionary_id\": e.dictionary_id,\n \"source_term\": e.source_term,\n \"source_term_normalized\": e.source_term_normalized,\n \"target_term\": e.target_term,\n \"source_language\": e.source_language,\n \"target_language\": e.target_language,\n \"context_notes\": e.context_notes,\n \"context_data\": e.context_data,\n \"usage_notes\": e.usage_notes,\n \"has_context\": e.has_context,\n \"context_source\": e.context_source,\n \"origin_source_language\": e.origin_source_language,\n \"created_at\": e.created_at,\n \"updated_at\": e.updated_at,\n }\n for e in entries\n ]\n logger.reflect(\"Entries listed\", {\"dict_id\": dictionary_id, \"total\": total, \"source_language\": source_language, \"target_language\": target_language})\n return {\"items\": items, \"total\": total, \"page\": page, \"page_size\": page_size}\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion list_dictionary_entries\n" + "body": "# #region list_dictionary_entries [C:4] [TYPE Function]\n# @BRIEF List entries for a dictionary, optionally filtered by language pair.\n# @PRE: User has translate.dictionary.view permission.\n# @POST: Returns paginated list of entries with language pair fields.\n@router.get(\"/dictionaries/{dictionary_id}/entries\")\nasync def list_dictionary_entries(\n dictionary_id: str,\n page: int = Query(1, ge=1),\n page_size: int = Query(50, ge=1, le=500),\n source_language: str | None = Query(None, description=\"Filter by BCP-47 source language\"),\n target_language: str | None = Query(None, description=\"Filter by BCP-47 target language\"),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"List entries for a dictionary.\"\"\"\n with belief_scope(\"list_dictionary_entries\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n entries, total = DictionaryManager.list_entries(db, dictionary_id, page=page, page_size=page_size)\n # Apply language pair filtering\n if source_language or target_language:\n filtered = []\n for e in entries:\n if source_language and e.source_language != source_language and e.source_language != \"und\":\n continue\n if target_language and e.target_language != target_language:\n continue\n filtered.append(e)\n entries = filtered\n total = len(filtered)\n items = [\n {\n \"id\": e.id,\n \"dictionary_id\": e.dictionary_id,\n \"source_term\": e.source_term,\n \"source_term_normalized\": e.source_term_normalized,\n \"target_term\": e.target_term,\n \"source_language\": e.source_language,\n \"target_language\": e.target_language,\n \"context_notes\": e.context_notes,\n \"context_data\": e.context_data,\n \"usage_notes\": e.usage_notes,\n \"has_context\": e.has_context,\n \"context_source\": e.context_source,\n \"origin_source_language\": e.origin_source_language,\n \"created_at\": e.created_at,\n \"updated_at\": e.updated_at,\n }\n for e in entries\n ]\n logger.reflect(\"Entries listed\", {\"dict_id\": dictionary_id, \"total\": total, \"source_language\": source_language, \"target_language\": target_language})\n return {\"items\": items, \"total\": total, \"page\": page, \"page_size\": page_size}\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion list_dictionary_entries\n" }, { "contract_id": "add_dictionary_entry", @@ -22330,9 +22121,10 @@ "file_path": "backend/src/api/routes/translate/_dictionary_routes.py", "start_line": 223, "end_line": 269, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Entry is created.", "PRE": "User has translate.dictionary.edit permission.", "PURPOSE": "Add a new entry to a dictionary." @@ -22340,27 +22132,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region add_dictionary_entry [TYPE Function]\n# @BRIEF Add a new entry to a dictionary.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Entry is created.\n@router.post(\"/dictionaries/{dictionary_id}/entries\", status_code=status.HTTP_201_CREATED)\nasync def add_dictionary_entry(\n dictionary_id: str,\n payload: DictionaryEntryCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Add a new entry to a dictionary.\"\"\"\n with belief_scope(\"add_dictionary_entry\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n entry = DictionaryManager.add_entry(\n db, dictionary_id,\n source_term=payload.source_term,\n target_term=payload.target_term,\n context_notes=payload.context_notes,\n source_language=payload.source_language,\n target_language=payload.target_language,\n )\n logger.reflect(\"Entry added\", {\"entry_id\": entry.id})\n return {\n \"id\": entry.id,\n \"dictionary_id\": entry.dictionary_id,\n \"source_term\": entry.source_term,\n \"source_term_normalized\": entry.source_term_normalized,\n \"target_term\": entry.target_term,\n \"source_language\": entry.source_language,\n \"target_language\": entry.target_language,\n \"context_notes\": entry.context_notes,\n \"context_data\": entry.context_data,\n \"usage_notes\": entry.usage_notes,\n \"has_context\": entry.has_context,\n \"context_source\": entry.context_source,\n \"origin_source_language\": entry.origin_source_language,\n \"created_at\": entry.created_at,\n \"updated_at\": entry.updated_at,\n }\n except ValueError as e:\n if \"already exists\" in str(e):\n raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(e))\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion add_dictionary_entry\n" + "body": "# #region add_dictionary_entry [C:4] [TYPE Function]\n# @BRIEF Add a new entry to a dictionary.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Entry is created.\n@router.post(\"/dictionaries/{dictionary_id}/entries\", status_code=status.HTTP_201_CREATED)\nasync def add_dictionary_entry(\n dictionary_id: str,\n payload: DictionaryEntryCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Add a new entry to a dictionary.\"\"\"\n with belief_scope(\"add_dictionary_entry\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n try:\n entry = DictionaryManager.add_entry(\n db, dictionary_id,\n source_term=payload.source_term,\n target_term=payload.target_term,\n context_notes=payload.context_notes,\n source_language=payload.source_language,\n target_language=payload.target_language,\n )\n logger.reflect(\"Entry added\", {\"entry_id\": entry.id})\n return {\n \"id\": entry.id,\n \"dictionary_id\": entry.dictionary_id,\n \"source_term\": entry.source_term,\n \"source_term_normalized\": entry.source_term_normalized,\n \"target_term\": entry.target_term,\n \"source_language\": entry.source_language,\n \"target_language\": entry.target_language,\n \"context_notes\": entry.context_notes,\n \"context_data\": entry.context_data,\n \"usage_notes\": entry.usage_notes,\n \"has_context\": entry.has_context,\n \"context_source\": entry.context_source,\n \"origin_source_language\": entry.origin_source_language,\n \"created_at\": entry.created_at,\n \"updated_at\": entry.updated_at,\n }\n except ValueError as e:\n if \"already exists\" in str(e):\n raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(e))\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion add_dictionary_entry\n" }, { "contract_id": "edit_dictionary_entry", @@ -22368,9 +22160,10 @@ "file_path": "backend/src/api/routes/translate/_dictionary_routes.py", "start_line": 272, "end_line": 319, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Entry is updated.", "PRE": "User has translate.dictionary.edit permission.", "PURPOSE": "Update an existing dictionary entry." @@ -22378,27 +22171,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region edit_dictionary_entry [TYPE Function]\n# @BRIEF Update an existing dictionary entry.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Entry is updated.\n@router.put(\"/dictionaries/{dictionary_id}/entries/{entry_id}\")\nasync def edit_dictionary_entry(\n dictionary_id: str,\n entry_id: str,\n payload: DictionaryEntryCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Update an existing dictionary entry.\"\"\"\n with belief_scope(\"edit_dictionary_entry\"):\n logger.reason(f\"Entry: {entry_id}, User: {current_user.username}\")\n try:\n entry = DictionaryManager.edit_entry(\n db, entry_id,\n source_term=payload.source_term,\n target_term=payload.target_term,\n context_notes=payload.context_notes,\n source_language=payload.source_language,\n target_language=payload.target_language,\n )\n logger.reflect(\"Entry updated\", {\"entry_id\": entry_id})\n return {\n \"id\": entry.id,\n \"dictionary_id\": entry.dictionary_id,\n \"source_term\": entry.source_term,\n \"source_term_normalized\": entry.source_term_normalized,\n \"target_term\": entry.target_term,\n \"source_language\": entry.source_language,\n \"target_language\": entry.target_language,\n \"context_notes\": entry.context_notes,\n \"context_data\": entry.context_data,\n \"usage_notes\": entry.usage_notes,\n \"has_context\": entry.has_context,\n \"context_source\": entry.context_source,\n \"origin_source_language\": entry.origin_source_language,\n \"created_at\": entry.created_at,\n \"updated_at\": entry.updated_at,\n }\n except ValueError as e:\n if \"already exists\" in str(e):\n raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(e))\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion edit_dictionary_entry\n" + "body": "# #region edit_dictionary_entry [C:4] [TYPE Function]\n# @BRIEF Update an existing dictionary entry.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Entry is updated.\n@router.put(\"/dictionaries/{dictionary_id}/entries/{entry_id}\")\nasync def edit_dictionary_entry(\n dictionary_id: str,\n entry_id: str,\n payload: DictionaryEntryCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Update an existing dictionary entry.\"\"\"\n with belief_scope(\"edit_dictionary_entry\"):\n logger.reason(f\"Entry: {entry_id}, User: {current_user.username}\")\n try:\n entry = DictionaryManager.edit_entry(\n db, entry_id,\n source_term=payload.source_term,\n target_term=payload.target_term,\n context_notes=payload.context_notes,\n source_language=payload.source_language,\n target_language=payload.target_language,\n )\n logger.reflect(\"Entry updated\", {\"entry_id\": entry_id})\n return {\n \"id\": entry.id,\n \"dictionary_id\": entry.dictionary_id,\n \"source_term\": entry.source_term,\n \"source_term_normalized\": entry.source_term_normalized,\n \"target_term\": entry.target_term,\n \"source_language\": entry.source_language,\n \"target_language\": entry.target_language,\n \"context_notes\": entry.context_notes,\n \"context_data\": entry.context_data,\n \"usage_notes\": entry.usage_notes,\n \"has_context\": entry.has_context,\n \"context_source\": entry.context_source,\n \"origin_source_language\": entry.origin_source_language,\n \"created_at\": entry.created_at,\n \"updated_at\": entry.updated_at,\n }\n except ValueError as e:\n if \"already exists\" in str(e):\n raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(e))\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion edit_dictionary_entry\n" }, { "contract_id": "delete_dictionary_entry", @@ -22406,9 +22199,10 @@ "file_path": "backend/src/api/routes/translate/_dictionary_routes.py", "start_line": 322, "end_line": 343, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Entry is deleted.", "PRE": "User has translate.dictionary.edit permission.", "PURPOSE": "Delete a dictionary entry." @@ -22416,37 +22210,38 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region delete_dictionary_entry [TYPE Function]\n# @BRIEF Delete a dictionary entry.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Entry is deleted.\n@router.delete(\"/dictionaries/{dictionary_id}/entries/{entry_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_dictionary_entry(\n dictionary_id: str,\n entry_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Delete a dictionary entry.\"\"\"\n with belief_scope(\"delete_dictionary_entry\"):\n logger.reason(f\"Entry: {entry_id}, User: {current_user.username}\")\n try:\n DictionaryManager.delete_entry(db, entry_id)\n logger.reflect(\"Entry deleted\", {\"entry_id\": entry_id})\n return None\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion delete_dictionary_entry\n" + "body": "# #region delete_dictionary_entry [C:4] [TYPE Function]\n# @BRIEF Delete a dictionary entry.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Entry is deleted.\n@router.delete(\"/dictionaries/{dictionary_id}/entries/{entry_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_dictionary_entry(\n dictionary_id: str,\n entry_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Delete a dictionary entry.\"\"\"\n with belief_scope(\"delete_dictionary_entry\"):\n logger.reason(f\"Entry: {entry_id}, User: {current_user.username}\")\n try:\n DictionaryManager.delete_entry(db, entry_id)\n logger.reflect(\"Entry deleted\", {\"entry_id\": entry_id})\n return None\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion delete_dictionary_entry\n" }, { "contract_id": "import_dictionary_entries", "contract_type": "Function", "file_path": "backend/src/api/routes/translate/_dictionary_routes.py", "start_line": 346, - "end_line": 387, - "tier": "TIER_1", - "complexity": 1, + "end_line": 389, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": "4", "POST": "Entries are imported per conflict mode.", "PRE": "User has translate.dictionary.edit permission.", "PURPOSE": "Import entries into a terminology dictionary from CSV/TSV content." @@ -22454,27 +22249,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region import_dictionary_entries [TYPE Function]\n# @BRIEF Import entries into a terminology dictionary from CSV/TSV content.\n# @PRE: User has translate.dictionary.edit permission.\n# @POST: Entries are imported per conflict mode.\n@router.post(\"/dictionaries/{dictionary_id}/import\")\nasync def import_dictionary_entries(\n dictionary_id: str,\n payload: DictionaryImport,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Import entries into a terminology dictionary from CSV/TSV content.\"\"\"\n with belief_scope(\"import_dictionary_entries\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n\n if payload.on_conflict not in (\"overwrite\", \"keep_existing\", \"cancel\"):\n raise HTTPException(\n status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,\n detail=\"on_conflict must be 'overwrite', 'keep_existing', or 'cancel'\",\n )\n\n try:\n result = DictionaryManager.import_entries(\n db,\n dict_id=dictionary_id,\n content=payload.content,\n delimiter=payload.delimiter,\n on_conflict=payload.on_conflict,\n preview_only=payload.preview_only,\n default_source_language=payload.default_source_language,\n default_target_language=payload.default_target_language,\n )\n logger.reflect(\"Import completed\", {\n \"dict_id\": dictionary_id,\n \"total\": result[\"total\"],\n \"errors\": len(result[\"errors\"]),\n })\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion import_dictionary_entries\n" + "body": "# #region import_dictionary_entries [C:4] [TYPE Function]\n# @BRIEF Import entries into a terminology dictionary from CSV/TSV content.\n# @PRE User has translate.dictionary.edit permission.\n# @POST Entries are imported per conflict mode.\n# @COMPLEXITY 4\n\n@router.post(\"/dictionaries/{dictionary_id}/import\")\nasync def import_dictionary_entries(\n dictionary_id: str,\n payload: DictionaryImport,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.dictionary\", \"EDIT\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Import entries into a terminology dictionary from CSV/TSV content.\"\"\"\n with belief_scope(\"import_dictionary_entries\"):\n logger.reason(f\"Dict: {dictionary_id}, User: {current_user.username}\")\n\n if payload.on_conflict not in (\"overwrite\", \"keep_existing\", \"cancel\"):\n raise HTTPException(\n status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,\n detail=\"on_conflict must be 'overwrite', 'keep_existing', or 'cancel'\",\n )\n\n try:\n result = DictionaryManager.import_entries(\n db,\n dict_id=dictionary_id,\n content=payload.content,\n delimiter=payload.delimiter,\n on_conflict=payload.on_conflict,\n preview_only=payload.preview_only,\n default_source_language=payload.default_source_language,\n default_target_language=payload.default_target_language,\n )\n logger.reflect(\"Import completed\", {\n \"dict_id\": dictionary_id,\n \"total\": result[\"total\"],\n \"errors\": len(result[\"errors\"]),\n })\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion import_dictionary_entries\n" }, { "contract_id": "TranslateHelpersModule", @@ -22510,7 +22305,7 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslateHelpersModule [C:2] [TYPE Module] [SEMANTICS sqlalchemy, translate, helper, query, mapping]\n# @BRIEF Shared helper functions for translate route handlers.\n# @LAYER: API\n# @RELATION DEPENDS_ON -> [models.translate]\n\nfrom typing import Any\n\nfrom sqlalchemy.orm import Session\n\n\n# #region _run_to_response [C:2] [TYPE Function]\n# @BRIEF Convert TranslationRun ORM to response dict.\ndef _run_to_response(run: Any) -> dict:\n return {\n \"id\": run.id,\n \"job_id\": run.job_id,\n \"status\": run.status,\n \"trigger_type\": run.trigger_type,\n \"started_at\": run.started_at.isoformat() if run.started_at else None,\n \"completed_at\": run.completed_at.isoformat() if run.completed_at else None,\n \"error_message\": run.error_message,\n \"total_records\": run.total_records or 0,\n \"successful_records\": run.successful_records or 0,\n \"failed_records\": run.failed_records or 0,\n \"skipped_records\": run.skipped_records or 0,\n \"insert_status\": run.insert_status,\n \"superset_execution_id\": run.superset_execution_id,\n \"config_snapshot\": run.config_snapshot,\n \"key_hash\": run.key_hash,\n \"config_hash\": run.config_hash,\n \"dict_snapshot_hash\": run.dict_snapshot_hash,\n \"created_by\": run.created_by,\n \"created_at\": run.created_at.isoformat() if run.created_at else None,\n }\n# #endregion _run_to_response\n\n\n# #region _dict_to_response [C:2] [TYPE Function]\n# @BRIEF Convert a TerminologyDictionary ORM model to a response dict with computed entry_count.\ndef _dict_to_response(d: Any, entry_count: int = 0) -> dict:\n return {\n \"id\": d.id,\n \"name\": d.name,\n \"description\": d.description,\n \"source_dialect\": d.source_dialect,\n \"target_dialect\": d.target_dialect,\n \"is_active\": d.is_active,\n \"created_by\": d.created_by,\n \"created_at\": d.created_at,\n \"updated_at\": d.updated_at,\n \"entry_count\": entry_count,\n }\n# #endregion _dict_to_response\n\n\n# #region _get_dictionary_entry_counts [C:2] [TYPE Function]\n# @BRIEF Get entry counts for a list of dictionary IDs.\ndef _get_dictionary_entry_counts(db: Session, dict_ids: list[str]) -> dict[str, int]:\n from sqlalchemy import func\n\n from ....models.translate import DictionaryEntry\n counts = (\n db.query(DictionaryEntry.dictionary_id, func.count(DictionaryEntry.id))\n .filter(DictionaryEntry.dictionary_id.in_(dict_ids))\n .group_by(DictionaryEntry.dictionary_id)\n .all()\n )\n return {row[0]: row[1] for row in counts}\n# #endregion _get_dictionary_entry_counts\n\n# #endregion TranslateHelpersModule\n" + "body": "# #region TranslateHelpersModule [C:2] [TYPE Module] [SEMANTICS sqlalchemy, translate, helper, query, mapping]\n# @BRIEF Shared helper functions for translate route handlers.\n# @LAYER API\n# @RELATION DEPENDS_ON -> [models.translate]\n\nfrom typing import Any\n\nfrom sqlalchemy.orm import Session\n\n\n# #region _run_to_response [C:2] [TYPE Function]\n# @BRIEF Convert TranslationRun ORM to response dict.\ndef _run_to_response(run: Any) -> dict:\n return {\n \"id\": run.id,\n \"job_id\": run.job_id,\n \"status\": run.status,\n \"trigger_type\": run.trigger_type,\n \"started_at\": run.started_at.isoformat() if run.started_at else None,\n \"completed_at\": run.completed_at.isoformat() if run.completed_at else None,\n \"error_message\": run.error_message,\n \"total_records\": run.total_records or 0,\n \"successful_records\": run.successful_records or 0,\n \"failed_records\": run.failed_records or 0,\n \"skipped_records\": run.skipped_records or 0,\n \"insert_status\": run.insert_status,\n \"superset_execution_id\": run.superset_execution_id,\n \"config_snapshot\": run.config_snapshot,\n \"key_hash\": run.key_hash,\n \"config_hash\": run.config_hash,\n \"dict_snapshot_hash\": run.dict_snapshot_hash,\n \"created_by\": run.created_by,\n \"created_at\": run.created_at.isoformat() if run.created_at else None,\n }\n# #endregion _run_to_response\n\n\n# #region _dict_to_response [C:2] [TYPE Function]\n# @BRIEF Convert a TerminologyDictionary ORM model to a response dict with computed entry_count.\ndef _dict_to_response(d: Any, entry_count: int = 0) -> dict:\n return {\n \"id\": d.id,\n \"name\": d.name,\n \"description\": d.description,\n \"source_dialect\": d.source_dialect,\n \"target_dialect\": d.target_dialect,\n \"is_active\": d.is_active,\n \"created_by\": d.created_by,\n \"created_at\": d.created_at,\n \"updated_at\": d.updated_at,\n \"entry_count\": entry_count,\n }\n# #endregion _dict_to_response\n\n\n# #region _get_dictionary_entry_counts [C:2] [TYPE Function]\n# @BRIEF Get entry counts for a list of dictionary IDs.\ndef _get_dictionary_entry_counts(db: Session, dict_ids: list[str]) -> dict[str, int]:\n from sqlalchemy import func\n\n from ....models.translate import DictionaryEntry\n counts = (\n db.query(DictionaryEntry.dictionary_id, func.count(DictionaryEntry.id))\n .filter(DictionaryEntry.dictionary_id.in_(dict_ids))\n .group_by(DictionaryEntry.dictionary_id)\n .all()\n )\n return {row[0]: row[1] for row in counts}\n# #endregion _get_dictionary_entry_counts\n\n# #endregion TranslateHelpersModule\n" }, { "contract_id": "_run_to_response", @@ -22571,7 +22366,7 @@ "contract_type": "Module", "file_path": "backend/src/api/routes/translate/_job_routes.py", "start_line": 1, - "end_line": 248, + "end_line": 249, "tier": "TIER_2", "complexity": 3, "metadata": { @@ -22593,7 +22388,7 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslateJobRoutesModule [C:3] [TYPE Module] [SEMANTICS fastapi, translate, api, search]\n# @BRIEF Translation Job CRUD and datasource column routes.\n# @LAYER: API\n\n\nfrom fastapi import Depends, HTTPException, Query, status\nfrom sqlalchemy.orm import Session\n\nfrom ....core.config_manager import ConfigManager\nfrom ....core.database import get_db\nfrom ....core.logger import belief_scope, logger\nfrom ....dependencies import get_config_manager, get_current_user, has_permission\nfrom ....plugins.translate.service import (\n TranslateJobService,\n job_to_response,\n)\nfrom ....plugins.translate.service import (\n get_datasource_columns as fetch_datasource_columns_service,\n)\nfrom ....schemas.auth import User\nfrom ....schemas.translate import (\n DatasourceColumnsResponse,\n DuplicateJobResponse,\n TranslateJobCreate,\n TranslateJobResponse,\n TranslateJobUpdate,\n)\nfrom ._router import router\n\n# ============================================================\n# Translation Job CRUD\n# ============================================================\n\n# #region list_jobs [TYPE Function]\n# @BRIEF List all translation jobs.\n# @PRE: User has translate.job.view permission.\n# @POST: Returns list of translation jobs.\n@router.get(\"/jobs\", response_model=list[TranslateJobResponse])\nasync def list_jobs(\n page: int = Query(1, ge=1),\n page_size: int = Query(20, ge=1, le=100),\n status: str | None = Query(None),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"List all translation jobs.\"\"\"\n logger.reason(f\"list_jobs — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n total, jobs = service.list_jobs(\n page=page,\n page_size=page_size,\n status_filter=status,\n )\n results = []\n for job in jobs:\n dict_ids = service.get_job_dictionary_ids(job.id)\n results.append(job_to_response(job, dict_ids))\n return results\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion list_jobs\n\n\n# #region get_job [TYPE Function]\n# @BRIEF Get a single translation job by ID.\n# @PRE: User has translate.job.view permission.\n# @POST: Returns the translation job.\n@router.get(\"/jobs/{job_id}\", response_model=TranslateJobResponse)\nasync def get_job(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get a translation job by ID.\"\"\"\n logger.reason(f\"get_job — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n job = service.get_job(job_id)\n dict_ids = service.get_job_dictionary_ids(job.id)\n return job_to_response(job, dict_ids)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_job\n\n\n# #region create_job [TYPE Function]\n# @BRIEF Create a new translation job.\n# @PRE: User has translate.job.create permission.\n# @POST: Returns the created translation job.\n# @SIDE_EFFECT: Validates columns via SupersetClient; caches database_dialect.\n@router.post(\"/jobs\", response_model=TranslateJobResponse, status_code=status.HTTP_201_CREATED)\nasync def create_job(\n payload: TranslateJobCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"CREATE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Create a new translation job.\"\"\"\n logger.reason(f\"create_job — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n job = service.create_job(payload)\n dict_ids = service.get_job_dictionary_ids(job.id)\n return job_to_response(job, dict_ids)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(e))\n# #endregion create_job\n\n\n# #region update_job [TYPE Function]\n# @BRIEF Update an existing translation job.\n# @PRE: User has translate.job.edit permission.\n# @POST: Returns the updated translation job.\n# @SIDE_EFFECT: Re-detects database_dialect if datasource changed.\n@router.put(\"/jobs/{job_id}\", response_model=TranslateJobResponse)\nasync def update_job(\n job_id: str,\n payload: TranslateJobUpdate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EDIT\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Update a translation job.\"\"\"\n logger.reason(f\"update_job — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n job = service.update_job(job_id, payload)\n dict_ids = service.get_job_dictionary_ids(job.id)\n return job_to_response(job, dict_ids)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion update_job\n\n\n# #region delete_job [TYPE Function]\n# @BRIEF Delete a translation job.\n# @PRE: User has translate.job.delete permission.\n# @POST: Job is deleted.\n@router.delete(\"/jobs/{job_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_job(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"DELETE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Delete a translation job.\"\"\"\n logger.reason(f\"delete_job — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n service.delete_job(job_id)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion delete_job\n\n\n# #region duplicate_job [TYPE Function]\n# @BRIEF Duplicate a translation job.\n# @PRE: User has translate.job.create permission.\n# @POST: Returns the duplicated job with status DRAFT.\n@router.post(\"/jobs/{job_id}/duplicate\", response_model=DuplicateJobResponse, status_code=status.HTTP_201_CREATED)\nasync def duplicate_job(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"CREATE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Duplicate a translation job.\"\"\"\n logger.reason(f\"duplicate_job — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n new_job = service.duplicate_job(job_id)\n return DuplicateJobResponse(\n id=new_job.id,\n name=new_job.name,\n message=\"Job duplicated successfully\",\n )\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion duplicate_job\n\n\n# #region get_datasource_columns [TYPE Function]\n# @BRIEF Get column metadata and database dialect for a Superset datasource.\n# @PRE: User has translate.job.view permission.\n# @POST: Returns column list with metadata and database_dialect.\n# @SIDE_EFFECT: Queries Superset API for dataset detail and database info.\n# @RATIONALE: Dialect detection from Superset connection cached on TranslationJob at save time.\n# @REJECTED: Hardcoding dialect list per database — would drift from actual Superset config.\n\n@router.get(\"/datasources\")\nasync def list_datasources(\n env_id: str = Query(..., description=\"Superset environment ID\"),\n search: str | None = Query(None, description=\"Search by table name\"),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"List all Superset datasets available for translation jobs.\"\"\"\n with belief_scope(\"list_datasources\"):\n try:\n service = TranslateJobService(db, config_manager)\n datasets = service.fetch_available_datasources(env_id, search)\n return datasets\n except Exception as e:\n logger.explore(\"list_datasources failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=str(e))\n\n@router.get(\"/datasources/{datasource_id}/columns\", response_model=DatasourceColumnsResponse)\nasync def get_datasource_columns(\n datasource_id: int,\n env_id: str = Query(..., description=\"Superset environment ID\"),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get column metadata and database dialect for a Superset datasource.\"\"\"\n logger.reason(\n f\"get_datasource_columns — Datasource: {datasource_id}, Env: {env_id}, User: {current_user.username}\",\n extra={\"src\": \"translate_routes\"}\n )\n try:\n result = fetch_datasource_columns_service(\n datasource_id=datasource_id,\n env_id=env_id,\n config_manager=config_manager,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"get_datasource_columns failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(\n status_code=status.HTTP_502_BAD_GATEWAY,\n detail=f\"Failed to fetch datasource columns from Superset: {e}\",\n )\n# #endregion get_datasource_columns\n\n# #endregion TranslateJobRoutesModule\n" + "body": "# #region TranslateJobRoutesModule [C:3] [TYPE Module] [SEMANTICS fastapi, translate, api, search]\n# @BRIEF Translation Job CRUD and datasource column routes.\n# @LAYER: API\n\n\nfrom fastapi import Depends, HTTPException, Query, status\nfrom sqlalchemy.orm import Session\n\nfrom ....core.config_manager import ConfigManager\nfrom ....core.database import get_db\nfrom ....core.logger import belief_scope, logger\nfrom ....dependencies import get_config_manager, get_current_user, has_permission\nfrom ....plugins.translate.service import (\n TranslateJobService,\n job_to_response,\n)\nfrom ....plugins.translate.service import (\n get_datasource_columns as fetch_datasource_columns_service,\n)\nfrom ....schemas.auth import User\nfrom ....schemas.translate import (\n DatasourceColumnsResponse,\n DuplicateJobResponse,\n TranslateJobCreate,\n TranslateJobResponse,\n TranslateJobUpdate,\n)\nfrom ._router import router\n\n# ============================================================\n# Translation Job CRUD\n# ============================================================\n\n# #region list_jobs [C:4] [TYPE Function]\n# @BRIEF List all translation jobs.\n# @PRE: User has translate.job.view permission.\n# @POST: Returns list of translation jobs.\n@router.get(\"/jobs\", response_model=list[TranslateJobResponse])\nasync def list_jobs(\n page: int = Query(1, ge=1),\n page_size: int = Query(20, ge=1, le=100),\n status: str | None = Query(None),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"List all translation jobs.\"\"\"\n logger.reason(f\"list_jobs — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n total, jobs = service.list_jobs(\n page=page,\n page_size=page_size,\n status_filter=status,\n )\n results = []\n for job in jobs:\n dict_ids = service.get_job_dictionary_ids(job.id)\n results.append(job_to_response(job, dict_ids))\n return results\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion list_jobs\n\n\n# #region get_job [C:4] [TYPE Function]\n# @BRIEF Get a single translation job by ID.\n# @PRE: User has translate.job.view permission.\n# @POST: Returns the translation job.\n@router.get(\"/jobs/{job_id}\", response_model=TranslateJobResponse)\nasync def get_job(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get a translation job by ID.\"\"\"\n logger.reason(f\"get_job — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n job = service.get_job(job_id)\n dict_ids = service.get_job_dictionary_ids(job.id)\n return job_to_response(job, dict_ids)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_job\n\n\n# #region create_job [C:4] [TYPE Function]\n# @BRIEF Create a new translation job.\n# @PRE: User has translate.job.create permission.\n# @POST: Returns the created translation job.\n# @SIDE_EFFECT: Validates columns via SupersetClient; caches database_dialect.\n@router.post(\"/jobs\", response_model=TranslateJobResponse, status_code=status.HTTP_201_CREATED)\nasync def create_job(\n payload: TranslateJobCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"CREATE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Create a new translation job.\"\"\"\n logger.reason(f\"create_job — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n job = service.create_job(payload)\n dict_ids = service.get_job_dictionary_ids(job.id)\n return job_to_response(job, dict_ids)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(e))\n# #endregion create_job\n\n\n# #region update_job [C:4] [TYPE Function]\n# @BRIEF Update an existing translation job.\n# @PRE: User has translate.job.edit permission.\n# @POST: Returns the updated translation job.\n# @SIDE_EFFECT: Re-detects database_dialect if datasource changed.\n@router.put(\"/jobs/{job_id}\", response_model=TranslateJobResponse)\nasync def update_job(\n job_id: str,\n payload: TranslateJobUpdate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EDIT\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Update a translation job.\"\"\"\n logger.reason(f\"update_job — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n job = service.update_job(job_id, payload)\n dict_ids = service.get_job_dictionary_ids(job.id)\n return job_to_response(job, dict_ids)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion update_job\n\n\n# #region delete_job [C:4] [TYPE Function]\n# @BRIEF Delete a translation job.\n# @PRE: User has translate.job.delete permission.\n# @POST: Job is deleted.\n@router.delete(\"/jobs/{job_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_job(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"DELETE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Delete a translation job.\"\"\"\n logger.reason(f\"delete_job — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n service.delete_job(job_id)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion delete_job\n\n\n# #region duplicate_job [C:4] [TYPE Function]\n# @BRIEF Duplicate a translation job.\n# @PRE: User has translate.job.create permission.\n# @POST: Returns the duplicated job with status DRAFT.\n@router.post(\"/jobs/{job_id}/duplicate\", response_model=DuplicateJobResponse, status_code=status.HTTP_201_CREATED)\nasync def duplicate_job(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"CREATE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Duplicate a translation job.\"\"\"\n logger.reason(f\"duplicate_job — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n new_job = service.duplicate_job(job_id)\n return DuplicateJobResponse(\n id=new_job.id,\n name=new_job.name,\n message=\"Job duplicated successfully\",\n )\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion duplicate_job\n\n\n# #region get_datasource_columns [C:4] [TYPE Function]\n# @BRIEF Get column metadata and database dialect for a Superset datasource.\n# @PRE User has translate.job.view permission.\n# @POST Returns column list with metadata and database_dialect.\n# @SIDE_EFFECT Queries Superset API for dataset detail and database info.\n# @RATIONALE Dialect detection from Superset connection cached on TranslationJob at save time.\n# @REJECTED Hardcoding dialect list per database — would drift from actual Superset config.\n# @COMPLEXITY 4\n\n@router.get(\"/datasources\")\nasync def list_datasources(\n env_id: str = Query(..., description=\"Superset environment ID\"),\n search: str | None = Query(None, description=\"Search by table name\"),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"List all Superset datasets available for translation jobs.\"\"\"\n with belief_scope(\"list_datasources\"):\n try:\n service = TranslateJobService(db, config_manager)\n datasets = service.fetch_available_datasources(env_id, search)\n return datasets\n except Exception as e:\n logger.explore(\"list_datasources failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=str(e))\n\n@router.get(\"/datasources/{datasource_id}/columns\", response_model=DatasourceColumnsResponse)\nasync def get_datasource_columns(\n datasource_id: int,\n env_id: str = Query(..., description=\"Superset environment ID\"),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get column metadata and database dialect for a Superset datasource.\"\"\"\n logger.reason(\n f\"get_datasource_columns — Datasource: {datasource_id}, Env: {env_id}, User: {current_user.username}\",\n extra={\"src\": \"translate_routes\"}\n )\n try:\n result = fetch_datasource_columns_service(\n datasource_id=datasource_id,\n env_id=env_id,\n config_manager=config_manager,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"get_datasource_columns failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(\n status_code=status.HTTP_502_BAD_GATEWAY,\n detail=f\"Failed to fetch datasource columns from Superset: {e}\",\n )\n# #endregion get_datasource_columns\n\n# #endregion TranslateJobRoutesModule\n" }, { "contract_id": "list_jobs", @@ -22601,9 +22396,10 @@ "file_path": "backend/src/api/routes/translate/_job_routes.py", "start_line": 34, "end_line": 64, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns list of translation jobs.", "PRE": "User has translate.job.view permission.", "PURPOSE": "List all translation jobs." @@ -22611,27 +22407,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region list_jobs [TYPE Function]\n# @BRIEF List all translation jobs.\n# @PRE: User has translate.job.view permission.\n# @POST: Returns list of translation jobs.\n@router.get(\"/jobs\", response_model=list[TranslateJobResponse])\nasync def list_jobs(\n page: int = Query(1, ge=1),\n page_size: int = Query(20, ge=1, le=100),\n status: str | None = Query(None),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"List all translation jobs.\"\"\"\n logger.reason(f\"list_jobs — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n total, jobs = service.list_jobs(\n page=page,\n page_size=page_size,\n status_filter=status,\n )\n results = []\n for job in jobs:\n dict_ids = service.get_job_dictionary_ids(job.id)\n results.append(job_to_response(job, dict_ids))\n return results\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion list_jobs\n" + "body": "# #region list_jobs [C:4] [TYPE Function]\n# @BRIEF List all translation jobs.\n# @PRE: User has translate.job.view permission.\n# @POST: Returns list of translation jobs.\n@router.get(\"/jobs\", response_model=list[TranslateJobResponse])\nasync def list_jobs(\n page: int = Query(1, ge=1),\n page_size: int = Query(20, ge=1, le=100),\n status: str | None = Query(None),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"List all translation jobs.\"\"\"\n logger.reason(f\"list_jobs — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n total, jobs = service.list_jobs(\n page=page,\n page_size=page_size,\n status_filter=status,\n )\n results = []\n for job in jobs:\n dict_ids = service.get_job_dictionary_ids(job.id)\n results.append(job_to_response(job, dict_ids))\n return results\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion list_jobs\n" }, { "contract_id": "get_job", @@ -22639,9 +22435,10 @@ "file_path": "backend/src/api/routes/translate/_job_routes.py", "start_line": 67, "end_line": 88, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns the translation job.", "PRE": "User has translate.job.view permission.", "PURPOSE": "Get a single translation job by ID." @@ -22649,27 +22446,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region get_job [TYPE Function]\n# @BRIEF Get a single translation job by ID.\n# @PRE: User has translate.job.view permission.\n# @POST: Returns the translation job.\n@router.get(\"/jobs/{job_id}\", response_model=TranslateJobResponse)\nasync def get_job(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get a translation job by ID.\"\"\"\n logger.reason(f\"get_job — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n job = service.get_job(job_id)\n dict_ids = service.get_job_dictionary_ids(job.id)\n return job_to_response(job, dict_ids)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_job\n" + "body": "# #region get_job [C:4] [TYPE Function]\n# @BRIEF Get a single translation job by ID.\n# @PRE: User has translate.job.view permission.\n# @POST: Returns the translation job.\n@router.get(\"/jobs/{job_id}\", response_model=TranslateJobResponse)\nasync def get_job(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get a translation job by ID.\"\"\"\n logger.reason(f\"get_job — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n job = service.get_job(job_id)\n dict_ids = service.get_job_dictionary_ids(job.id)\n return job_to_response(job, dict_ids)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_job\n" }, { "contract_id": "create_job", @@ -22677,9 +22474,10 @@ "file_path": "backend/src/api/routes/translate/_job_routes.py", "start_line": 91, "end_line": 113, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns the created translation job.", "PRE": "User has translate.job.create permission.", "PURPOSE": "Create a new translation job.", @@ -22688,36 +22486,18 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "SIDE_EFFECT", - "message": "@SIDE_EFFECT is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region create_job [TYPE Function]\n# @BRIEF Create a new translation job.\n# @PRE: User has translate.job.create permission.\n# @POST: Returns the created translation job.\n# @SIDE_EFFECT: Validates columns via SupersetClient; caches database_dialect.\n@router.post(\"/jobs\", response_model=TranslateJobResponse, status_code=status.HTTP_201_CREATED)\nasync def create_job(\n payload: TranslateJobCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"CREATE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Create a new translation job.\"\"\"\n logger.reason(f\"create_job — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n job = service.create_job(payload)\n dict_ids = service.get_job_dictionary_ids(job.id)\n return job_to_response(job, dict_ids)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(e))\n# #endregion create_job\n" + "body": "# #region create_job [C:4] [TYPE Function]\n# @BRIEF Create a new translation job.\n# @PRE: User has translate.job.create permission.\n# @POST: Returns the created translation job.\n# @SIDE_EFFECT: Validates columns via SupersetClient; caches database_dialect.\n@router.post(\"/jobs\", response_model=TranslateJobResponse, status_code=status.HTTP_201_CREATED)\nasync def create_job(\n payload: TranslateJobCreate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"CREATE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Create a new translation job.\"\"\"\n logger.reason(f\"create_job — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n job = service.create_job(payload)\n dict_ids = service.get_job_dictionary_ids(job.id)\n return job_to_response(job, dict_ids)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(e))\n# #endregion create_job\n" }, { "contract_id": "update_job", @@ -22725,9 +22505,10 @@ "file_path": "backend/src/api/routes/translate/_job_routes.py", "start_line": 116, "end_line": 139, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns the updated translation job.", "PRE": "User has translate.job.edit permission.", "PURPOSE": "Update an existing translation job.", @@ -22736,36 +22517,18 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "SIDE_EFFECT", - "message": "@SIDE_EFFECT is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region update_job [TYPE Function]\n# @BRIEF Update an existing translation job.\n# @PRE: User has translate.job.edit permission.\n# @POST: Returns the updated translation job.\n# @SIDE_EFFECT: Re-detects database_dialect if datasource changed.\n@router.put(\"/jobs/{job_id}\", response_model=TranslateJobResponse)\nasync def update_job(\n job_id: str,\n payload: TranslateJobUpdate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EDIT\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Update a translation job.\"\"\"\n logger.reason(f\"update_job — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n job = service.update_job(job_id, payload)\n dict_ids = service.get_job_dictionary_ids(job.id)\n return job_to_response(job, dict_ids)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion update_job\n" + "body": "# #region update_job [C:4] [TYPE Function]\n# @BRIEF Update an existing translation job.\n# @PRE: User has translate.job.edit permission.\n# @POST: Returns the updated translation job.\n# @SIDE_EFFECT: Re-detects database_dialect if datasource changed.\n@router.put(\"/jobs/{job_id}\", response_model=TranslateJobResponse)\nasync def update_job(\n job_id: str,\n payload: TranslateJobUpdate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EDIT\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Update a translation job.\"\"\"\n logger.reason(f\"update_job — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n job = service.update_job(job_id, payload)\n dict_ids = service.get_job_dictionary_ids(job.id)\n return job_to_response(job, dict_ids)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion update_job\n" }, { "contract_id": "delete_job", @@ -22773,9 +22536,10 @@ "file_path": "backend/src/api/routes/translate/_job_routes.py", "start_line": 142, "end_line": 161, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Job is deleted.", "PRE": "User has translate.job.delete permission.", "PURPOSE": "Delete a translation job." @@ -22783,27 +22547,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region delete_job [TYPE Function]\n# @BRIEF Delete a translation job.\n# @PRE: User has translate.job.delete permission.\n# @POST: Job is deleted.\n@router.delete(\"/jobs/{job_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_job(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"DELETE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Delete a translation job.\"\"\"\n logger.reason(f\"delete_job — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n service.delete_job(job_id)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion delete_job\n" + "body": "# #region delete_job [C:4] [TYPE Function]\n# @BRIEF Delete a translation job.\n# @PRE: User has translate.job.delete permission.\n# @POST: Job is deleted.\n@router.delete(\"/jobs/{job_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_job(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"DELETE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Delete a translation job.\"\"\"\n logger.reason(f\"delete_job — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n service.delete_job(job_id)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion delete_job\n" }, { "contract_id": "duplicate_job", @@ -22811,9 +22575,10 @@ "file_path": "backend/src/api/routes/translate/_job_routes.py", "start_line": 164, "end_line": 188, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns the duplicated job with status DRAFT.", "PRE": "User has translate.job.create permission.", "PURPOSE": "Duplicate a translation job." @@ -22821,37 +22586,38 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region duplicate_job [TYPE Function]\n# @BRIEF Duplicate a translation job.\n# @PRE: User has translate.job.create permission.\n# @POST: Returns the duplicated job with status DRAFT.\n@router.post(\"/jobs/{job_id}/duplicate\", response_model=DuplicateJobResponse, status_code=status.HTTP_201_CREATED)\nasync def duplicate_job(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"CREATE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Duplicate a translation job.\"\"\"\n logger.reason(f\"duplicate_job — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n new_job = service.duplicate_job(job_id)\n return DuplicateJobResponse(\n id=new_job.id,\n name=new_job.name,\n message=\"Job duplicated successfully\",\n )\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion duplicate_job\n" + "body": "# #region duplicate_job [C:4] [TYPE Function]\n# @BRIEF Duplicate a translation job.\n# @PRE: User has translate.job.create permission.\n# @POST: Returns the duplicated job with status DRAFT.\n@router.post(\"/jobs/{job_id}/duplicate\", response_model=DuplicateJobResponse, status_code=status.HTTP_201_CREATED)\nasync def duplicate_job(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"CREATE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Duplicate a translation job.\"\"\"\n logger.reason(f\"duplicate_job — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n service = TranslateJobService(db, config_manager, current_user.username)\n new_job = service.duplicate_job(job_id)\n return DuplicateJobResponse(\n id=new_job.id,\n name=new_job.name,\n message=\"Job duplicated successfully\",\n )\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion duplicate_job\n" }, { "contract_id": "get_datasource_columns", "contract_type": "Function", "file_path": "backend/src/api/routes/translate/_job_routes.py", "start_line": 191, - "end_line": 246, - "tier": "TIER_1", - "complexity": 1, + "end_line": 247, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": "4", "POST": "Returns column list with metadata and database_dialect.", "PRE": "User has translate.job.view permission.", "PURPOSE": "Get column metadata and database dialect for a Superset datasource.", @@ -22862,43 +22628,25 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "SIDE_EFFECT", - "message": "@SIDE_EFFECT is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region get_datasource_columns [TYPE Function]\n# @BRIEF Get column metadata and database dialect for a Superset datasource.\n# @PRE: User has translate.job.view permission.\n# @POST: Returns column list with metadata and database_dialect.\n# @SIDE_EFFECT: Queries Superset API for dataset detail and database info.\n# @RATIONALE: Dialect detection from Superset connection cached on TranslationJob at save time.\n# @REJECTED: Hardcoding dialect list per database — would drift from actual Superset config.\n\n@router.get(\"/datasources\")\nasync def list_datasources(\n env_id: str = Query(..., description=\"Superset environment ID\"),\n search: str | None = Query(None, description=\"Search by table name\"),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"List all Superset datasets available for translation jobs.\"\"\"\n with belief_scope(\"list_datasources\"):\n try:\n service = TranslateJobService(db, config_manager)\n datasets = service.fetch_available_datasources(env_id, search)\n return datasets\n except Exception as e:\n logger.explore(\"list_datasources failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=str(e))\n\n@router.get(\"/datasources/{datasource_id}/columns\", response_model=DatasourceColumnsResponse)\nasync def get_datasource_columns(\n datasource_id: int,\n env_id: str = Query(..., description=\"Superset environment ID\"),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get column metadata and database dialect for a Superset datasource.\"\"\"\n logger.reason(\n f\"get_datasource_columns — Datasource: {datasource_id}, Env: {env_id}, User: {current_user.username}\",\n extra={\"src\": \"translate_routes\"}\n )\n try:\n result = fetch_datasource_columns_service(\n datasource_id=datasource_id,\n env_id=env_id,\n config_manager=config_manager,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"get_datasource_columns failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(\n status_code=status.HTTP_502_BAD_GATEWAY,\n detail=f\"Failed to fetch datasource columns from Superset: {e}\",\n )\n# #endregion get_datasource_columns\n" + "body": "# #region get_datasource_columns [C:4] [TYPE Function]\n# @BRIEF Get column metadata and database dialect for a Superset datasource.\n# @PRE User has translate.job.view permission.\n# @POST Returns column list with metadata and database_dialect.\n# @SIDE_EFFECT Queries Superset API for dataset detail and database info.\n# @RATIONALE Dialect detection from Superset connection cached on TranslationJob at save time.\n# @REJECTED Hardcoding dialect list per database — would drift from actual Superset config.\n# @COMPLEXITY 4\n\n@router.get(\"/datasources\")\nasync def list_datasources(\n env_id: str = Query(..., description=\"Superset environment ID\"),\n search: str | None = Query(None, description=\"Search by table name\"),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"List all Superset datasets available for translation jobs.\"\"\"\n with belief_scope(\"list_datasources\"):\n try:\n service = TranslateJobService(db, config_manager)\n datasets = service.fetch_available_datasources(env_id, search)\n return datasets\n except Exception as e:\n logger.explore(\"list_datasources failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=str(e))\n\n@router.get(\"/datasources/{datasource_id}/columns\", response_model=DatasourceColumnsResponse)\nasync def get_datasource_columns(\n datasource_id: int,\n env_id: str = Query(..., description=\"Superset environment ID\"),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get column metadata and database dialect for a Superset datasource.\"\"\"\n logger.reason(\n f\"get_datasource_columns — Datasource: {datasource_id}, Env: {env_id}, User: {current_user.username}\",\n extra={\"src\": \"translate_routes\"}\n )\n try:\n result = fetch_datasource_columns_service(\n datasource_id=datasource_id,\n env_id=env_id,\n config_manager=config_manager,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"get_datasource_columns failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(\n status_code=status.HTTP_502_BAD_GATEWAY,\n detail=f\"Failed to fetch datasource columns from Superset: {e}\",\n )\n# #endregion get_datasource_columns\n" }, { "contract_id": "TranslateMetricsRoutesModule", "contract_type": "Module", "file_path": "backend/src/api/routes/translate/_metrics_routes.py", "start_line": 1, - "end_line": 63, + "end_line": 65, "tier": "TIER_1", "complexity": 2, "metadata": { @@ -22910,7 +22658,7 @@ "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslateMetricsRoutesModule [C:2] [TYPE Module] [SEMANTICS fastapi, translate, api, search]\n# @BRIEF Translation Metrics endpoints.\n# @LAYER: API\n\n\nfrom fastapi import Depends, HTTPException, Query, status\nfrom sqlalchemy.orm import Session\n\nfrom ....core.database import get_db\nfrom ....core.logger import logger\nfrom ....dependencies import get_current_user, has_permission\nfrom ....plugins.translate.metrics import TranslationMetrics\nfrom ....schemas.auth import User\nfrom ._router import router\n\n# ============================================================\n# Metrics\n# ============================================================\n\n# #region get_metrics [TYPE Function]\n# @BRIEF Get translation metrics, optionally filtered by job.\n# @PRE: User has translate.metrics.view permission.\n# @POST: Returns metrics data.\n@router.get(\"/metrics\")\nasync def get_metrics(\n job_id: str | None = Query(None),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.metrics\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get translation metrics.\"\"\"\n logger.reason(f\"get_metrics — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n metrics_svc = TranslationMetrics(db)\n if job_id:\n return metrics_svc.get_job_metrics(job_id)\n return metrics_svc.get_all_metrics()\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_metrics\n\n\n# #region get_job_metrics [TYPE Function]\n# @BRIEF Get aggregated metrics for a specific job.\n# @PRE: User has translate.metrics.view permission.\n# @POST: Returns metrics dict.\n@router.get(\"/jobs/{job_id}/metrics\")\nasync def get_job_metrics(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.metrics\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get aggregated metrics for a specific job.\"\"\"\n logger.reason(f\"get_job_metrics — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n metrics_svc = TranslationMetrics(db)\n return metrics_svc.get_job_metrics(job_id)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_job_metrics\n\n# #endregion TranslateMetricsRoutesModule\n" + "body": "# #region TranslateMetricsRoutesModule [C:2] [TYPE Module] [SEMANTICS fastapi, translate, api, search]\n# @BRIEF Translation Metrics endpoints.\n# @LAYER: API\n\n\nfrom fastapi import Depends, HTTPException, Query, status\nfrom sqlalchemy.orm import Session\n\nfrom ....core.database import get_db\nfrom ....core.logger import logger\nfrom ....dependencies import get_current_user, has_permission\nfrom ....plugins.translate.metrics import TranslationMetrics\nfrom ....schemas.auth import User\nfrom ._router import router\n\n# ============================================================\n# Metrics\n# ============================================================\n\n# #region get_metrics [C:4] [TYPE Function]\n# @BRIEF Get translation metrics, optionally filtered by job.\n# @PRE: User has translate.metrics.view permission.\n# @POST: Returns metrics data.\n@router.get(\"/metrics\")\nasync def get_metrics(\n job_id: str | None = Query(None),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.metrics\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get translation metrics.\"\"\"\n logger.reason(f\"get_metrics — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n metrics_svc = TranslationMetrics(db)\n if job_id:\n return metrics_svc.get_job_metrics(job_id)\n return metrics_svc.get_all_metrics()\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_metrics\n\n\n# #region get_job_metrics [C:4] [TYPE Function]\n# @BRIEF Get aggregated metrics for a specific job.\n# @PRE User has translate.metrics.view permission.\n# @POST Returns metrics dict.\n# @COMPLEXITY 4\n\n@router.get(\"/jobs/{job_id}/metrics\")\nasync def get_job_metrics(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.metrics\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get aggregated metrics for a specific job.\"\"\"\n logger.reason(f\"get_job_metrics — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n metrics_svc = TranslationMetrics(db)\n return metrics_svc.get_job_metrics(job_id)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_job_metrics\n\n# #endregion TranslateMetricsRoutesModule\n" }, { "contract_id": "get_metrics", @@ -22918,9 +22666,10 @@ "file_path": "backend/src/api/routes/translate/_metrics_routes.py", "start_line": 20, "end_line": 40, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns metrics data.", "PRE": "User has translate.metrics.view permission.", "PURPOSE": "Get translation metrics, optionally filtered by job." @@ -22928,37 +22677,38 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region get_metrics [TYPE Function]\n# @BRIEF Get translation metrics, optionally filtered by job.\n# @PRE: User has translate.metrics.view permission.\n# @POST: Returns metrics data.\n@router.get(\"/metrics\")\nasync def get_metrics(\n job_id: str | None = Query(None),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.metrics\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get translation metrics.\"\"\"\n logger.reason(f\"get_metrics — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n metrics_svc = TranslationMetrics(db)\n if job_id:\n return metrics_svc.get_job_metrics(job_id)\n return metrics_svc.get_all_metrics()\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_metrics\n" + "body": "# #region get_metrics [C:4] [TYPE Function]\n# @BRIEF Get translation metrics, optionally filtered by job.\n# @PRE: User has translate.metrics.view permission.\n# @POST: Returns metrics data.\n@router.get(\"/metrics\")\nasync def get_metrics(\n job_id: str | None = Query(None),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.metrics\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get translation metrics.\"\"\"\n logger.reason(f\"get_metrics — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n metrics_svc = TranslationMetrics(db)\n if job_id:\n return metrics_svc.get_job_metrics(job_id)\n return metrics_svc.get_all_metrics()\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_metrics\n" }, { "contract_id": "get_job_metrics", "contract_type": "Function", "file_path": "backend/src/api/routes/translate/_metrics_routes.py", "start_line": 43, - "end_line": 61, - "tier": "TIER_1", - "complexity": 1, + "end_line": 63, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": "4", "POST": "Returns metrics dict.", "PRE": "User has translate.metrics.view permission.", "PURPOSE": "Get aggregated metrics for a specific job." @@ -22966,34 +22716,34 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region get_job_metrics [TYPE Function]\n# @BRIEF Get aggregated metrics for a specific job.\n# @PRE: User has translate.metrics.view permission.\n# @POST: Returns metrics dict.\n@router.get(\"/jobs/{job_id}/metrics\")\nasync def get_job_metrics(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.metrics\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get aggregated metrics for a specific job.\"\"\"\n logger.reason(f\"get_job_metrics — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n metrics_svc = TranslationMetrics(db)\n return metrics_svc.get_job_metrics(job_id)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_job_metrics\n" + "body": "# #region get_job_metrics [C:4] [TYPE Function]\n# @BRIEF Get aggregated metrics for a specific job.\n# @PRE User has translate.metrics.view permission.\n# @POST Returns metrics dict.\n# @COMPLEXITY 4\n\n@router.get(\"/jobs/{job_id}/metrics\")\nasync def get_job_metrics(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.metrics\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get aggregated metrics for a specific job.\"\"\"\n logger.reason(f\"get_job_metrics — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n metrics_svc = TranslationMetrics(db)\n return metrics_svc.get_job_metrics(job_id)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_job_metrics\n" }, { "contract_id": "TranslatePreviewRoutesModule", "contract_type": "Module", "file_path": "backend/src/api/routes/translate/_preview_routes.py", "start_line": 1, - "end_line": 192, + "end_line": 194, "tier": "TIER_2", "complexity": 3, "metadata": { @@ -23015,7 +22765,7 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslatePreviewRoutesModule [C:3] [TYPE Module] [SEMANTICS fastapi, translate, preview, review, api, search]\n# @BRIEF Translation Preview session management routes.\n# @LAYER: API\n\n\nfrom fastapi import Depends, HTTPException, status\nfrom sqlalchemy.orm import Session\n\nfrom ....core.config_manager import ConfigManager\nfrom ....core.database import get_db\nfrom ....core.logger import logger\nfrom ....dependencies import get_config_manager, get_current_user, has_permission\nfrom ....plugins.translate.preview import TranslationPreview\nfrom ....schemas.auth import User\nfrom ....schemas.translate import (\n PreviewRequest,\n PreviewRow,\n PreviewRowUpdate,\n)\nfrom ._router import router\n\n# ============================================================\n# Preview\n# ============================================================\n\n# #region preview_translation [TYPE Function]\n# @BRIEF Preview a translation before applying it.\n# @PRE: User has translate.job.execute permission.\n# @POST: Returns a preview session with records and cost estimation.\n# @SIDE_EFFECT: Fetches sample data from Superset; calls LLM provider; creates DB rows.\n@router.post(\"/jobs/{job_id}/preview\", status_code=status.HTTP_201_CREATED)\nasync def preview_translation(\n job_id: str,\n payload: PreviewRequest = None,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Preview a translation before applying it.\"\"\"\n logger.reason(f\"preview_translation — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n if payload is None:\n payload = PreviewRequest()\n try:\n preview_service = TranslationPreview(db, config_manager, current_user.username)\n result = preview_service.preview_rows(\n job_id=job_id,\n sample_size=payload.sample_size,\n prompt_template=payload.prompt_template,\n env_id=payload.env_id,\n )\n return result\n except ValueError as e:\n logger.explore(\"preview_translation validation failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"preview_translation failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=f\"Preview failed: {e}\")\n# #endregion preview_translation\n\n\n# #region update_preview_row [TYPE Function]\n# @BRIEF Approve, edit, or reject a preview row (optionally per language).\n# @PRE: User has translate.job.execute permission.\n# @POST: Preview row status is updated.\n@router.put(\"/jobs/{job_id}/preview/rows/{row_key}\")\nasync def update_preview_row(\n job_id: str,\n row_key: str,\n payload: PreviewRowUpdate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Approve, edit, or reject a preview row (optionally per language).\"\"\"\n logger.reason(f\"update_preview_row — Job: {job_id}, Row: {row_key}, Action: {payload.action}, Lang: {payload.language_code}\", extra={\"src\": \"translate_routes\"})\n try:\n preview_service = TranslationPreview(db, config_manager, current_user.username)\n result = preview_service.update_preview_row(\n job_id=job_id,\n row_id=row_key,\n action=payload.action,\n translation=payload.translation,\n feedback=payload.feedback,\n language_code=payload.language_code,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion update_preview_row\n\n\n# #region accept_preview_session [TYPE Function]\n# @BRIEF Accept a preview session, marking it as the quality gate for full execution.\n# @PRE: User has translate.job.execute permission. Job has an ACTIVE preview session.\n# @POST: Preview session is marked as APPLIED; full execution can proceed.\n@router.post(\"/jobs/{job_id}/preview/accept\")\nasync def accept_preview_session(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Accept a preview session, enabling full translation execution.\"\"\"\n logger.reason(f\"accept_preview_session — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n preview_service = TranslationPreview(db, config_manager, current_user.username)\n result = preview_service.accept_preview_session(job_id=job_id)\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion accept_preview_session\n\n\n# #region apply_preview [TYPE Function]\n# @BRIEF Apply a preview session (alias for accept when accepting at session level).\n# @PRE: User has translate.job.execute permission.\n# @POST: Preview is applied.\n@router.post(\"/preview/{session_id}/apply\")\nasync def apply_preview(\n session_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Apply a preview session by session ID.\"\"\"\n logger.reason(f\"apply_preview — Session: {session_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n # Find job_id from session\n from ....models.translate import TranslationPreviewSession\n session = db.query(TranslationPreviewSession).filter(TranslationPreviewSession.id == session_id).first()\n if not session:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f\"Preview session '{session_id}' not found\")\n try:\n preview_service = TranslationPreview(db, config_manager, current_user.username)\n result = preview_service.accept_preview_session(job_id=session.job_id)\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion apply_preview\n\n\n# ============================================================\n# Preview Records\n# ============================================================\n\n# #region get_preview_records [TYPE Function]\n# @BRIEF Get records for a preview session.\n# @PRE: User has translate.job.view permission.\n# @POST: Returns list of preview records.\n@router.get(\"/preview/{session_id}/records\", response_model=list[PreviewRow])\nasync def get_preview_records(\n session_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get records for a preview session.\"\"\"\n logger.reason(f\"get_preview_records — Session: {session_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n from ....models.translate import TranslationPreviewRecord, TranslationPreviewSession\n session = db.query(TranslationPreviewSession).filter(TranslationPreviewSession.id == session_id).first()\n if not session:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f\"Preview session '{session_id}' not found\")\n records = (\n db.query(TranslationPreviewRecord)\n .filter(TranslationPreviewRecord.session_id == session_id)\n .all()\n )\n return [\n PreviewRow(\n id=r.id,\n source_sql=r.source_sql,\n target_sql=r.target_sql,\n source_object_type=r.source_object_type,\n source_object_id=r.source_object_id,\n source_object_name=r.source_object_name,\n status=r.status,\n feedback=r.feedback,\n )\n for r in records\n ]\n except HTTPException:\n raise\n except Exception as e:\n logger.explore(\"get_preview_records failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion get_preview_records\n\n# #endregion TranslatePreviewRoutesModule\n" + "body": "# #region TranslatePreviewRoutesModule [C:3] [TYPE Module] [SEMANTICS fastapi, translate, preview, review, api, search]\n# @BRIEF Translation Preview session management routes.\n# @LAYER: API\n\n\nfrom fastapi import Depends, HTTPException, status\nfrom sqlalchemy.orm import Session\n\nfrom ....core.config_manager import ConfigManager\nfrom ....core.database import get_db\nfrom ....core.logger import logger\nfrom ....dependencies import get_config_manager, get_current_user, has_permission\nfrom ....plugins.translate.preview import TranslationPreview\nfrom ....schemas.auth import User\nfrom ....schemas.translate import (\n PreviewRequest,\n PreviewRow,\n PreviewRowUpdate,\n)\nfrom ._router import router\n\n# ============================================================\n# Preview\n# ============================================================\n\n# #region preview_translation [C:4] [TYPE Function]\n# @BRIEF Preview a translation before applying it.\n# @PRE: User has translate.job.execute permission.\n# @POST: Returns a preview session with records and cost estimation.\n# @SIDE_EFFECT: Fetches sample data from Superset; calls LLM provider; creates DB rows.\n@router.post(\"/jobs/{job_id}/preview\", status_code=status.HTTP_201_CREATED)\nasync def preview_translation(\n job_id: str,\n payload: PreviewRequest = None,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Preview a translation before applying it.\"\"\"\n logger.reason(f\"preview_translation — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n if payload is None:\n payload = PreviewRequest()\n try:\n preview_service = TranslationPreview(db, config_manager, current_user.username)\n result = preview_service.preview_rows(\n job_id=job_id,\n sample_size=payload.sample_size,\n prompt_template=payload.prompt_template,\n env_id=payload.env_id,\n )\n return result\n except ValueError as e:\n logger.explore(\"preview_translation validation failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"preview_translation failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=f\"Preview failed: {e}\")\n# #endregion preview_translation\n\n\n# #region update_preview_row [C:4] [TYPE Function]\n# @BRIEF Approve, edit, or reject a preview row (optionally per language).\n# @PRE: User has translate.job.execute permission.\n# @POST: Preview row status is updated.\n@router.put(\"/jobs/{job_id}/preview/rows/{row_key}\")\nasync def update_preview_row(\n job_id: str,\n row_key: str,\n payload: PreviewRowUpdate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Approve, edit, or reject a preview row (optionally per language).\"\"\"\n logger.reason(f\"update_preview_row — Job: {job_id}, Row: {row_key}, Action: {payload.action}, Lang: {payload.language_code}\", extra={\"src\": \"translate_routes\"})\n try:\n preview_service = TranslationPreview(db, config_manager, current_user.username)\n result = preview_service.update_preview_row(\n job_id=job_id,\n row_id=row_key,\n action=payload.action,\n translation=payload.translation,\n feedback=payload.feedback,\n language_code=payload.language_code,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion update_preview_row\n\n\n# #region accept_preview_session [C:4] [TYPE Function]\n# @BRIEF Accept a preview session, marking it as the quality gate for full execution.\n# @PRE: User has translate.job.execute permission. Job has an ACTIVE preview session.\n# @POST: Preview session is marked as APPLIED; full execution can proceed.\n@router.post(\"/jobs/{job_id}/preview/accept\")\nasync def accept_preview_session(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Accept a preview session, enabling full translation execution.\"\"\"\n logger.reason(f\"accept_preview_session — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n preview_service = TranslationPreview(db, config_manager, current_user.username)\n result = preview_service.accept_preview_session(job_id=job_id)\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion accept_preview_session\n\n\n# #region apply_preview [C:4] [TYPE Function]\n# @BRIEF Apply a preview session (alias for accept when accepting at session level).\n# @PRE: User has translate.job.execute permission.\n# @POST: Preview is applied.\n@router.post(\"/preview/{session_id}/apply\")\nasync def apply_preview(\n session_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Apply a preview session by session ID.\"\"\"\n logger.reason(f\"apply_preview — Session: {session_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n # Find job_id from session\n from ....models.translate import TranslationPreviewSession\n session = db.query(TranslationPreviewSession).filter(TranslationPreviewSession.id == session_id).first()\n if not session:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f\"Preview session '{session_id}' not found\")\n try:\n preview_service = TranslationPreview(db, config_manager, current_user.username)\n result = preview_service.accept_preview_session(job_id=session.job_id)\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion apply_preview\n\n\n# ============================================================\n# Preview Records\n# ============================================================\n\n# #region get_preview_records [C:4] [TYPE Function]\n# @BRIEF Get records for a preview session.\n# @PRE User has translate.job.view permission.\n# @POST Returns list of preview records.\n# @COMPLEXITY 4\n\n@router.get(\"/preview/{session_id}/records\", response_model=list[PreviewRow])\nasync def get_preview_records(\n session_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get records for a preview session.\"\"\"\n logger.reason(f\"get_preview_records — Session: {session_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n from ....models.translate import TranslationPreviewRecord, TranslationPreviewSession\n session = db.query(TranslationPreviewSession).filter(TranslationPreviewSession.id == session_id).first()\n if not session:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f\"Preview session '{session_id}' not found\")\n records = (\n db.query(TranslationPreviewRecord)\n .filter(TranslationPreviewRecord.session_id == session_id)\n .all()\n )\n return [\n PreviewRow(\n id=r.id,\n source_sql=r.source_sql,\n target_sql=r.target_sql,\n source_object_type=r.source_object_type,\n source_object_id=r.source_object_id,\n source_object_name=r.source_object_name,\n status=r.status,\n feedback=r.feedback,\n )\n for r in records\n ]\n except HTTPException:\n raise\n except Exception as e:\n logger.explore(\"get_preview_records failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion get_preview_records\n\n# #endregion TranslatePreviewRoutesModule\n" }, { "contract_id": "preview_translation", @@ -23023,9 +22773,10 @@ "file_path": "backend/src/api/routes/translate/_preview_routes.py", "start_line": 26, "end_line": 59, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns a preview session with records and cost estimation.", "PRE": "User has translate.job.execute permission.", "PURPOSE": "Preview a translation before applying it.", @@ -23034,36 +22785,18 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "SIDE_EFFECT", - "message": "@SIDE_EFFECT is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region preview_translation [TYPE Function]\n# @BRIEF Preview a translation before applying it.\n# @PRE: User has translate.job.execute permission.\n# @POST: Returns a preview session with records and cost estimation.\n# @SIDE_EFFECT: Fetches sample data from Superset; calls LLM provider; creates DB rows.\n@router.post(\"/jobs/{job_id}/preview\", status_code=status.HTTP_201_CREATED)\nasync def preview_translation(\n job_id: str,\n payload: PreviewRequest = None,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Preview a translation before applying it.\"\"\"\n logger.reason(f\"preview_translation — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n if payload is None:\n payload = PreviewRequest()\n try:\n preview_service = TranslationPreview(db, config_manager, current_user.username)\n result = preview_service.preview_rows(\n job_id=job_id,\n sample_size=payload.sample_size,\n prompt_template=payload.prompt_template,\n env_id=payload.env_id,\n )\n return result\n except ValueError as e:\n logger.explore(\"preview_translation validation failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"preview_translation failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=f\"Preview failed: {e}\")\n# #endregion preview_translation\n" + "body": "# #region preview_translation [C:4] [TYPE Function]\n# @BRIEF Preview a translation before applying it.\n# @PRE: User has translate.job.execute permission.\n# @POST: Returns a preview session with records and cost estimation.\n# @SIDE_EFFECT: Fetches sample data from Superset; calls LLM provider; creates DB rows.\n@router.post(\"/jobs/{job_id}/preview\", status_code=status.HTTP_201_CREATED)\nasync def preview_translation(\n job_id: str,\n payload: PreviewRequest = None,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Preview a translation before applying it.\"\"\"\n logger.reason(f\"preview_translation — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n if payload is None:\n payload = PreviewRequest()\n try:\n preview_service = TranslationPreview(db, config_manager, current_user.username)\n result = preview_service.preview_rows(\n job_id=job_id,\n sample_size=payload.sample_size,\n prompt_template=payload.prompt_template,\n env_id=payload.env_id,\n )\n return result\n except ValueError as e:\n logger.explore(\"preview_translation validation failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"preview_translation failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=f\"Preview failed: {e}\")\n# #endregion preview_translation\n" }, { "contract_id": "update_preview_row", @@ -23071,9 +22804,10 @@ "file_path": "backend/src/api/routes/translate/_preview_routes.py", "start_line": 62, "end_line": 91, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Preview row status is updated.", "PRE": "User has translate.job.execute permission.", "PURPOSE": "Approve, edit, or reject a preview row (optionally per language)." @@ -23081,27 +22815,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region update_preview_row [TYPE Function]\n# @BRIEF Approve, edit, or reject a preview row (optionally per language).\n# @PRE: User has translate.job.execute permission.\n# @POST: Preview row status is updated.\n@router.put(\"/jobs/{job_id}/preview/rows/{row_key}\")\nasync def update_preview_row(\n job_id: str,\n row_key: str,\n payload: PreviewRowUpdate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Approve, edit, or reject a preview row (optionally per language).\"\"\"\n logger.reason(f\"update_preview_row — Job: {job_id}, Row: {row_key}, Action: {payload.action}, Lang: {payload.language_code}\", extra={\"src\": \"translate_routes\"})\n try:\n preview_service = TranslationPreview(db, config_manager, current_user.username)\n result = preview_service.update_preview_row(\n job_id=job_id,\n row_id=row_key,\n action=payload.action,\n translation=payload.translation,\n feedback=payload.feedback,\n language_code=payload.language_code,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion update_preview_row\n" + "body": "# #region update_preview_row [C:4] [TYPE Function]\n# @BRIEF Approve, edit, or reject a preview row (optionally per language).\n# @PRE: User has translate.job.execute permission.\n# @POST: Preview row status is updated.\n@router.put(\"/jobs/{job_id}/preview/rows/{row_key}\")\nasync def update_preview_row(\n job_id: str,\n row_key: str,\n payload: PreviewRowUpdate,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Approve, edit, or reject a preview row (optionally per language).\"\"\"\n logger.reason(f\"update_preview_row — Job: {job_id}, Row: {row_key}, Action: {payload.action}, Lang: {payload.language_code}\", extra={\"src\": \"translate_routes\"})\n try:\n preview_service = TranslationPreview(db, config_manager, current_user.username)\n result = preview_service.update_preview_row(\n job_id=job_id,\n row_id=row_key,\n action=payload.action,\n translation=payload.translation,\n feedback=payload.feedback,\n language_code=payload.language_code,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion update_preview_row\n" }, { "contract_id": "accept_preview_session", @@ -23109,9 +22843,10 @@ "file_path": "backend/src/api/routes/translate/_preview_routes.py", "start_line": 94, "end_line": 114, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Preview session is marked as APPLIED; full execution can proceed.", "PRE": "User has translate.job.execute permission. Job has an ACTIVE preview session.", "PURPOSE": "Accept a preview session, marking it as the quality gate for full execution." @@ -23119,27 +22854,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region accept_preview_session [TYPE Function]\n# @BRIEF Accept a preview session, marking it as the quality gate for full execution.\n# @PRE: User has translate.job.execute permission. Job has an ACTIVE preview session.\n# @POST: Preview session is marked as APPLIED; full execution can proceed.\n@router.post(\"/jobs/{job_id}/preview/accept\")\nasync def accept_preview_session(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Accept a preview session, enabling full translation execution.\"\"\"\n logger.reason(f\"accept_preview_session — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n preview_service = TranslationPreview(db, config_manager, current_user.username)\n result = preview_service.accept_preview_session(job_id=job_id)\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion accept_preview_session\n" + "body": "# #region accept_preview_session [C:4] [TYPE Function]\n# @BRIEF Accept a preview session, marking it as the quality gate for full execution.\n# @PRE: User has translate.job.execute permission. Job has an ACTIVE preview session.\n# @POST: Preview session is marked as APPLIED; full execution can proceed.\n@router.post(\"/jobs/{job_id}/preview/accept\")\nasync def accept_preview_session(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Accept a preview session, enabling full translation execution.\"\"\"\n logger.reason(f\"accept_preview_session — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n preview_service = TranslationPreview(db, config_manager, current_user.username)\n result = preview_service.accept_preview_session(job_id=job_id)\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion accept_preview_session\n" }, { "contract_id": "apply_preview", @@ -23147,9 +22882,10 @@ "file_path": "backend/src/api/routes/translate/_preview_routes.py", "start_line": 117, "end_line": 142, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Preview is applied.", "PRE": "User has translate.job.execute permission.", "PURPOSE": "Apply a preview session (alias for accept when accepting at session level)." @@ -23157,37 +22893,38 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region apply_preview [TYPE Function]\n# @BRIEF Apply a preview session (alias for accept when accepting at session level).\n# @PRE: User has translate.job.execute permission.\n# @POST: Preview is applied.\n@router.post(\"/preview/{session_id}/apply\")\nasync def apply_preview(\n session_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Apply a preview session by session ID.\"\"\"\n logger.reason(f\"apply_preview — Session: {session_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n # Find job_id from session\n from ....models.translate import TranslationPreviewSession\n session = db.query(TranslationPreviewSession).filter(TranslationPreviewSession.id == session_id).first()\n if not session:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f\"Preview session '{session_id}' not found\")\n try:\n preview_service = TranslationPreview(db, config_manager, current_user.username)\n result = preview_service.accept_preview_session(job_id=session.job_id)\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion apply_preview\n" + "body": "# #region apply_preview [C:4] [TYPE Function]\n# @BRIEF Apply a preview session (alias for accept when accepting at session level).\n# @PRE: User has translate.job.execute permission.\n# @POST: Preview is applied.\n@router.post(\"/preview/{session_id}/apply\")\nasync def apply_preview(\n session_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Apply a preview session by session ID.\"\"\"\n logger.reason(f\"apply_preview — Session: {session_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n # Find job_id from session\n from ....models.translate import TranslationPreviewSession\n session = db.query(TranslationPreviewSession).filter(TranslationPreviewSession.id == session_id).first()\n if not session:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f\"Preview session '{session_id}' not found\")\n try:\n preview_service = TranslationPreview(db, config_manager, current_user.username)\n result = preview_service.accept_preview_session(job_id=session.job_id)\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion apply_preview\n" }, { "contract_id": "get_preview_records", "contract_type": "Function", "file_path": "backend/src/api/routes/translate/_preview_routes.py", "start_line": 149, - "end_line": 190, - "tier": "TIER_1", - "complexity": 1, + "end_line": 192, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": "4", "POST": "Returns list of preview records.", "PRE": "User has translate.job.view permission.", "PURPOSE": "Get records for a preview session." @@ -23195,34 +22932,34 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region get_preview_records [TYPE Function]\n# @BRIEF Get records for a preview session.\n# @PRE: User has translate.job.view permission.\n# @POST: Returns list of preview records.\n@router.get(\"/preview/{session_id}/records\", response_model=list[PreviewRow])\nasync def get_preview_records(\n session_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get records for a preview session.\"\"\"\n logger.reason(f\"get_preview_records — Session: {session_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n from ....models.translate import TranslationPreviewRecord, TranslationPreviewSession\n session = db.query(TranslationPreviewSession).filter(TranslationPreviewSession.id == session_id).first()\n if not session:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f\"Preview session '{session_id}' not found\")\n records = (\n db.query(TranslationPreviewRecord)\n .filter(TranslationPreviewRecord.session_id == session_id)\n .all()\n )\n return [\n PreviewRow(\n id=r.id,\n source_sql=r.source_sql,\n target_sql=r.target_sql,\n source_object_type=r.source_object_type,\n source_object_id=r.source_object_id,\n source_object_name=r.source_object_name,\n status=r.status,\n feedback=r.feedback,\n )\n for r in records\n ]\n except HTTPException:\n raise\n except Exception as e:\n logger.explore(\"get_preview_records failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion get_preview_records\n" + "body": "# #region get_preview_records [C:4] [TYPE Function]\n# @BRIEF Get records for a preview session.\n# @PRE User has translate.job.view permission.\n# @POST Returns list of preview records.\n# @COMPLEXITY 4\n\n@router.get(\"/preview/{session_id}/records\", response_model=list[PreviewRow])\nasync def get_preview_records(\n session_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get records for a preview session.\"\"\"\n logger.reason(f\"get_preview_records — Session: {session_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n from ....models.translate import TranslationPreviewRecord, TranslationPreviewSession\n session = db.query(TranslationPreviewSession).filter(TranslationPreviewSession.id == session_id).first()\n if not session:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f\"Preview session '{session_id}' not found\")\n records = (\n db.query(TranslationPreviewRecord)\n .filter(TranslationPreviewRecord.session_id == session_id)\n .all()\n )\n return [\n PreviewRow(\n id=r.id,\n source_sql=r.source_sql,\n target_sql=r.target_sql,\n source_object_type=r.source_object_type,\n source_object_id=r.source_object_id,\n source_object_name=r.source_object_name,\n status=r.status,\n feedback=r.feedback,\n )\n for r in records\n ]\n except HTTPException:\n raise\n except Exception as e:\n logger.explore(\"get_preview_records failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion get_preview_records\n" }, { "contract_id": "TranslateRouterModule", "contract_type": "Module", "file_path": "backend/src/api/routes/translate/_router.py", "start_line": 1, - "end_line": 12, + "end_line": 13, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -23234,14 +22971,14 @@ "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslateRouterModule [C:1] [TYPE Module] [SEMANTICS fastapi, translate, api]\n# @BRIEF APIRouter instance for translate routes.\n# @LAYER: API\n\nfrom fastapi import APIRouter\n\n# #region translate_router [TYPE Global]\n# @BRIEF APIRouter instance for all translate sub-routes.\nrouter = APIRouter(prefix=\"/api/translate\", tags=[\"translate\"])\n# #endregion translate_router\n\n# #endregion TranslateRouterModule\n" + "body": "# #region TranslateRouterModule [C:1] [TYPE Module] [SEMANTICS fastapi, translate, api]\n# @BRIEF APIRouter instance for translate routes.\n# @LAYER: API\n\nfrom fastapi import APIRouter\n\n# #region translate_router [TYPE Global]\n# @BRIEF APIRouter instance for all translate sub-routes.\n\nrouter = APIRouter(prefix=\"/api/translate\", tags=[\"translate\"])\n# #endregion translate_router\n\n# #endregion TranslateRouterModule\n" }, { "contract_id": "translate_router", "contract_type": "Global", "file_path": "backend/src/api/routes/translate/_router.py", "start_line": 7, - "end_line": 10, + "end_line": 11, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -23279,14 +23016,14 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region translate_router [TYPE Global]\n# @BRIEF APIRouter instance for all translate sub-routes.\nrouter = APIRouter(prefix=\"/api/translate\", tags=[\"translate\"])\n# #endregion translate_router\n" + "body": "# #region translate_router [TYPE Global]\n# @BRIEF APIRouter instance for all translate sub-routes.\n\nrouter = APIRouter(prefix=\"/api/translate\", tags=[\"translate\"])\n# #endregion translate_router\n" }, { "contract_id": "TranslateRunListRoutesModule", "contract_type": "Module", "file_path": "backend/src/api/routes/translate/_run_list_routes.py", "start_line": 1, - "end_line": 223, + "end_line": 225, "tier": "TIER_2", "complexity": 3, "metadata": { @@ -23308,7 +23045,7 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslateRunListRoutesModule [C:3] [TYPE Module] [SEMANTICS fastapi, translate, api, download, search]\n# @BRIEF Translation Run listing, detail, and CSV download routes (cross-job).\n# @LAYER: API\n\n\nfrom fastapi import Depends, HTTPException, Query, status\nfrom sqlalchemy.orm import Session\n\nfrom ....core.config_manager import ConfigManager\nfrom ....core.database import get_db\nfrom ....core.logger import logger\nfrom ....dependencies import get_config_manager, get_current_user, has_permission\nfrom ....plugins.translate.events import TranslationEventLog\nfrom ....plugins.translate.orchestrator import TranslationOrchestrator\nfrom ....schemas.auth import User\nfrom ._router import router\n\n# ============================================================\n# List Runs (cross-job)\n# ============================================================\n\n# #region list_runs [TYPE Function]\n# @BRIEF List all runs with cross-job filtering and pagination.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns paginated list of runs.\n@router.get(\"/runs\")\nasync def list_runs(\n job_id: str | None = Query(None),\n run_status: str | None = Query(None),\n trigger_type: str | None = Query(None),\n created_by: str | None = Query(None),\n date_from: str | None = Query(None),\n date_to: str | None = Query(None),\n page: int = Query(1, ge=1),\n page_size: int = Query(20, ge=1, le=100),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"List all runs with cross-job filtering and pagination.\"\"\"\n logger.reason(f\"list_runs — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n from ....models.translate import TranslationRun\n query = db.query(TranslationRun)\n\n if job_id:\n query = query.filter(TranslationRun.job_id == job_id)\n if run_status:\n query = query.filter(TranslationRun.status == run_status)\n if trigger_type:\n query = query.filter(TranslationRun.trigger_type == trigger_type)\n if created_by:\n query = query.filter(TranslationRun.created_by == created_by)\n if date_from:\n try:\n from datetime import datetime\n dt_from = datetime.fromisoformat(date_from)\n query = query.filter(TranslationRun.created_at >= dt_from)\n except ValueError:\n pass\n if date_to:\n try:\n from datetime import datetime\n dt_to = datetime.fromisoformat(date_to)\n query = query.filter(TranslationRun.created_at <= dt_to)\n except ValueError:\n pass\n\n total = query.count()\n runs = (\n query.order_by(TranslationRun.created_at.desc())\n .offset((page - 1) * page_size)\n .limit(page_size)\n .all()\n )\n\n items = []\n for r in runs:\n # Gather per-language statistics from the run's language_stats relationship\n lang_stats = r.language_stats or []\n target_languages = [ls.language_code for ls in lang_stats]\n total_translated = sum((ls.translated_rows or 0) for ls in lang_stats)\n language_stats = {\n ls.language_code: {\n \"total_rows\": ls.total_rows or 0,\n \"translated_rows\": ls.translated_rows or 0,\n \"failed_rows\": ls.failed_rows or 0,\n \"skipped_rows\": ls.skipped_rows or 0,\n \"token_count\": ls.token_count or 0,\n \"estimated_cost\": ls.estimated_cost or 0.0,\n }\n for ls in lang_stats\n }\n\n items.append({\n \"id\": r.id,\n \"job_id\": r.job_id,\n \"status\": r.status,\n \"trigger_type\": r.trigger_type,\n \"started_at\": r.started_at.isoformat() if r.started_at else None,\n \"completed_at\": r.completed_at.isoformat() if r.completed_at else None,\n \"error_message\": r.error_message,\n \"total_records\": r.total_records or 0,\n \"successful_records\": r.successful_records or 0,\n \"failed_records\": r.failed_records or 0,\n \"skipped_records\": r.skipped_records or 0,\n \"insert_status\": r.insert_status,\n \"superset_execution_id\": r.superset_execution_id,\n \"config_hash\": r.config_hash,\n \"dict_snapshot_hash\": r.dict_snapshot_hash,\n \"created_by\": r.created_by,\n \"created_at\": r.created_at.isoformat() if r.created_at else None,\n \"target_languages\": target_languages,\n \"total_translated\": total_translated,\n \"language_stats\": language_stats,\n })\n\n return {\"items\": items, \"total\": total, \"page\": page, \"page_size\": page_size}\n except Exception as e:\n logger.explore(\"list_runs failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion list_runs\n\n\n# ============================================================\n# Run Detail\n# ============================================================\n\n# #region get_run_detail [TYPE Function]\n# @BRIEF Get detailed run info with config_snapshot, records, events.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns run detail with records and events.\n@router.get(\"/runs/{run_id}/detail\")\nasync def get_run_detail(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get detailed run info with config_snapshot, records, events.\"\"\"\n logger.reason(f\"get_run_detail — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n status_info = orch.get_run_status(run_id)\n records = orch.get_run_records(run_id, page=1, page_size=50)\n events = TranslationEventLog(db).query_events(run_id=run_id)\n event_summary = TranslationEventLog(db).get_run_event_summary(run_id)\n\n # Get config snapshot from run\n from ....models.translate import TranslationRun\n run = db.query(TranslationRun).filter(TranslationRun.id == run_id).first()\n config_snapshot = run.config_snapshot if run else None\n\n return {\n **status_info,\n \"config_snapshot\": config_snapshot,\n \"config_hash\": run.config_hash if run else None,\n \"records\": records,\n \"events\": events,\n \"event_invariants\": event_summary,\n }\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_run_detail\n\n\n# ============================================================\n# Download Skipped CSV\n# ============================================================\n\n# #region download_skipped_csv [TYPE Function]\n# @BRIEF Download a CSV of skipped translation records from a run.\n# @PRE: User has translate.job.view permission.\n# @POST: Returns CSV file of skipped records.\n@router.get(\"/runs/{run_id}/skipped.csv\")\nasync def download_skipped_csv(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Download skipped translation records as CSV.\"\"\"\n logger.reason(f\"download_skipped_csv — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n import csv\n import io\n\n from fastapi.responses import StreamingResponse\n\n from ....models.translate import TranslationRecord\n\n records = (\n db.query(TranslationRecord)\n .filter(\n TranslationRecord.run_id == run_id,\n TranslationRecord.status == \"SKIPPED\",\n )\n .all()\n )\n\n output = io.StringIO()\n writer = csv.writer(output)\n writer.writerow([\"id\", \"source_sql\", \"target_sql\", \"source_object_type\",\n \"source_object_id\", \"source_object_name\", \"error_message\"])\n for rec in records:\n writer.writerow([\n rec.id, rec.source_sql, rec.target_sql, rec.source_object_type,\n rec.source_object_id, rec.source_object_name, rec.error_message,\n ])\n\n output.seek(0)\n return StreamingResponse(\n iter([output.getvalue()]),\n media_type=\"text/csv\",\n headers={\"Content-Disposition\": f\"attachment; filename=skipped_{run_id}.csv\"},\n )\n except Exception as e:\n logger.explore(\"download_skipped_csv failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion download_skipped_csv\n\n# #endregion TranslateRunListRoutesModule\n" + "body": "# #region TranslateRunListRoutesModule [C:3] [TYPE Module] [SEMANTICS fastapi, translate, api, download, search]\n# @BRIEF Translation Run listing, detail, and CSV download routes (cross-job).\n# @LAYER: API\n\n\nfrom fastapi import Depends, HTTPException, Query, status\nfrom sqlalchemy.orm import Session\n\nfrom ....core.config_manager import ConfigManager\nfrom ....core.database import get_db\nfrom ....core.logger import logger\nfrom ....dependencies import get_config_manager, get_current_user, has_permission\nfrom ....plugins.translate.events import TranslationEventLog\nfrom ....plugins.translate.orchestrator import TranslationOrchestrator\nfrom ....schemas.auth import User\nfrom ._router import router\n\n# ============================================================\n# List Runs (cross-job)\n# ============================================================\n\n# #region list_runs [C:4] [TYPE Function]\n# @BRIEF List all runs with cross-job filtering and pagination.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns paginated list of runs.\n@router.get(\"/runs\")\nasync def list_runs(\n job_id: str | None = Query(None),\n run_status: str | None = Query(None),\n trigger_type: str | None = Query(None),\n created_by: str | None = Query(None),\n date_from: str | None = Query(None),\n date_to: str | None = Query(None),\n page: int = Query(1, ge=1),\n page_size: int = Query(20, ge=1, le=100),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"List all runs with cross-job filtering and pagination.\"\"\"\n logger.reason(f\"list_runs — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n from ....models.translate import TranslationRun\n query = db.query(TranslationRun)\n\n if job_id:\n query = query.filter(TranslationRun.job_id == job_id)\n if run_status:\n query = query.filter(TranslationRun.status == run_status)\n if trigger_type:\n query = query.filter(TranslationRun.trigger_type == trigger_type)\n if created_by:\n query = query.filter(TranslationRun.created_by == created_by)\n if date_from:\n try:\n from datetime import datetime\n dt_from = datetime.fromisoformat(date_from)\n query = query.filter(TranslationRun.created_at >= dt_from)\n except ValueError:\n pass\n if date_to:\n try:\n from datetime import datetime\n dt_to = datetime.fromisoformat(date_to)\n query = query.filter(TranslationRun.created_at <= dt_to)\n except ValueError:\n pass\n\n total = query.count()\n runs = (\n query.order_by(TranslationRun.created_at.desc())\n .offset((page - 1) * page_size)\n .limit(page_size)\n .all()\n )\n\n items = []\n for r in runs:\n # Gather per-language statistics from the run's language_stats relationship\n lang_stats = r.language_stats or []\n target_languages = [ls.language_code for ls in lang_stats]\n total_translated = sum((ls.translated_rows or 0) for ls in lang_stats)\n language_stats = {\n ls.language_code: {\n \"total_rows\": ls.total_rows or 0,\n \"translated_rows\": ls.translated_rows or 0,\n \"failed_rows\": ls.failed_rows or 0,\n \"skipped_rows\": ls.skipped_rows or 0,\n \"token_count\": ls.token_count or 0,\n \"estimated_cost\": ls.estimated_cost or 0.0,\n }\n for ls in lang_stats\n }\n\n items.append({\n \"id\": r.id,\n \"job_id\": r.job_id,\n \"status\": r.status,\n \"trigger_type\": r.trigger_type,\n \"started_at\": r.started_at.isoformat() if r.started_at else None,\n \"completed_at\": r.completed_at.isoformat() if r.completed_at else None,\n \"error_message\": r.error_message,\n \"total_records\": r.total_records or 0,\n \"successful_records\": r.successful_records or 0,\n \"failed_records\": r.failed_records or 0,\n \"skipped_records\": r.skipped_records or 0,\n \"insert_status\": r.insert_status,\n \"superset_execution_id\": r.superset_execution_id,\n \"config_hash\": r.config_hash,\n \"dict_snapshot_hash\": r.dict_snapshot_hash,\n \"created_by\": r.created_by,\n \"created_at\": r.created_at.isoformat() if r.created_at else None,\n \"target_languages\": target_languages,\n \"total_translated\": total_translated,\n \"language_stats\": language_stats,\n })\n\n return {\"items\": items, \"total\": total, \"page\": page, \"page_size\": page_size}\n except Exception as e:\n logger.explore(\"list_runs failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion list_runs\n\n\n# ============================================================\n# Run Detail\n# ============================================================\n\n# #region get_run_detail [C:4] [TYPE Function]\n# @BRIEF Get detailed run info with config_snapshot, records, events.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns run detail with records and events.\n@router.get(\"/runs/{run_id}/detail\")\nasync def get_run_detail(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get detailed run info with config_snapshot, records, events.\"\"\"\n logger.reason(f\"get_run_detail — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n status_info = orch.get_run_status(run_id)\n records = orch.get_run_records(run_id, page=1, page_size=50)\n events = TranslationEventLog(db).query_events(run_id=run_id)\n event_summary = TranslationEventLog(db).get_run_event_summary(run_id)\n\n # Get config snapshot from run\n from ....models.translate import TranslationRun\n run = db.query(TranslationRun).filter(TranslationRun.id == run_id).first()\n config_snapshot = run.config_snapshot if run else None\n\n return {\n **status_info,\n \"config_snapshot\": config_snapshot,\n \"config_hash\": run.config_hash if run else None,\n \"records\": records,\n \"events\": events,\n \"event_invariants\": event_summary,\n }\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_run_detail\n\n\n# ============================================================\n# Download Skipped CSV\n# ============================================================\n\n# #region download_skipped_csv [C:4] [TYPE Function]\n# @BRIEF Download a CSV of skipped translation records from a run.\n# @PRE User has translate.job.view permission.\n# @POST Returns CSV file of skipped records.\n# @COMPLEXITY 4\n\n@router.get(\"/runs/{run_id}/skipped.csv\")\nasync def download_skipped_csv(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Download skipped translation records as CSV.\"\"\"\n logger.reason(f\"download_skipped_csv — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n import csv\n import io\n\n from fastapi.responses import StreamingResponse\n\n from ....models.translate import TranslationRecord\n\n records = (\n db.query(TranslationRecord)\n .filter(\n TranslationRecord.run_id == run_id,\n TranslationRecord.status == \"SKIPPED\",\n )\n .all()\n )\n\n output = io.StringIO()\n writer = csv.writer(output)\n writer.writerow([\"id\", \"source_sql\", \"target_sql\", \"source_object_type\",\n \"source_object_id\", \"source_object_name\", \"error_message\"])\n for rec in records:\n writer.writerow([\n rec.id, rec.source_sql, rec.target_sql, rec.source_object_type,\n rec.source_object_id, rec.source_object_name, rec.error_message,\n ])\n\n output.seek(0)\n return StreamingResponse(\n iter([output.getvalue()]),\n media_type=\"text/csv\",\n headers={\"Content-Disposition\": f\"attachment; filename=skipped_{run_id}.csv\"},\n )\n except Exception as e:\n logger.explore(\"download_skipped_csv failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion download_skipped_csv\n\n# #endregion TranslateRunListRoutesModule\n" }, { "contract_id": "list_runs", @@ -23316,9 +23053,10 @@ "file_path": "backend/src/api/routes/translate/_run_list_routes.py", "start_line": 22, "end_line": 122, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns paginated list of runs.", "PRE": "User has translate.history.view permission.", "PURPOSE": "List all runs with cross-job filtering and pagination." @@ -23326,27 +23064,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region list_runs [TYPE Function]\n# @BRIEF List all runs with cross-job filtering and pagination.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns paginated list of runs.\n@router.get(\"/runs\")\nasync def list_runs(\n job_id: str | None = Query(None),\n run_status: str | None = Query(None),\n trigger_type: str | None = Query(None),\n created_by: str | None = Query(None),\n date_from: str | None = Query(None),\n date_to: str | None = Query(None),\n page: int = Query(1, ge=1),\n page_size: int = Query(20, ge=1, le=100),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"List all runs with cross-job filtering and pagination.\"\"\"\n logger.reason(f\"list_runs — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n from ....models.translate import TranslationRun\n query = db.query(TranslationRun)\n\n if job_id:\n query = query.filter(TranslationRun.job_id == job_id)\n if run_status:\n query = query.filter(TranslationRun.status == run_status)\n if trigger_type:\n query = query.filter(TranslationRun.trigger_type == trigger_type)\n if created_by:\n query = query.filter(TranslationRun.created_by == created_by)\n if date_from:\n try:\n from datetime import datetime\n dt_from = datetime.fromisoformat(date_from)\n query = query.filter(TranslationRun.created_at >= dt_from)\n except ValueError:\n pass\n if date_to:\n try:\n from datetime import datetime\n dt_to = datetime.fromisoformat(date_to)\n query = query.filter(TranslationRun.created_at <= dt_to)\n except ValueError:\n pass\n\n total = query.count()\n runs = (\n query.order_by(TranslationRun.created_at.desc())\n .offset((page - 1) * page_size)\n .limit(page_size)\n .all()\n )\n\n items = []\n for r in runs:\n # Gather per-language statistics from the run's language_stats relationship\n lang_stats = r.language_stats or []\n target_languages = [ls.language_code for ls in lang_stats]\n total_translated = sum((ls.translated_rows or 0) for ls in lang_stats)\n language_stats = {\n ls.language_code: {\n \"total_rows\": ls.total_rows or 0,\n \"translated_rows\": ls.translated_rows or 0,\n \"failed_rows\": ls.failed_rows or 0,\n \"skipped_rows\": ls.skipped_rows or 0,\n \"token_count\": ls.token_count or 0,\n \"estimated_cost\": ls.estimated_cost or 0.0,\n }\n for ls in lang_stats\n }\n\n items.append({\n \"id\": r.id,\n \"job_id\": r.job_id,\n \"status\": r.status,\n \"trigger_type\": r.trigger_type,\n \"started_at\": r.started_at.isoformat() if r.started_at else None,\n \"completed_at\": r.completed_at.isoformat() if r.completed_at else None,\n \"error_message\": r.error_message,\n \"total_records\": r.total_records or 0,\n \"successful_records\": r.successful_records or 0,\n \"failed_records\": r.failed_records or 0,\n \"skipped_records\": r.skipped_records or 0,\n \"insert_status\": r.insert_status,\n \"superset_execution_id\": r.superset_execution_id,\n \"config_hash\": r.config_hash,\n \"dict_snapshot_hash\": r.dict_snapshot_hash,\n \"created_by\": r.created_by,\n \"created_at\": r.created_at.isoformat() if r.created_at else None,\n \"target_languages\": target_languages,\n \"total_translated\": total_translated,\n \"language_stats\": language_stats,\n })\n\n return {\"items\": items, \"total\": total, \"page\": page, \"page_size\": page_size}\n except Exception as e:\n logger.explore(\"list_runs failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion list_runs\n" + "body": "# #region list_runs [C:4] [TYPE Function]\n# @BRIEF List all runs with cross-job filtering and pagination.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns paginated list of runs.\n@router.get(\"/runs\")\nasync def list_runs(\n job_id: str | None = Query(None),\n run_status: str | None = Query(None),\n trigger_type: str | None = Query(None),\n created_by: str | None = Query(None),\n date_from: str | None = Query(None),\n date_to: str | None = Query(None),\n page: int = Query(1, ge=1),\n page_size: int = Query(20, ge=1, le=100),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"List all runs with cross-job filtering and pagination.\"\"\"\n logger.reason(f\"list_runs — User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n from ....models.translate import TranslationRun\n query = db.query(TranslationRun)\n\n if job_id:\n query = query.filter(TranslationRun.job_id == job_id)\n if run_status:\n query = query.filter(TranslationRun.status == run_status)\n if trigger_type:\n query = query.filter(TranslationRun.trigger_type == trigger_type)\n if created_by:\n query = query.filter(TranslationRun.created_by == created_by)\n if date_from:\n try:\n from datetime import datetime\n dt_from = datetime.fromisoformat(date_from)\n query = query.filter(TranslationRun.created_at >= dt_from)\n except ValueError:\n pass\n if date_to:\n try:\n from datetime import datetime\n dt_to = datetime.fromisoformat(date_to)\n query = query.filter(TranslationRun.created_at <= dt_to)\n except ValueError:\n pass\n\n total = query.count()\n runs = (\n query.order_by(TranslationRun.created_at.desc())\n .offset((page - 1) * page_size)\n .limit(page_size)\n .all()\n )\n\n items = []\n for r in runs:\n # Gather per-language statistics from the run's language_stats relationship\n lang_stats = r.language_stats or []\n target_languages = [ls.language_code for ls in lang_stats]\n total_translated = sum((ls.translated_rows or 0) for ls in lang_stats)\n language_stats = {\n ls.language_code: {\n \"total_rows\": ls.total_rows or 0,\n \"translated_rows\": ls.translated_rows or 0,\n \"failed_rows\": ls.failed_rows or 0,\n \"skipped_rows\": ls.skipped_rows or 0,\n \"token_count\": ls.token_count or 0,\n \"estimated_cost\": ls.estimated_cost or 0.0,\n }\n for ls in lang_stats\n }\n\n items.append({\n \"id\": r.id,\n \"job_id\": r.job_id,\n \"status\": r.status,\n \"trigger_type\": r.trigger_type,\n \"started_at\": r.started_at.isoformat() if r.started_at else None,\n \"completed_at\": r.completed_at.isoformat() if r.completed_at else None,\n \"error_message\": r.error_message,\n \"total_records\": r.total_records or 0,\n \"successful_records\": r.successful_records or 0,\n \"failed_records\": r.failed_records or 0,\n \"skipped_records\": r.skipped_records or 0,\n \"insert_status\": r.insert_status,\n \"superset_execution_id\": r.superset_execution_id,\n \"config_hash\": r.config_hash,\n \"dict_snapshot_hash\": r.dict_snapshot_hash,\n \"created_by\": r.created_by,\n \"created_at\": r.created_at.isoformat() if r.created_at else None,\n \"target_languages\": target_languages,\n \"total_translated\": total_translated,\n \"language_stats\": language_stats,\n })\n\n return {\"items\": items, \"total\": total, \"page\": page, \"page_size\": page_size}\n except Exception as e:\n logger.explore(\"list_runs failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion list_runs\n" }, { "contract_id": "get_run_detail", @@ -23354,9 +23092,10 @@ "file_path": "backend/src/api/routes/translate/_run_list_routes.py", "start_line": 129, "end_line": 165, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns run detail with records and events.", "PRE": "User has translate.history.view permission.", "PURPOSE": "Get detailed run info with config_snapshot, records, events." @@ -23364,37 +23103,38 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region get_run_detail [TYPE Function]\n# @BRIEF Get detailed run info with config_snapshot, records, events.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns run detail with records and events.\n@router.get(\"/runs/{run_id}/detail\")\nasync def get_run_detail(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get detailed run info with config_snapshot, records, events.\"\"\"\n logger.reason(f\"get_run_detail — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n status_info = orch.get_run_status(run_id)\n records = orch.get_run_records(run_id, page=1, page_size=50)\n events = TranslationEventLog(db).query_events(run_id=run_id)\n event_summary = TranslationEventLog(db).get_run_event_summary(run_id)\n\n # Get config snapshot from run\n from ....models.translate import TranslationRun\n run = db.query(TranslationRun).filter(TranslationRun.id == run_id).first()\n config_snapshot = run.config_snapshot if run else None\n\n return {\n **status_info,\n \"config_snapshot\": config_snapshot,\n \"config_hash\": run.config_hash if run else None,\n \"records\": records,\n \"events\": events,\n \"event_invariants\": event_summary,\n }\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_run_detail\n" + "body": "# #region get_run_detail [C:4] [TYPE Function]\n# @BRIEF Get detailed run info with config_snapshot, records, events.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns run detail with records and events.\n@router.get(\"/runs/{run_id}/detail\")\nasync def get_run_detail(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get detailed run info with config_snapshot, records, events.\"\"\"\n logger.reason(f\"get_run_detail — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n status_info = orch.get_run_status(run_id)\n records = orch.get_run_records(run_id, page=1, page_size=50)\n events = TranslationEventLog(db).query_events(run_id=run_id)\n event_summary = TranslationEventLog(db).get_run_event_summary(run_id)\n\n # Get config snapshot from run\n from ....models.translate import TranslationRun\n run = db.query(TranslationRun).filter(TranslationRun.id == run_id).first()\n config_snapshot = run.config_snapshot if run else None\n\n return {\n **status_info,\n \"config_snapshot\": config_snapshot,\n \"config_hash\": run.config_hash if run else None,\n \"records\": records,\n \"events\": events,\n \"event_invariants\": event_summary,\n }\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_run_detail\n" }, { "contract_id": "download_skipped_csv", "contract_type": "Function", "file_path": "backend/src/api/routes/translate/_run_list_routes.py", "start_line": 172, - "end_line": 221, - "tier": "TIER_1", - "complexity": 1, + "end_line": 223, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": "4", "POST": "Returns CSV file of skipped records.", "PRE": "User has translate.job.view permission.", "PURPOSE": "Download a CSV of skipped translation records from a run." @@ -23402,34 +23142,34 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region download_skipped_csv [TYPE Function]\n# @BRIEF Download a CSV of skipped translation records from a run.\n# @PRE: User has translate.job.view permission.\n# @POST: Returns CSV file of skipped records.\n@router.get(\"/runs/{run_id}/skipped.csv\")\nasync def download_skipped_csv(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Download skipped translation records as CSV.\"\"\"\n logger.reason(f\"download_skipped_csv — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n import csv\n import io\n\n from fastapi.responses import StreamingResponse\n\n from ....models.translate import TranslationRecord\n\n records = (\n db.query(TranslationRecord)\n .filter(\n TranslationRecord.run_id == run_id,\n TranslationRecord.status == \"SKIPPED\",\n )\n .all()\n )\n\n output = io.StringIO()\n writer = csv.writer(output)\n writer.writerow([\"id\", \"source_sql\", \"target_sql\", \"source_object_type\",\n \"source_object_id\", \"source_object_name\", \"error_message\"])\n for rec in records:\n writer.writerow([\n rec.id, rec.source_sql, rec.target_sql, rec.source_object_type,\n rec.source_object_id, rec.source_object_name, rec.error_message,\n ])\n\n output.seek(0)\n return StreamingResponse(\n iter([output.getvalue()]),\n media_type=\"text/csv\",\n headers={\"Content-Disposition\": f\"attachment; filename=skipped_{run_id}.csv\"},\n )\n except Exception as e:\n logger.explore(\"download_skipped_csv failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion download_skipped_csv\n" + "body": "# #region download_skipped_csv [C:4] [TYPE Function]\n# @BRIEF Download a CSV of skipped translation records from a run.\n# @PRE User has translate.job.view permission.\n# @POST Returns CSV file of skipped records.\n# @COMPLEXITY 4\n\n@router.get(\"/runs/{run_id}/skipped.csv\")\nasync def download_skipped_csv(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Download skipped translation records as CSV.\"\"\"\n logger.reason(f\"download_skipped_csv — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n import csv\n import io\n\n from fastapi.responses import StreamingResponse\n\n from ....models.translate import TranslationRecord\n\n records = (\n db.query(TranslationRecord)\n .filter(\n TranslationRecord.run_id == run_id,\n TranslationRecord.status == \"SKIPPED\",\n )\n .all()\n )\n\n output = io.StringIO()\n writer = csv.writer(output)\n writer.writerow([\"id\", \"source_sql\", \"target_sql\", \"source_object_type\",\n \"source_object_id\", \"source_object_name\", \"error_message\"])\n for rec in records:\n writer.writerow([\n rec.id, rec.source_sql, rec.target_sql, rec.source_object_type,\n rec.source_object_id, rec.source_object_name, rec.error_message,\n ])\n\n output.seek(0)\n return StreamingResponse(\n iter([output.getvalue()]),\n media_type=\"text/csv\",\n headers={\"Content-Disposition\": f\"attachment; filename=skipped_{run_id}.csv\"},\n )\n except Exception as e:\n logger.explore(\"download_skipped_csv failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion download_skipped_csv\n" }, { "contract_id": "TranslateRunRoutesModule", "contract_type": "Module", "file_path": "backend/src/api/routes/translate/_run_routes.py", "start_line": 1, - "end_line": 552, + "end_line": 554, "tier": "TIER_2", "complexity": 3, "metadata": { @@ -23451,7 +23191,7 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslateRunRoutesModule [C:3] [TYPE Module] [SEMANTICS fastapi, translate, api, search, execution, history]\n# @BRIEF Translation Run execution, history, status, records and batches routes.\n# @LAYER: API\n\nfrom datetime import UTC, datetime\n\nfrom fastapi import Depends, HTTPException, Query, status\nfrom sqlalchemy.orm import Session\n\nfrom ....core.config_manager import ConfigManager\nfrom ....core.database import SessionLocal, get_db\nfrom ....core.logger import logger\nfrom ....dependencies import get_config_manager, get_current_user, has_permission\nfrom ....plugins.translate.orchestrator import TranslationOrchestrator\nfrom ....schemas.auth import User\nfrom ....schemas.translate import (\n BulkFindReplaceRequest,\n InlineEditRequest,\n OverrideLanguageRequest,\n)\nfrom ._helpers import _run_to_response\nfrom ._router import router\n\n# ============================================================\n# Translation Run / Execute\n# ============================================================\n\n# #region run_translation [TYPE Function]\n# @BRIEF Execute a translation job (trigger a run).\n# @PRE: User has translate.job.execute permission.\n# @POST: Returns the created translation run.\n@router.post(\"/jobs/{job_id}/run\", status_code=status.HTTP_201_CREATED)\ndef run_translation(\n job_id: str,\n full_translation: bool = Query(False, description=\"Translate ALL rows (skip new-key-only filter)\"),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Execute a translation job (trigger a run).\n\n - Normal run (default): translates only new/changed rows\n - Full translation (full_translation=true): re-translates ALL rows from the datasource\n \"\"\"\n logger.reason(\n f\"run_translation — Job: {job_id}, User: {current_user.username}, full: {full_translation}\",\n extra={\"src\": \"translate_routes\"},\n )\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n run = orch.start_run(job_id=job_id, is_scheduled=False, full_translation=full_translation)\n # The request-scoped db session will be closed after this handler returns.\n # The background thread must use its OWN session to avoid operating on a\n # closed or expunged session.\n import threading\n\n def _background_execute():\n from ....models.translate import TranslationRun as TRModel\n bg_db = None\n try:\n bg_db = SessionLocal()\n bg_orch = TranslationOrchestrator(\n bg_db, config_manager,\n current_user.username if current_user else None,\n )\n # Re-fetch the run within the background session to get a fresh,\n # attached object\n bg_run = bg_db.query(TRModel).filter(TRModel.id == run.id).first()\n if bg_run is None:\n logger.explore(\n \"Background execute: run not found\",\n extra={\"src\": \"translate_routes\", \"run_id\": run.id},\n )\n return\n\n # execute_run internally calls self.db.commit()\n bg_orch.execute_run(bg_run)\n\n # ----- VERIFICATION -----\n # After execute_run the run object from bg_db is detached after\n # commit. Re-query to verify the status was persisted in the\n # database and is a terminal state.\n check_run = bg_db.query(TRModel).filter(TRModel.id == run.id).first()\n if check_run and check_run.status in (\"COMPLETED\", \"FAILED\", \"CANCELLED\"):\n logger.reason(\n \"Background execute verified\",\n extra={\n \"src\": \"translate_routes\",\n \"run_id\": run.id,\n \"status\": check_run.status,\n },\n )\n else:\n # execute_run appeared to succeed but the run is still in a\n # non-terminal state — manually fail it so the frontend\n # polling can detect the terminal state and stop spinning.\n actual_status = check_run.status if check_run else \"NOT_FOUND\"\n logger.explore(\n \"Background execute: run not in terminal state after commit\",\n extra={\n \"src\": \"translate_routes\",\n \"run_id\": run.id,\n \"status\": actual_status,\n },\n )\n if check_run:\n check_run.status = \"FAILED\"\n check_run.error_message = (\n \"Background execution did not reach terminal state \"\n f\"(was: {actual_status})\"\n )\n bg_db.commit()\n\n except Exception as bg_err:\n logger.explore(\n \"Background execute failed\",\n extra={\n \"src\": \"translate_routes\",\n \"run_id\": run.id,\n \"error\": str(bg_err),\n },\n )\n # Mark the run as FAILED so the frontend polling can detect a\n # terminal state and stop spinning.\n try:\n fb_db = SessionLocal()\n try:\n fb_run = fb_db.query(TRModel).filter(TRModel.id == run.id).first()\n if fb_run:\n fb_run.status = \"FAILED\"\n fb_run.error_message = f\"Background execute error: {bg_err}\"\n fb_run.completed_at = datetime.now(UTC)\n fb_db.commit()\n logger.reason(\n \"Background execute: run marked FAILED\",\n extra={\"src\": \"translate_routes\", \"run_id\": run.id},\n )\n finally:\n fb_db.close()\n except Exception as fb_err:\n logger.explore(\n \"Background execute: unable to mark run FAILED\",\n extra={\n \"src\": \"translate_routes\",\n \"run_id\": run.id,\n \"error\": str(fb_err),\n },\n )\n finally:\n if bg_db is not None:\n bg_db.close()\n\n threading.Thread(\n target=_background_execute,\n daemon=True,\n ).start()\n return _run_to_response(run)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"run_translation failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=f\"Run failed: {e}\")\n# #endregion run_translation\n\n\n# #region retry_run [TYPE Function]\n# @BRIEF Retry failed batches in a translation run.\n# @PRE: User has translate.job.execute permission.\n# @POST: Returns the updated translation run.\n@router.post(\"/runs/{run_id}/retry\")\ndef retry_run(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Retry failed batches in a translation run.\"\"\"\n logger.reason(f\"retry_run — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n run = orch.retry_failed_batches(run_id)\n return _run_to_response(run)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"retry_run failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=f\"Retry failed: {e}\")\n# #endregion retry_run\n\n\n# #region retry_insert [TYPE Function]\n# @BRIEF Retry the SQL insert phase for a completed run.\n# @PRE: User has translate.job.execute permission.\n# @POST: Returns the updated run.\n@router.post(\"/runs/{run_id}/retry-insert\")\ndef retry_insert(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Retry the SQL insert phase for a completed run.\"\"\"\n logger.reason(f\"retry_insert — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n run = orch.retry_insert(run_id)\n return _run_to_response(run)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"retry_insert failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=f\"Retry insert failed: {e}\")\n# #endregion retry_insert\n\n\n# #region cancel_run [TYPE Function]\n# @BRIEF Cancel a running translation.\n# @PRE: User has translate.job.execute permission.\n# @POST: Run is cancelled.\n@router.post(\"/runs/{run_id}/cancel\")\ndef cancel_run(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Cancel a running translation.\"\"\"\n logger.reason(f\"cancel_run — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n run = orch.cancel_run(run_id)\n return _run_to_response(run)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion cancel_run\n\n\n# #region get_run_history [TYPE Function]\n# @BRIEF Get run history for a translation job.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns list of runs.\n@router.get(\"/jobs/{job_id}/runs\")\ndef get_run_history(\n job_id: str,\n page: int = Query(1, ge=1),\n page_size: int = Query(20, ge=1, le=100),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get run history for a translation job.\"\"\"\n logger.reason(f\"get_run_history — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n total, runs = orch.get_run_history(job_id, page=page, page_size=page_size)\n return {\"items\": runs, \"total\": total, \"page\": page, \"page_size\": page_size}\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_run_history\n\n\n# #region get_run_status [TYPE Function]\n# @BRIEF Get status and statistics for a translation run.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns run details with statistics.\n@router.get(\"/runs/{run_id}\")\ndef get_run_status(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get status and statistics for a translation run.\"\"\"\n logger.reason(f\"get_run_status — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n return orch.get_run_status(run_id)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_run_status\n\n\n# #region get_run_records [TYPE Function]\n# @BRIEF Get paginated records for a translation run.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns paginated records.\n@router.get(\"/runs/{run_id}/records\")\ndef get_run_records(\n run_id: str,\n page: int = Query(1, ge=1),\n page_size: int = Query(50, ge=1, le=500),\n status: str | None = Query(None),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get paginated records for a translation run.\"\"\"\n logger.reason(f\"get_run_records — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n return orch.get_run_records(run_id, page=page, page_size=page_size, status_filter=status)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_run_records\n\n\n# ============================================================\n# Batches\n# ============================================================\n\n# #region get_batches [TYPE Function]\n# @BRIEF Get batches for a translation run.\n# @PRE: User has translate.job.view permission.\n# @POST: Returns list of batches.\n@router.get(\"/runs/{run_id}/batches\")\ndef get_batches(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get batches for a translation run.\"\"\"\n logger.reason(f\"get_batches — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n from ....models.translate import TranslationBatch\n batches = (\n db.query(TranslationBatch)\n .filter(TranslationBatch.run_id == run_id)\n .order_by(TranslationBatch.batch_index.asc())\n .all()\n )\n return [\n {\n \"id\": b.id,\n \"run_id\": b.run_id,\n \"batch_index\": b.batch_index,\n \"status\": b.status,\n \"total_records\": b.total_records or 0,\n \"successful_records\": b.successful_records or 0,\n \"failed_records\": b.failed_records or 0,\n \"started_at\": b.started_at.isoformat() if b.started_at else None,\n \"completed_at\": b.completed_at.isoformat() if b.completed_at else None,\n \"created_at\": b.created_at.isoformat() if b.created_at else None,\n }\n for b in batches\n ]\n except Exception as e:\n logger.explore(\"get_batches failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion get_batches\n\n# ============================================================\n# Manual Language Override\n# ============================================================\n\n# #region override_detected_language [TYPE Function]\n# @BRIEF Manually override the detected source language for a specific translation language entry.\n# @PRE: User has translate.job.execute permission. Run, record, and language entry exist.\n# @POST: TranslationLanguage.source_language_detected is updated; language_overridden is set to True.\n# @SIDE_EFFECT: DB write.\n@router.put(\"/runs/{run_id}/records/{record_id}/languages/{language_code}/override-language\")\ndef override_detected_language(\n run_id: str,\n record_id: str,\n language_code: str,\n payload: OverrideLanguageRequest,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Manually override the detected source language for a translation entry.\"\"\"\n logger.reason(f\"override_detected_language — Run: {run_id}, Record: {record_id}, Lang: {language_code}, Override: {payload.source_language}\", extra={\"src\": \"translate_routes\"})\n try:\n from ....models.translate import TranslationLanguage, TranslationRecord\n\n # Verify the record exists and belongs to the run\n record = (\n db.query(TranslationRecord)\n .filter(\n TranslationRecord.id == record_id,\n TranslationRecord.run_id == run_id,\n )\n .first()\n )\n if not record:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=f\"Translation record '{record_id}' not found in run '{run_id}'\",\n )\n\n # Find the language entry\n lang_entry = (\n db.query(TranslationLanguage)\n .filter(\n TranslationLanguage.record_id == record_id,\n TranslationLanguage.language_code == language_code,\n )\n .first()\n )\n if not lang_entry:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=f\"Language entry '{language_code}' not found for record '{record_id}'\",\n )\n\n # Update the language entry\n lang_entry.source_language_detected = payload.source_language\n lang_entry.language_overridden = True\n lang_entry.needs_review = False # Override clears the review flag\n db.commit()\n db.refresh(lang_entry)\n\n logger.reason(\"Language override applied\", {\n \"run_id\": run_id,\n \"record_id\": record_id,\n \"language_code\": language_code,\n \"new_source_language\": payload.source_language,\n \"overridden_by\": current_user.username,\n })\n\n from ....schemas.translate import TranslationLanguageResponse\n return TranslationLanguageResponse.model_validate(lang_entry)\n except HTTPException:\n raise\n except Exception as e:\n logger.explore(\"override_detected_language failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion override_detected_language\n\n\n# ============================================================\n# Inline Correction\n# ============================================================\n\n# #region inline_edit_translation [C:3] [TYPE Function] [SEMANTICS api,translate,correction]\n# @BRIEF Apply an inline correction to a translated value on a completed run result.\n# @PRE: User has translate.job.execute permission. Run, record, and language entry exist.\n# @POST: TranslationLanguage.final_value and user_edit are updated. Optional dictionary submission.\n@router.put(\"/runs/{run_id}/records/{record_id}/languages/{language_code}\")\ndef inline_edit_translation(\n run_id: str,\n record_id: str,\n language_code: str,\n payload: InlineEditRequest,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Apply an inline correction to a translated value.\"\"\"\n logger.reason(\n f\"inline_edit_translation — Run: {run_id}, Record: {record_id}, \"\n f\"Lang: {language_code}, User: {current_user.username}\",\n extra={\"src\": \"translate_routes\"},\n )\n try:\n from ....plugins.translate.service import InlineCorrectionService\n\n result = InlineCorrectionService.apply_inline_edit(\n db=db,\n run_id=run_id,\n record_id=record_id,\n language_code=language_code,\n final_value=payload.final_value,\n submit_to_dictionary=payload.submit_to_dictionary,\n dictionary_id=payload.dictionary_id,\n current_user=current_user.username,\n context_data_override=payload.context_data_override,\n usage_notes=payload.usage_notes,\n keep_context=payload.keep_context,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"inline_edit_translation failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion inline_edit_translation\n\n\n# ============================================================\n# Bulk Find-and-Replace\n# ============================================================\n\n# #region bulk_find_replace [C:3] [TYPE Function] [SEMANTICS api,translate,bulk,replace]\n# @BRIEF Perform bulk find-and-replace on translated values within a run.\n# @PRE: User has translate.job.execute permission. Run exists.\n# @POST: If preview=false, matching translations are updated. Optional dictionary submission.\n@router.post(\"/runs/{run_id}/bulk-replace\")\ndef bulk_find_replace(\n run_id: str,\n payload: BulkFindReplaceRequest,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Perform bulk find-and-replace on translated values within a run.\"\"\"\n logger.reason(\n f\"bulk_find_replace — Run: {run_id}, Pattern: '{payload.find_pattern}', \"\n f\"Regex: {payload.is_regex}, Lang: {payload.target_language}, \"\n f\"User: {current_user.username}\",\n extra={\"src\": \"translate_routes\"},\n )\n try:\n from ....plugins.translate.service import BulkFindReplaceService\n\n if payload.preview:\n # Preview mode: return matches without applying\n preview = BulkFindReplaceService.preview(\n db=db,\n run_id=run_id,\n pattern=payload.find_pattern,\n is_regex=payload.is_regex,\n replacement_text=payload.replacement_text,\n target_language=payload.target_language,\n )\n return {\n \"rows_affected\": len(preview),\n \"corrections_submitted\": 0,\n \"preview\": preview,\n }\n\n # Apply mode: perform replacements\n result = BulkFindReplaceService.apply(\n db=db,\n run_id=run_id,\n pattern=payload.find_pattern,\n is_regex=payload.is_regex,\n replacement_text=payload.replacement_text,\n target_language=payload.target_language,\n submit_to_dictionary=payload.submit_to_dictionary,\n dictionary_id=payload.dictionary_id,\n usage_notes=payload.usage_notes,\n current_user=current_user.username,\n submit_to_dictionary_with_context=payload.submit_to_dictionary_with_context,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"bulk_find_replace failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion bulk_find_replace\n\n\n# #endregion TranslateRunRoutesModule\n" + "body": "# #region TranslateRunRoutesModule [C:3] [TYPE Module] [SEMANTICS fastapi, translate, api, search, execution, history]\n# @BRIEF Translation Run execution, history, status, records and batches routes.\n# @LAYER: API\n\nfrom datetime import UTC, datetime\n\nfrom fastapi import Depends, HTTPException, Query, status\nfrom sqlalchemy.orm import Session\n\nfrom ....core.config_manager import ConfigManager\nfrom ....core.database import SessionLocal, get_db\nfrom ....core.logger import logger\nfrom ....dependencies import get_config_manager, get_current_user, has_permission\nfrom ....plugins.translate.orchestrator import TranslationOrchestrator\nfrom ....schemas.auth import User\nfrom ....schemas.translate import (\n BulkFindReplaceRequest,\n InlineEditRequest,\n OverrideLanguageRequest,\n)\nfrom ._helpers import _run_to_response\nfrom ._router import router\n\n# ============================================================\n# Translation Run / Execute\n# ============================================================\n\n# #region run_translation [C:4] [TYPE Function]\n# @BRIEF Execute a translation job (trigger a run).\n# @PRE: User has translate.job.execute permission.\n# @POST: Returns the created translation run.\n@router.post(\"/jobs/{job_id}/run\", status_code=status.HTTP_201_CREATED)\ndef run_translation(\n job_id: str,\n full_translation: bool = Query(False, description=\"Translate ALL rows (skip new-key-only filter)\"),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Execute a translation job (trigger a run).\n\n - Normal run (default): translates only new/changed rows\n - Full translation (full_translation=true): re-translates ALL rows from the datasource\n \"\"\"\n logger.reason(\n f\"run_translation — Job: {job_id}, User: {current_user.username}, full: {full_translation}\",\n extra={\"src\": \"translate_routes\"},\n )\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n run = orch.start_run(job_id=job_id, is_scheduled=False, full_translation=full_translation)\n # The request-scoped db session will be closed after this handler returns.\n # The background thread must use its OWN session to avoid operating on a\n # closed or expunged session.\n import threading\n\n def _background_execute():\n from ....models.translate import TranslationRun as TRModel\n bg_db = None\n try:\n bg_db = SessionLocal()\n bg_orch = TranslationOrchestrator(\n bg_db, config_manager,\n current_user.username if current_user else None,\n )\n # Re-fetch the run within the background session to get a fresh,\n # attached object\n bg_run = bg_db.query(TRModel).filter(TRModel.id == run.id).first()\n if bg_run is None:\n logger.explore(\n \"Background execute: run not found\",\n extra={\"src\": \"translate_routes\", \"run_id\": run.id},\n )\n return\n\n # execute_run internally calls self.db.commit()\n bg_orch.execute_run(bg_run)\n\n # ----- VERIFICATION -----\n # After execute_run the run object from bg_db is detached after\n # commit. Re-query to verify the status was persisted in the\n # database and is a terminal state.\n check_run = bg_db.query(TRModel).filter(TRModel.id == run.id).first()\n if check_run and check_run.status in (\"COMPLETED\", \"FAILED\", \"CANCELLED\"):\n logger.reason(\n \"Background execute verified\",\n extra={\n \"src\": \"translate_routes\",\n \"run_id\": run.id,\n \"status\": check_run.status,\n },\n )\n else:\n # execute_run appeared to succeed but the run is still in a\n # non-terminal state — manually fail it so the frontend\n # polling can detect the terminal state and stop spinning.\n actual_status = check_run.status if check_run else \"NOT_FOUND\"\n logger.explore(\n \"Background execute: run not in terminal state after commit\",\n extra={\n \"src\": \"translate_routes\",\n \"run_id\": run.id,\n \"status\": actual_status,\n },\n )\n if check_run:\n check_run.status = \"FAILED\"\n check_run.error_message = (\n \"Background execution did not reach terminal state \"\n f\"(was: {actual_status})\"\n )\n bg_db.commit()\n\n except Exception as bg_err:\n logger.explore(\n \"Background execute failed\",\n extra={\n \"src\": \"translate_routes\",\n \"run_id\": run.id,\n \"error\": str(bg_err),\n },\n )\n # Mark the run as FAILED so the frontend polling can detect a\n # terminal state and stop spinning.\n try:\n fb_db = SessionLocal()\n try:\n fb_run = fb_db.query(TRModel).filter(TRModel.id == run.id).first()\n if fb_run:\n fb_run.status = \"FAILED\"\n fb_run.error_message = f\"Background execute error: {bg_err}\"\n fb_run.completed_at = datetime.now(UTC)\n fb_db.commit()\n logger.reason(\n \"Background execute: run marked FAILED\",\n extra={\"src\": \"translate_routes\", \"run_id\": run.id},\n )\n finally:\n fb_db.close()\n except Exception as fb_err:\n logger.explore(\n \"Background execute: unable to mark run FAILED\",\n extra={\n \"src\": \"translate_routes\",\n \"run_id\": run.id,\n \"error\": str(fb_err),\n },\n )\n finally:\n if bg_db is not None:\n bg_db.close()\n\n threading.Thread(\n target=_background_execute,\n daemon=True,\n ).start()\n return _run_to_response(run)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"run_translation failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=f\"Run failed: {e}\")\n# #endregion run_translation\n\n\n# #region retry_run [C:4] [TYPE Function]\n# @BRIEF Retry failed batches in a translation run.\n# @PRE: User has translate.job.execute permission.\n# @POST: Returns the updated translation run.\n@router.post(\"/runs/{run_id}/retry\")\ndef retry_run(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Retry failed batches in a translation run.\"\"\"\n logger.reason(f\"retry_run — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n run = orch.retry_failed_batches(run_id)\n return _run_to_response(run)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"retry_run failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=f\"Retry failed: {e}\")\n# #endregion retry_run\n\n\n# #region retry_insert [C:4] [TYPE Function]\n# @BRIEF Retry the SQL insert phase for a completed run.\n# @PRE: User has translate.job.execute permission.\n# @POST: Returns the updated run.\n@router.post(\"/runs/{run_id}/retry-insert\")\ndef retry_insert(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Retry the SQL insert phase for a completed run.\"\"\"\n logger.reason(f\"retry_insert — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n run = orch.retry_insert(run_id)\n return _run_to_response(run)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"retry_insert failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=f\"Retry insert failed: {e}\")\n# #endregion retry_insert\n\n\n# #region cancel_run [C:4] [TYPE Function]\n# @BRIEF Cancel a running translation.\n# @PRE: User has translate.job.execute permission.\n# @POST: Run is cancelled.\n@router.post(\"/runs/{run_id}/cancel\")\ndef cancel_run(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Cancel a running translation.\"\"\"\n logger.reason(f\"cancel_run — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n run = orch.cancel_run(run_id)\n return _run_to_response(run)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion cancel_run\n\n\n# #region get_run_history [C:4] [TYPE Function]\n# @BRIEF Get run history for a translation job.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns list of runs.\n@router.get(\"/jobs/{job_id}/runs\")\ndef get_run_history(\n job_id: str,\n page: int = Query(1, ge=1),\n page_size: int = Query(20, ge=1, le=100),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get run history for a translation job.\"\"\"\n logger.reason(f\"get_run_history — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n total, runs = orch.get_run_history(job_id, page=page, page_size=page_size)\n return {\"items\": runs, \"total\": total, \"page\": page, \"page_size\": page_size}\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_run_history\n\n\n# #region get_run_status [C:4] [TYPE Function]\n# @BRIEF Get status and statistics for a translation run.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns run details with statistics.\n@router.get(\"/runs/{run_id}\")\ndef get_run_status(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get status and statistics for a translation run.\"\"\"\n logger.reason(f\"get_run_status — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n return orch.get_run_status(run_id)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_run_status\n\n\n# #region get_run_records [C:4] [TYPE Function]\n# @BRIEF Get paginated records for a translation run.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns paginated records.\n@router.get(\"/runs/{run_id}/records\")\ndef get_run_records(\n run_id: str,\n page: int = Query(1, ge=1),\n page_size: int = Query(50, ge=1, le=500),\n status: str | None = Query(None),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get paginated records for a translation run.\"\"\"\n logger.reason(f\"get_run_records — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n return orch.get_run_records(run_id, page=page, page_size=page_size, status_filter=status)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_run_records\n\n\n# ============================================================\n# Batches\n# ============================================================\n\n# #region get_batches [C:4] [TYPE Function]\n# @BRIEF Get batches for a translation run.\n# @PRE: User has translate.job.view permission.\n# @POST: Returns list of batches.\n@router.get(\"/runs/{run_id}/batches\")\ndef get_batches(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get batches for a translation run.\"\"\"\n logger.reason(f\"get_batches — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n from ....models.translate import TranslationBatch\n batches = (\n db.query(TranslationBatch)\n .filter(TranslationBatch.run_id == run_id)\n .order_by(TranslationBatch.batch_index.asc())\n .all()\n )\n return [\n {\n \"id\": b.id,\n \"run_id\": b.run_id,\n \"batch_index\": b.batch_index,\n \"status\": b.status,\n \"total_records\": b.total_records or 0,\n \"successful_records\": b.successful_records or 0,\n \"failed_records\": b.failed_records or 0,\n \"started_at\": b.started_at.isoformat() if b.started_at else None,\n \"completed_at\": b.completed_at.isoformat() if b.completed_at else None,\n \"created_at\": b.created_at.isoformat() if b.created_at else None,\n }\n for b in batches\n ]\n except Exception as e:\n logger.explore(\"get_batches failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion get_batches\n\n# ============================================================\n# Manual Language Override\n# ============================================================\n\n# #region override_detected_language [C:4] [TYPE Function]\n# @BRIEF Manually override the detected source language for a specific translation language entry.\n# @PRE: User has translate.job.execute permission. Run, record, and language entry exist.\n# @POST: TranslationLanguage.source_language_detected is updated; language_overridden is set to True.\n# @SIDE_EFFECT: DB write.\n@router.put(\"/runs/{run_id}/records/{record_id}/languages/{language_code}/override-language\")\ndef override_detected_language(\n run_id: str,\n record_id: str,\n language_code: str,\n payload: OverrideLanguageRequest,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Manually override the detected source language for a translation entry.\"\"\"\n logger.reason(f\"override_detected_language — Run: {run_id}, Record: {record_id}, Lang: {language_code}, Override: {payload.source_language}\", extra={\"src\": \"translate_routes\"})\n try:\n from ....models.translate import TranslationLanguage, TranslationRecord\n\n # Verify the record exists and belongs to the run\n record = (\n db.query(TranslationRecord)\n .filter(\n TranslationRecord.id == record_id,\n TranslationRecord.run_id == run_id,\n )\n .first()\n )\n if not record:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=f\"Translation record '{record_id}' not found in run '{run_id}'\",\n )\n\n # Find the language entry\n lang_entry = (\n db.query(TranslationLanguage)\n .filter(\n TranslationLanguage.record_id == record_id,\n TranslationLanguage.language_code == language_code,\n )\n .first()\n )\n if not lang_entry:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=f\"Language entry '{language_code}' not found for record '{record_id}'\",\n )\n\n # Update the language entry\n lang_entry.source_language_detected = payload.source_language\n lang_entry.language_overridden = True\n lang_entry.needs_review = False # Override clears the review flag\n db.commit()\n db.refresh(lang_entry)\n\n logger.reason(\"Language override applied\", {\n \"run_id\": run_id,\n \"record_id\": record_id,\n \"language_code\": language_code,\n \"new_source_language\": payload.source_language,\n \"overridden_by\": current_user.username,\n })\n\n from ....schemas.translate import TranslationLanguageResponse\n return TranslationLanguageResponse.model_validate(lang_entry)\n except HTTPException:\n raise\n except Exception as e:\n logger.explore(\"override_detected_language failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion override_detected_language\n\n\n# ============================================================\n# Inline Correction\n# ============================================================\n\n# #region inline_edit_translation [C:4] [TYPE Function] [SEMANTICS api,translate,correction]\n# @BRIEF Apply an inline correction to a translated value on a completed run result.\n# @PRE: User has translate.job.execute permission. Run, record, and language entry exist.\n# @POST: TranslationLanguage.final_value and user_edit are updated. Optional dictionary submission.\n@router.put(\"/runs/{run_id}/records/{record_id}/languages/{language_code}\")\ndef inline_edit_translation(\n run_id: str,\n record_id: str,\n language_code: str,\n payload: InlineEditRequest,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Apply an inline correction to a translated value.\"\"\"\n logger.reason(\n f\"inline_edit_translation — Run: {run_id}, Record: {record_id}, \"\n f\"Lang: {language_code}, User: {current_user.username}\",\n extra={\"src\": \"translate_routes\"},\n )\n try:\n from ....plugins.translate.service import InlineCorrectionService\n\n result = InlineCorrectionService.apply_inline_edit(\n db=db,\n run_id=run_id,\n record_id=record_id,\n language_code=language_code,\n final_value=payload.final_value,\n submit_to_dictionary=payload.submit_to_dictionary,\n dictionary_id=payload.dictionary_id,\n current_user=current_user.username,\n context_data_override=payload.context_data_override,\n usage_notes=payload.usage_notes,\n keep_context=payload.keep_context,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"inline_edit_translation failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion inline_edit_translation\n\n\n# ============================================================\n# Bulk Find-and-Replace\n# ============================================================\n\n# #region bulk_find_replace [C:4] [TYPE Function] [SEMANTICS api,translate,bulk,replace]\n# @BRIEF Perform bulk find-and-replace on translated values within a run.\n# @PRE User has translate.job.execute permission. Run exists.\n# @POST If preview=false, matching translations are updated. Optional dictionary submission.\n# @COMPLEXITY 4\n\n@router.post(\"/runs/{run_id}/bulk-replace\")\ndef bulk_find_replace(\n run_id: str,\n payload: BulkFindReplaceRequest,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Perform bulk find-and-replace on translated values within a run.\"\"\"\n logger.reason(\n f\"bulk_find_replace — Run: {run_id}, Pattern: '{payload.find_pattern}', \"\n f\"Regex: {payload.is_regex}, Lang: {payload.target_language}, \"\n f\"User: {current_user.username}\",\n extra={\"src\": \"translate_routes\"},\n )\n try:\n from ....plugins.translate.service import BulkFindReplaceService\n\n if payload.preview:\n # Preview mode: return matches without applying\n preview = BulkFindReplaceService.preview(\n db=db,\n run_id=run_id,\n pattern=payload.find_pattern,\n is_regex=payload.is_regex,\n replacement_text=payload.replacement_text,\n target_language=payload.target_language,\n )\n return {\n \"rows_affected\": len(preview),\n \"corrections_submitted\": 0,\n \"preview\": preview,\n }\n\n # Apply mode: perform replacements\n result = BulkFindReplaceService.apply(\n db=db,\n run_id=run_id,\n pattern=payload.find_pattern,\n is_regex=payload.is_regex,\n replacement_text=payload.replacement_text,\n target_language=payload.target_language,\n submit_to_dictionary=payload.submit_to_dictionary,\n dictionary_id=payload.dictionary_id,\n usage_notes=payload.usage_notes,\n current_user=current_user.username,\n submit_to_dictionary_with_context=payload.submit_to_dictionary_with_context,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"bulk_find_replace failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion bulk_find_replace\n\n\n# #endregion TranslateRunRoutesModule\n" }, { "contract_id": "run_translation", @@ -23459,9 +23199,10 @@ "file_path": "backend/src/api/routes/translate/_run_routes.py", "start_line": 28, "end_line": 164, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns the created translation run.", "PRE": "User has translate.job.execute permission.", "PURPOSE": "Execute a translation job (trigger a run)." @@ -23469,27 +23210,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region run_translation [TYPE Function]\n# @BRIEF Execute a translation job (trigger a run).\n# @PRE: User has translate.job.execute permission.\n# @POST: Returns the created translation run.\n@router.post(\"/jobs/{job_id}/run\", status_code=status.HTTP_201_CREATED)\ndef run_translation(\n job_id: str,\n full_translation: bool = Query(False, description=\"Translate ALL rows (skip new-key-only filter)\"),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Execute a translation job (trigger a run).\n\n - Normal run (default): translates only new/changed rows\n - Full translation (full_translation=true): re-translates ALL rows from the datasource\n \"\"\"\n logger.reason(\n f\"run_translation — Job: {job_id}, User: {current_user.username}, full: {full_translation}\",\n extra={\"src\": \"translate_routes\"},\n )\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n run = orch.start_run(job_id=job_id, is_scheduled=False, full_translation=full_translation)\n # The request-scoped db session will be closed after this handler returns.\n # The background thread must use its OWN session to avoid operating on a\n # closed or expunged session.\n import threading\n\n def _background_execute():\n from ....models.translate import TranslationRun as TRModel\n bg_db = None\n try:\n bg_db = SessionLocal()\n bg_orch = TranslationOrchestrator(\n bg_db, config_manager,\n current_user.username if current_user else None,\n )\n # Re-fetch the run within the background session to get a fresh,\n # attached object\n bg_run = bg_db.query(TRModel).filter(TRModel.id == run.id).first()\n if bg_run is None:\n logger.explore(\n \"Background execute: run not found\",\n extra={\"src\": \"translate_routes\", \"run_id\": run.id},\n )\n return\n\n # execute_run internally calls self.db.commit()\n bg_orch.execute_run(bg_run)\n\n # ----- VERIFICATION -----\n # After execute_run the run object from bg_db is detached after\n # commit. Re-query to verify the status was persisted in the\n # database and is a terminal state.\n check_run = bg_db.query(TRModel).filter(TRModel.id == run.id).first()\n if check_run and check_run.status in (\"COMPLETED\", \"FAILED\", \"CANCELLED\"):\n logger.reason(\n \"Background execute verified\",\n extra={\n \"src\": \"translate_routes\",\n \"run_id\": run.id,\n \"status\": check_run.status,\n },\n )\n else:\n # execute_run appeared to succeed but the run is still in a\n # non-terminal state — manually fail it so the frontend\n # polling can detect the terminal state and stop spinning.\n actual_status = check_run.status if check_run else \"NOT_FOUND\"\n logger.explore(\n \"Background execute: run not in terminal state after commit\",\n extra={\n \"src\": \"translate_routes\",\n \"run_id\": run.id,\n \"status\": actual_status,\n },\n )\n if check_run:\n check_run.status = \"FAILED\"\n check_run.error_message = (\n \"Background execution did not reach terminal state \"\n f\"(was: {actual_status})\"\n )\n bg_db.commit()\n\n except Exception as bg_err:\n logger.explore(\n \"Background execute failed\",\n extra={\n \"src\": \"translate_routes\",\n \"run_id\": run.id,\n \"error\": str(bg_err),\n },\n )\n # Mark the run as FAILED so the frontend polling can detect a\n # terminal state and stop spinning.\n try:\n fb_db = SessionLocal()\n try:\n fb_run = fb_db.query(TRModel).filter(TRModel.id == run.id).first()\n if fb_run:\n fb_run.status = \"FAILED\"\n fb_run.error_message = f\"Background execute error: {bg_err}\"\n fb_run.completed_at = datetime.now(UTC)\n fb_db.commit()\n logger.reason(\n \"Background execute: run marked FAILED\",\n extra={\"src\": \"translate_routes\", \"run_id\": run.id},\n )\n finally:\n fb_db.close()\n except Exception as fb_err:\n logger.explore(\n \"Background execute: unable to mark run FAILED\",\n extra={\n \"src\": \"translate_routes\",\n \"run_id\": run.id,\n \"error\": str(fb_err),\n },\n )\n finally:\n if bg_db is not None:\n bg_db.close()\n\n threading.Thread(\n target=_background_execute,\n daemon=True,\n ).start()\n return _run_to_response(run)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"run_translation failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=f\"Run failed: {e}\")\n# #endregion run_translation\n" + "body": "# #region run_translation [C:4] [TYPE Function]\n# @BRIEF Execute a translation job (trigger a run).\n# @PRE: User has translate.job.execute permission.\n# @POST: Returns the created translation run.\n@router.post(\"/jobs/{job_id}/run\", status_code=status.HTTP_201_CREATED)\ndef run_translation(\n job_id: str,\n full_translation: bool = Query(False, description=\"Translate ALL rows (skip new-key-only filter)\"),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Execute a translation job (trigger a run).\n\n - Normal run (default): translates only new/changed rows\n - Full translation (full_translation=true): re-translates ALL rows from the datasource\n \"\"\"\n logger.reason(\n f\"run_translation — Job: {job_id}, User: {current_user.username}, full: {full_translation}\",\n extra={\"src\": \"translate_routes\"},\n )\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n run = orch.start_run(job_id=job_id, is_scheduled=False, full_translation=full_translation)\n # The request-scoped db session will be closed after this handler returns.\n # The background thread must use its OWN session to avoid operating on a\n # closed or expunged session.\n import threading\n\n def _background_execute():\n from ....models.translate import TranslationRun as TRModel\n bg_db = None\n try:\n bg_db = SessionLocal()\n bg_orch = TranslationOrchestrator(\n bg_db, config_manager,\n current_user.username if current_user else None,\n )\n # Re-fetch the run within the background session to get a fresh,\n # attached object\n bg_run = bg_db.query(TRModel).filter(TRModel.id == run.id).first()\n if bg_run is None:\n logger.explore(\n \"Background execute: run not found\",\n extra={\"src\": \"translate_routes\", \"run_id\": run.id},\n )\n return\n\n # execute_run internally calls self.db.commit()\n bg_orch.execute_run(bg_run)\n\n # ----- VERIFICATION -----\n # After execute_run the run object from bg_db is detached after\n # commit. Re-query to verify the status was persisted in the\n # database and is a terminal state.\n check_run = bg_db.query(TRModel).filter(TRModel.id == run.id).first()\n if check_run and check_run.status in (\"COMPLETED\", \"FAILED\", \"CANCELLED\"):\n logger.reason(\n \"Background execute verified\",\n extra={\n \"src\": \"translate_routes\",\n \"run_id\": run.id,\n \"status\": check_run.status,\n },\n )\n else:\n # execute_run appeared to succeed but the run is still in a\n # non-terminal state — manually fail it so the frontend\n # polling can detect the terminal state and stop spinning.\n actual_status = check_run.status if check_run else \"NOT_FOUND\"\n logger.explore(\n \"Background execute: run not in terminal state after commit\",\n extra={\n \"src\": \"translate_routes\",\n \"run_id\": run.id,\n \"status\": actual_status,\n },\n )\n if check_run:\n check_run.status = \"FAILED\"\n check_run.error_message = (\n \"Background execution did not reach terminal state \"\n f\"(was: {actual_status})\"\n )\n bg_db.commit()\n\n except Exception as bg_err:\n logger.explore(\n \"Background execute failed\",\n extra={\n \"src\": \"translate_routes\",\n \"run_id\": run.id,\n \"error\": str(bg_err),\n },\n )\n # Mark the run as FAILED so the frontend polling can detect a\n # terminal state and stop spinning.\n try:\n fb_db = SessionLocal()\n try:\n fb_run = fb_db.query(TRModel).filter(TRModel.id == run.id).first()\n if fb_run:\n fb_run.status = \"FAILED\"\n fb_run.error_message = f\"Background execute error: {bg_err}\"\n fb_run.completed_at = datetime.now(UTC)\n fb_db.commit()\n logger.reason(\n \"Background execute: run marked FAILED\",\n extra={\"src\": \"translate_routes\", \"run_id\": run.id},\n )\n finally:\n fb_db.close()\n except Exception as fb_err:\n logger.explore(\n \"Background execute: unable to mark run FAILED\",\n extra={\n \"src\": \"translate_routes\",\n \"run_id\": run.id,\n \"error\": str(fb_err),\n },\n )\n finally:\n if bg_db is not None:\n bg_db.close()\n\n threading.Thread(\n target=_background_execute,\n daemon=True,\n ).start()\n return _run_to_response(run)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"run_translation failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=f\"Run failed: {e}\")\n# #endregion run_translation\n" }, { "contract_id": "retry_run", @@ -23497,9 +23238,10 @@ "file_path": "backend/src/api/routes/translate/_run_routes.py", "start_line": 167, "end_line": 190, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns the updated translation run.", "PRE": "User has translate.job.execute permission.", "PURPOSE": "Retry failed batches in a translation run." @@ -23507,27 +23249,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region retry_run [TYPE Function]\n# @BRIEF Retry failed batches in a translation run.\n# @PRE: User has translate.job.execute permission.\n# @POST: Returns the updated translation run.\n@router.post(\"/runs/{run_id}/retry\")\ndef retry_run(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Retry failed batches in a translation run.\"\"\"\n logger.reason(f\"retry_run — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n run = orch.retry_failed_batches(run_id)\n return _run_to_response(run)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"retry_run failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=f\"Retry failed: {e}\")\n# #endregion retry_run\n" + "body": "# #region retry_run [C:4] [TYPE Function]\n# @BRIEF Retry failed batches in a translation run.\n# @PRE: User has translate.job.execute permission.\n# @POST: Returns the updated translation run.\n@router.post(\"/runs/{run_id}/retry\")\ndef retry_run(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Retry failed batches in a translation run.\"\"\"\n logger.reason(f\"retry_run — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n run = orch.retry_failed_batches(run_id)\n return _run_to_response(run)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"retry_run failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=f\"Retry failed: {e}\")\n# #endregion retry_run\n" }, { "contract_id": "retry_insert", @@ -23535,9 +23277,10 @@ "file_path": "backend/src/api/routes/translate/_run_routes.py", "start_line": 193, "end_line": 216, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns the updated run.", "PRE": "User has translate.job.execute permission.", "PURPOSE": "Retry the SQL insert phase for a completed run." @@ -23545,27 +23288,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region retry_insert [TYPE Function]\n# @BRIEF Retry the SQL insert phase for a completed run.\n# @PRE: User has translate.job.execute permission.\n# @POST: Returns the updated run.\n@router.post(\"/runs/{run_id}/retry-insert\")\ndef retry_insert(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Retry the SQL insert phase for a completed run.\"\"\"\n logger.reason(f\"retry_insert — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n run = orch.retry_insert(run_id)\n return _run_to_response(run)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"retry_insert failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=f\"Retry insert failed: {e}\")\n# #endregion retry_insert\n" + "body": "# #region retry_insert [C:4] [TYPE Function]\n# @BRIEF Retry the SQL insert phase for a completed run.\n# @PRE: User has translate.job.execute permission.\n# @POST: Returns the updated run.\n@router.post(\"/runs/{run_id}/retry-insert\")\ndef retry_insert(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Retry the SQL insert phase for a completed run.\"\"\"\n logger.reason(f\"retry_insert — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n run = orch.retry_insert(run_id)\n return _run_to_response(run)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"retry_insert failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=f\"Retry insert failed: {e}\")\n# #endregion retry_insert\n" }, { "contract_id": "cancel_run", @@ -23573,9 +23316,10 @@ "file_path": "backend/src/api/routes/translate/_run_routes.py", "start_line": 219, "end_line": 239, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Run is cancelled.", "PRE": "User has translate.job.execute permission.", "PURPOSE": "Cancel a running translation." @@ -23583,27 +23327,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region cancel_run [TYPE Function]\n# @BRIEF Cancel a running translation.\n# @PRE: User has translate.job.execute permission.\n# @POST: Run is cancelled.\n@router.post(\"/runs/{run_id}/cancel\")\ndef cancel_run(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Cancel a running translation.\"\"\"\n logger.reason(f\"cancel_run — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n run = orch.cancel_run(run_id)\n return _run_to_response(run)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion cancel_run\n" + "body": "# #region cancel_run [C:4] [TYPE Function]\n# @BRIEF Cancel a running translation.\n# @PRE: User has translate.job.execute permission.\n# @POST: Run is cancelled.\n@router.post(\"/runs/{run_id}/cancel\")\ndef cancel_run(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Cancel a running translation.\"\"\"\n logger.reason(f\"cancel_run — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n run = orch.cancel_run(run_id)\n return _run_to_response(run)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion cancel_run\n" }, { "contract_id": "get_run_history", @@ -23611,9 +23355,10 @@ "file_path": "backend/src/api/routes/translate/_run_routes.py", "start_line": 242, "end_line": 264, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns list of runs.", "PRE": "User has translate.history.view permission.", "PURPOSE": "Get run history for a translation job." @@ -23621,27 +23366,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region get_run_history [TYPE Function]\n# @BRIEF Get run history for a translation job.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns list of runs.\n@router.get(\"/jobs/{job_id}/runs\")\ndef get_run_history(\n job_id: str,\n page: int = Query(1, ge=1),\n page_size: int = Query(20, ge=1, le=100),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get run history for a translation job.\"\"\"\n logger.reason(f\"get_run_history — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n total, runs = orch.get_run_history(job_id, page=page, page_size=page_size)\n return {\"items\": runs, \"total\": total, \"page\": page, \"page_size\": page_size}\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_run_history\n" + "body": "# #region get_run_history [C:4] [TYPE Function]\n# @BRIEF Get run history for a translation job.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns list of runs.\n@router.get(\"/jobs/{job_id}/runs\")\ndef get_run_history(\n job_id: str,\n page: int = Query(1, ge=1),\n page_size: int = Query(20, ge=1, le=100),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get run history for a translation job.\"\"\"\n logger.reason(f\"get_run_history — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n total, runs = orch.get_run_history(job_id, page=page, page_size=page_size)\n return {\"items\": runs, \"total\": total, \"page\": page, \"page_size\": page_size}\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_run_history\n" }, { "contract_id": "get_run_status", @@ -23649,9 +23394,10 @@ "file_path": "backend/src/api/routes/translate/_run_routes.py", "start_line": 267, "end_line": 286, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns run details with statistics.", "PRE": "User has translate.history.view permission.", "PURPOSE": "Get status and statistics for a translation run." @@ -23659,27 +23405,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region get_run_status [TYPE Function]\n# @BRIEF Get status and statistics for a translation run.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns run details with statistics.\n@router.get(\"/runs/{run_id}\")\ndef get_run_status(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get status and statistics for a translation run.\"\"\"\n logger.reason(f\"get_run_status — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n return orch.get_run_status(run_id)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_run_status\n" + "body": "# #region get_run_status [C:4] [TYPE Function]\n# @BRIEF Get status and statistics for a translation run.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns run details with statistics.\n@router.get(\"/runs/{run_id}\")\ndef get_run_status(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get status and statistics for a translation run.\"\"\"\n logger.reason(f\"get_run_status — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n return orch.get_run_status(run_id)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_run_status\n" }, { "contract_id": "get_run_records", @@ -23687,9 +23433,10 @@ "file_path": "backend/src/api/routes/translate/_run_routes.py", "start_line": 289, "end_line": 311, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns paginated records.", "PRE": "User has translate.history.view permission.", "PURPOSE": "Get paginated records for a translation run." @@ -23697,27 +23444,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region get_run_records [TYPE Function]\n# @BRIEF Get paginated records for a translation run.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns paginated records.\n@router.get(\"/runs/{run_id}/records\")\ndef get_run_records(\n run_id: str,\n page: int = Query(1, ge=1),\n page_size: int = Query(50, ge=1, le=500),\n status: str | None = Query(None),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get paginated records for a translation run.\"\"\"\n logger.reason(f\"get_run_records — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n return orch.get_run_records(run_id, page=page, page_size=page_size, status_filter=status)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_run_records\n" + "body": "# #region get_run_records [C:4] [TYPE Function]\n# @BRIEF Get paginated records for a translation run.\n# @PRE: User has translate.history.view permission.\n# @POST: Returns paginated records.\n@router.get(\"/runs/{run_id}/records\")\ndef get_run_records(\n run_id: str,\n page: int = Query(1, ge=1),\n page_size: int = Query(50, ge=1, le=500),\n status: str | None = Query(None),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.history\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get paginated records for a translation run.\"\"\"\n logger.reason(f\"get_run_records — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n orch = TranslationOrchestrator(db, config_manager, current_user.username)\n return orch.get_run_records(run_id, page=page, page_size=page_size, status_filter=status)\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_run_records\n" }, { "contract_id": "get_batches", @@ -23725,9 +23472,10 @@ "file_path": "backend/src/api/routes/translate/_run_routes.py", "start_line": 318, "end_line": 357, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns list of batches.", "PRE": "User has translate.job.view permission.", "PURPOSE": "Get batches for a translation run." @@ -23735,27 +23483,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region get_batches [TYPE Function]\n# @BRIEF Get batches for a translation run.\n# @PRE: User has translate.job.view permission.\n# @POST: Returns list of batches.\n@router.get(\"/runs/{run_id}/batches\")\ndef get_batches(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get batches for a translation run.\"\"\"\n logger.reason(f\"get_batches — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n from ....models.translate import TranslationBatch\n batches = (\n db.query(TranslationBatch)\n .filter(TranslationBatch.run_id == run_id)\n .order_by(TranslationBatch.batch_index.asc())\n .all()\n )\n return [\n {\n \"id\": b.id,\n \"run_id\": b.run_id,\n \"batch_index\": b.batch_index,\n \"status\": b.status,\n \"total_records\": b.total_records or 0,\n \"successful_records\": b.successful_records or 0,\n \"failed_records\": b.failed_records or 0,\n \"started_at\": b.started_at.isoformat() if b.started_at else None,\n \"completed_at\": b.completed_at.isoformat() if b.completed_at else None,\n \"created_at\": b.created_at.isoformat() if b.created_at else None,\n }\n for b in batches\n ]\n except Exception as e:\n logger.explore(\"get_batches failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion get_batches\n" + "body": "# #region get_batches [C:4] [TYPE Function]\n# @BRIEF Get batches for a translation run.\n# @PRE: User has translate.job.view permission.\n# @POST: Returns list of batches.\n@router.get(\"/runs/{run_id}/batches\")\ndef get_batches(\n run_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"VIEW\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Get batches for a translation run.\"\"\"\n logger.reason(f\"get_batches — Run: {run_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n from ....models.translate import TranslationBatch\n batches = (\n db.query(TranslationBatch)\n .filter(TranslationBatch.run_id == run_id)\n .order_by(TranslationBatch.batch_index.asc())\n .all()\n )\n return [\n {\n \"id\": b.id,\n \"run_id\": b.run_id,\n \"batch_index\": b.batch_index,\n \"status\": b.status,\n \"total_records\": b.total_records or 0,\n \"successful_records\": b.successful_records or 0,\n \"failed_records\": b.failed_records or 0,\n \"started_at\": b.started_at.isoformat() if b.started_at else None,\n \"completed_at\": b.completed_at.isoformat() if b.completed_at else None,\n \"created_at\": b.created_at.isoformat() if b.created_at else None,\n }\n for b in batches\n ]\n except Exception as e:\n logger.explore(\"get_batches failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion get_batches\n" }, { "contract_id": "override_detected_language", @@ -23763,9 +23511,10 @@ "file_path": "backend/src/api/routes/translate/_run_routes.py", "start_line": 363, "end_line": 435, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "TranslationLanguage.source_language_detected is updated; language_overridden is set to True.", "PRE": "User has translate.job.execute permission. Run, record, and language entry exist.", "PURPOSE": "Manually override the detected source language for a specific translation language entry.", @@ -23774,36 +23523,18 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "SIDE_EFFECT", - "message": "@SIDE_EFFECT is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region override_detected_language [TYPE Function]\n# @BRIEF Manually override the detected source language for a specific translation language entry.\n# @PRE: User has translate.job.execute permission. Run, record, and language entry exist.\n# @POST: TranslationLanguage.source_language_detected is updated; language_overridden is set to True.\n# @SIDE_EFFECT: DB write.\n@router.put(\"/runs/{run_id}/records/{record_id}/languages/{language_code}/override-language\")\ndef override_detected_language(\n run_id: str,\n record_id: str,\n language_code: str,\n payload: OverrideLanguageRequest,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Manually override the detected source language for a translation entry.\"\"\"\n logger.reason(f\"override_detected_language — Run: {run_id}, Record: {record_id}, Lang: {language_code}, Override: {payload.source_language}\", extra={\"src\": \"translate_routes\"})\n try:\n from ....models.translate import TranslationLanguage, TranslationRecord\n\n # Verify the record exists and belongs to the run\n record = (\n db.query(TranslationRecord)\n .filter(\n TranslationRecord.id == record_id,\n TranslationRecord.run_id == run_id,\n )\n .first()\n )\n if not record:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=f\"Translation record '{record_id}' not found in run '{run_id}'\",\n )\n\n # Find the language entry\n lang_entry = (\n db.query(TranslationLanguage)\n .filter(\n TranslationLanguage.record_id == record_id,\n TranslationLanguage.language_code == language_code,\n )\n .first()\n )\n if not lang_entry:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=f\"Language entry '{language_code}' not found for record '{record_id}'\",\n )\n\n # Update the language entry\n lang_entry.source_language_detected = payload.source_language\n lang_entry.language_overridden = True\n lang_entry.needs_review = False # Override clears the review flag\n db.commit()\n db.refresh(lang_entry)\n\n logger.reason(\"Language override applied\", {\n \"run_id\": run_id,\n \"record_id\": record_id,\n \"language_code\": language_code,\n \"new_source_language\": payload.source_language,\n \"overridden_by\": current_user.username,\n })\n\n from ....schemas.translate import TranslationLanguageResponse\n return TranslationLanguageResponse.model_validate(lang_entry)\n except HTTPException:\n raise\n except Exception as e:\n logger.explore(\"override_detected_language failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion override_detected_language\n" + "body": "# #region override_detected_language [C:4] [TYPE Function]\n# @BRIEF Manually override the detected source language for a specific translation language entry.\n# @PRE: User has translate.job.execute permission. Run, record, and language entry exist.\n# @POST: TranslationLanguage.source_language_detected is updated; language_overridden is set to True.\n# @SIDE_EFFECT: DB write.\n@router.put(\"/runs/{run_id}/records/{record_id}/languages/{language_code}/override-language\")\ndef override_detected_language(\n run_id: str,\n record_id: str,\n language_code: str,\n payload: OverrideLanguageRequest,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Manually override the detected source language for a translation entry.\"\"\"\n logger.reason(f\"override_detected_language — Run: {run_id}, Record: {record_id}, Lang: {language_code}, Override: {payload.source_language}\", extra={\"src\": \"translate_routes\"})\n try:\n from ....models.translate import TranslationLanguage, TranslationRecord\n\n # Verify the record exists and belongs to the run\n record = (\n db.query(TranslationRecord)\n .filter(\n TranslationRecord.id == record_id,\n TranslationRecord.run_id == run_id,\n )\n .first()\n )\n if not record:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=f\"Translation record '{record_id}' not found in run '{run_id}'\",\n )\n\n # Find the language entry\n lang_entry = (\n db.query(TranslationLanguage)\n .filter(\n TranslationLanguage.record_id == record_id,\n TranslationLanguage.language_code == language_code,\n )\n .first()\n )\n if not lang_entry:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=f\"Language entry '{language_code}' not found for record '{record_id}'\",\n )\n\n # Update the language entry\n lang_entry.source_language_detected = payload.source_language\n lang_entry.language_overridden = True\n lang_entry.needs_review = False # Override clears the review flag\n db.commit()\n db.refresh(lang_entry)\n\n logger.reason(\"Language override applied\", {\n \"run_id\": run_id,\n \"record_id\": record_id,\n \"language_code\": language_code,\n \"new_source_language\": payload.source_language,\n \"overridden_by\": current_user.username,\n })\n\n from ....schemas.translate import TranslationLanguageResponse\n return TranslationLanguageResponse.model_validate(lang_entry)\n except HTTPException:\n raise\n except Exception as e:\n logger.explore(\"override_detected_language failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion override_detected_language\n" }, { "contract_id": "inline_edit_translation", @@ -23812,9 +23543,9 @@ "start_line": 442, "end_line": 484, "tier": "TIER_2", - "complexity": 3, + "complexity": 4, "metadata": { - "COMPLEXITY": 3, + "COMPLEXITY": 4, "POST": "TranslationLanguage.final_value and user_edit are updated. Optional dictionary submission.", "PRE": "User has translate.job.execute permission. Run, record, and language entry exist.", "PURPOSE": "Apply an inline correction to a translated value on a completed run result." @@ -23822,47 +23553,38 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C3", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 3, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C3", - "detail": { - "actual_complexity": 3, + "actual_complexity": 4, "contract_type": "Function" } }, { "code": "missing_required_tag", - "tag": "RELATION", - "message": "@RELATION is required for contract type 'Function' at C3", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 3, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region inline_edit_translation [C:3] [TYPE Function] [SEMANTICS api,translate,correction]\n# @BRIEF Apply an inline correction to a translated value on a completed run result.\n# @PRE: User has translate.job.execute permission. Run, record, and language entry exist.\n# @POST: TranslationLanguage.final_value and user_edit are updated. Optional dictionary submission.\n@router.put(\"/runs/{run_id}/records/{record_id}/languages/{language_code}\")\ndef inline_edit_translation(\n run_id: str,\n record_id: str,\n language_code: str,\n payload: InlineEditRequest,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Apply an inline correction to a translated value.\"\"\"\n logger.reason(\n f\"inline_edit_translation — Run: {run_id}, Record: {record_id}, \"\n f\"Lang: {language_code}, User: {current_user.username}\",\n extra={\"src\": \"translate_routes\"},\n )\n try:\n from ....plugins.translate.service import InlineCorrectionService\n\n result = InlineCorrectionService.apply_inline_edit(\n db=db,\n run_id=run_id,\n record_id=record_id,\n language_code=language_code,\n final_value=payload.final_value,\n submit_to_dictionary=payload.submit_to_dictionary,\n dictionary_id=payload.dictionary_id,\n current_user=current_user.username,\n context_data_override=payload.context_data_override,\n usage_notes=payload.usage_notes,\n keep_context=payload.keep_context,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"inline_edit_translation failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion inline_edit_translation\n" + "body": "# #region inline_edit_translation [C:4] [TYPE Function] [SEMANTICS api,translate,correction]\n# @BRIEF Apply an inline correction to a translated value on a completed run result.\n# @PRE: User has translate.job.execute permission. Run, record, and language entry exist.\n# @POST: TranslationLanguage.final_value and user_edit are updated. Optional dictionary submission.\n@router.put(\"/runs/{run_id}/records/{record_id}/languages/{language_code}\")\ndef inline_edit_translation(\n run_id: str,\n record_id: str,\n language_code: str,\n payload: InlineEditRequest,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Apply an inline correction to a translated value.\"\"\"\n logger.reason(\n f\"inline_edit_translation — Run: {run_id}, Record: {record_id}, \"\n f\"Lang: {language_code}, User: {current_user.username}\",\n extra={\"src\": \"translate_routes\"},\n )\n try:\n from ....plugins.translate.service import InlineCorrectionService\n\n result = InlineCorrectionService.apply_inline_edit(\n db=db,\n run_id=run_id,\n record_id=record_id,\n language_code=language_code,\n final_value=payload.final_value,\n submit_to_dictionary=payload.submit_to_dictionary,\n dictionary_id=payload.dictionary_id,\n current_user=current_user.username,\n context_data_override=payload.context_data_override,\n usage_notes=payload.usage_notes,\n keep_context=payload.keep_context,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"inline_edit_translation failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion inline_edit_translation\n" }, { "contract_id": "bulk_find_replace", "contract_type": "Function", "file_path": "backend/src/api/routes/translate/_run_routes.py", "start_line": 491, - "end_line": 549, + "end_line": 551, "tier": "TIER_2", - "complexity": 3, + "complexity": 4, "metadata": { - "COMPLEXITY": 3, + "COMPLEXITY": "4", "POST": "If preview=false, matching translations are updated. Optional dictionary submission.", "PRE": "User has translate.job.execute permission. Run exists.", "PURPOSE": "Perform bulk find-and-replace on translated values within a run." @@ -23870,43 +23592,34 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C3", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 3, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C3", - "detail": { - "actual_complexity": 3, + "actual_complexity": 4, "contract_type": "Function" } }, { "code": "missing_required_tag", - "tag": "RELATION", - "message": "@RELATION is required for contract type 'Function' at C3", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 3, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region bulk_find_replace [C:3] [TYPE Function] [SEMANTICS api,translate,bulk,replace]\n# @BRIEF Perform bulk find-and-replace on translated values within a run.\n# @PRE: User has translate.job.execute permission. Run exists.\n# @POST: If preview=false, matching translations are updated. Optional dictionary submission.\n@router.post(\"/runs/{run_id}/bulk-replace\")\ndef bulk_find_replace(\n run_id: str,\n payload: BulkFindReplaceRequest,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Perform bulk find-and-replace on translated values within a run.\"\"\"\n logger.reason(\n f\"bulk_find_replace — Run: {run_id}, Pattern: '{payload.find_pattern}', \"\n f\"Regex: {payload.is_regex}, Lang: {payload.target_language}, \"\n f\"User: {current_user.username}\",\n extra={\"src\": \"translate_routes\"},\n )\n try:\n from ....plugins.translate.service import BulkFindReplaceService\n\n if payload.preview:\n # Preview mode: return matches without applying\n preview = BulkFindReplaceService.preview(\n db=db,\n run_id=run_id,\n pattern=payload.find_pattern,\n is_regex=payload.is_regex,\n replacement_text=payload.replacement_text,\n target_language=payload.target_language,\n )\n return {\n \"rows_affected\": len(preview),\n \"corrections_submitted\": 0,\n \"preview\": preview,\n }\n\n # Apply mode: perform replacements\n result = BulkFindReplaceService.apply(\n db=db,\n run_id=run_id,\n pattern=payload.find_pattern,\n is_regex=payload.is_regex,\n replacement_text=payload.replacement_text,\n target_language=payload.target_language,\n submit_to_dictionary=payload.submit_to_dictionary,\n dictionary_id=payload.dictionary_id,\n usage_notes=payload.usage_notes,\n current_user=current_user.username,\n submit_to_dictionary_with_context=payload.submit_to_dictionary_with_context,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"bulk_find_replace failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion bulk_find_replace\n" + "body": "# #region bulk_find_replace [C:4] [TYPE Function] [SEMANTICS api,translate,bulk,replace]\n# @BRIEF Perform bulk find-and-replace on translated values within a run.\n# @PRE User has translate.job.execute permission. Run exists.\n# @POST If preview=false, matching translations are updated. Optional dictionary submission.\n# @COMPLEXITY 4\n\n@router.post(\"/runs/{run_id}/bulk-replace\")\ndef bulk_find_replace(\n run_id: str,\n payload: BulkFindReplaceRequest,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.job\", \"EXECUTE\")),\n db: Session = Depends(get_db),\n):\n \"\"\"Perform bulk find-and-replace on translated values within a run.\"\"\"\n logger.reason(\n f\"bulk_find_replace — Run: {run_id}, Pattern: '{payload.find_pattern}', \"\n f\"Regex: {payload.is_regex}, Lang: {payload.target_language}, \"\n f\"User: {current_user.username}\",\n extra={\"src\": \"translate_routes\"},\n )\n try:\n from ....plugins.translate.service import BulkFindReplaceService\n\n if payload.preview:\n # Preview mode: return matches without applying\n preview = BulkFindReplaceService.preview(\n db=db,\n run_id=run_id,\n pattern=payload.find_pattern,\n is_regex=payload.is_regex,\n replacement_text=payload.replacement_text,\n target_language=payload.target_language,\n )\n return {\n \"rows_affected\": len(preview),\n \"corrections_submitted\": 0,\n \"preview\": preview,\n }\n\n # Apply mode: perform replacements\n result = BulkFindReplaceService.apply(\n db=db,\n run_id=run_id,\n pattern=payload.find_pattern,\n is_regex=payload.is_regex,\n replacement_text=payload.replacement_text,\n target_language=payload.target_language,\n submit_to_dictionary=payload.submit_to_dictionary,\n dictionary_id=payload.dictionary_id,\n usage_notes=payload.usage_notes,\n current_user=current_user.username,\n submit_to_dictionary_with_context=payload.submit_to_dictionary_with_context,\n )\n return result\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n except Exception as e:\n logger.explore(\"bulk_find_replace failed\", extra={\"src\": \"translate_routes\", \"error\": str(e)})\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion bulk_find_replace\n" }, { "contract_id": "TranslateScheduleRoutesModule", "contract_type": "Module", "file_path": "backend/src/api/routes/translate/_schedule_routes.py", "start_line": 1, - "end_line": 237, + "end_line": 239, "tier": "TIER_2", "complexity": 3, "metadata": { @@ -23928,7 +23641,7 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslateScheduleRoutesModule [C:3] [TYPE Module] [SEMANTICS fastapi, translate, api, schedule, search]\n# @BRIEF Translation Schedule management routes.\n# @LAYER: API\n\nfrom fastapi import Depends, HTTPException, Query, status\nfrom sqlalchemy.orm import Session\n\nfrom ....core.config_manager import ConfigManager\nfrom ....core.database import get_db\nfrom ....core.logger import logger\nfrom ....dependencies import get_config_manager, get_current_user, has_permission\nfrom ....plugins.translate.scheduler import TranslationScheduler\nfrom ....schemas.auth import User\nfrom ....schemas.translate import ScheduleConfig\nfrom ._router import router\n\n# ============================================================\n# Schedule\n# ============================================================\n\n# #region get_schedule [TYPE Function]\n# @BRIEF Get the schedule for a translation job.\n# @PRE: User has translate.schedule.view permission.\n# @POST: Returns the schedule configuration.\n@router.get(\"/jobs/{job_id}/schedule\")\nasync def get_schedule(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get schedule for a translation job.\"\"\"\n logger.reason(f\"get_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n schedule = scheduler.get_schedule(job_id)\n return {\n \"id\": schedule.id,\n \"job_id\": schedule.job_id,\n \"cron_expression\": schedule.cron_expression,\n \"timezone\": schedule.timezone,\n \"is_active\": schedule.is_active,\n \"execution_mode\": schedule.execution_mode,\n \"last_run_at\": schedule.last_run_at.isoformat() if schedule.last_run_at else None,\n \"next_run_at\": schedule.next_run_at.isoformat() if schedule.next_run_at else None,\n \"created_by\": schedule.created_by,\n \"created_at\": schedule.created_at.isoformat() if schedule.created_at else None,\n \"updated_at\": schedule.updated_at.isoformat() if schedule.updated_at else None,\n }\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_schedule\n\n\n# #region set_schedule [TYPE Function]\n# @BRIEF Set or update the schedule for a translation job.\n# @PRE: User has translate.schedule.manage permission.\n# @POST: Schedule is created or updated.\n@router.put(\"/jobs/{job_id}/schedule\")\nasync def set_schedule(\n job_id: str,\n payload: ScheduleConfig,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"MANAGE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Set or update schedule for a translation job.\"\"\"\n logger.reason(f\"set_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n # Check if schedule already exists\n from ....models.translate import TranslationSchedule\n existing = db.query(TranslationSchedule).filter(\n TranslationSchedule.job_id == job_id\n ).first()\n execution_mode = getattr(payload, 'execution_mode', 'full')\n if existing:\n schedule = scheduler.update_schedule(\n job_id,\n cron_expression=payload.cron_expression,\n timezone_str=payload.timezone,\n is_active=payload.is_active,\n execution_mode=execution_mode,\n )\n else:\n schedule = scheduler.create_schedule(\n job_id,\n cron_expression=payload.cron_expression,\n timezone=payload.timezone,\n is_active=payload.is_active,\n execution_mode=execution_mode,\n )\n # Register with APScheduler via SchedulerService\n from ....dependencies import get_scheduler_service\n sched_svc = get_scheduler_service()\n sched_svc.add_translation_job(\n schedule_id=schedule.id,\n job_id=job_id,\n cron_expression=schedule.cron_expression,\n timezone=schedule.timezone,\n execution_mode=schedule.execution_mode,\n )\n return {\n \"id\": schedule.id,\n \"job_id\": schedule.job_id,\n \"cron_expression\": schedule.cron_expression,\n \"timezone\": schedule.timezone,\n \"is_active\": schedule.is_active,\n \"execution_mode\": schedule.execution_mode,\n \"last_run_at\": schedule.last_run_at.isoformat() if schedule.last_run_at else None,\n \"created_by\": schedule.created_by,\n \"created_at\": schedule.created_at.isoformat() if schedule.created_at else None,\n \"updated_at\": schedule.updated_at.isoformat() if schedule.updated_at else None,\n }\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion set_schedule\n\n\n# #region enable_schedule [TYPE Function]\n# @BRIEF Enable a schedule for a translation job.\n# @PRE: User has translate.schedule.manage permission.\n# @POST: Schedule is enabled.\n@router.post(\"/jobs/{job_id}/schedule/enable\")\nasync def enable_schedule(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"MANAGE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Enable a schedule for a translation job.\"\"\"\n logger.reason(f\"enable_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n schedule = scheduler.set_schedule_active(job_id, is_active=True)\n from ....dependencies import get_scheduler_service\n sched_svc = get_scheduler_service()\n sched_svc.add_translation_job(\n schedule_id=schedule.id,\n job_id=job_id,\n cron_expression=schedule.cron_expression,\n timezone=schedule.timezone,\n execution_mode=schedule.execution_mode,\n )\n return {\"status\": \"enabled\", \"job_id\": job_id}\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion enable_schedule\n\n\n# #region disable_schedule [TYPE Function]\n# @BRIEF Disable a schedule for a translation job.\n# @PRE: User has translate.schedule.manage permission.\n# @POST: Schedule is disabled.\n@router.post(\"/jobs/{job_id}/schedule/disable\")\nasync def disable_schedule(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"MANAGE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Disable a schedule for a translation job.\"\"\"\n logger.reason(f\"disable_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n scheduler.set_schedule_active(job_id, is_active=False)\n from ....dependencies import get_scheduler_service\n sched_svc = get_scheduler_service()\n sched_svc.remove_translation_job(schedule_id=job_id)\n return {\"status\": \"disabled\", \"job_id\": job_id}\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion disable_schedule\n\n\n# #region delete_schedule [TYPE Function]\n# @BRIEF Delete the schedule for a translation job.\n# @PRE: User has translate.schedule.manage permission.\n# @POST: Schedule is removed.\n@router.delete(\"/jobs/{job_id}/schedule\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_schedule(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"MANAGE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Delete schedule for a translation job.\"\"\"\n logger.reason(f\"delete_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n scheduler.delete_schedule(job_id)\n from ....dependencies import get_scheduler_service\n sched_svc = get_scheduler_service()\n sched_svc.remove_translation_job(schedule_id=job_id)\n return None\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion delete_schedule\n\n\n# #region get_next_executions [TYPE Function]\n# @BRIEF Preview next N executions for a job's schedule.\n# @PRE: User has translate.schedule.view permission.\n# @POST: Returns next execution times.\n@router.get(\"/jobs/{job_id}/schedule/next-executions\")\nasync def get_next_executions(\n job_id: str,\n n: int = Query(3, ge=1, le=10),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Preview next N executions for a job's schedule.\"\"\"\n logger.reason(f\"get_next_executions — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n schedule = scheduler.get_schedule(job_id)\n next_times = TranslationScheduler.get_next_executions(\n schedule.cron_expression, schedule.timezone, n=n\n )\n return {\n \"job_id\": job_id,\n \"cron_expression\": schedule.cron_expression,\n \"timezone\": schedule.timezone,\n \"next_executions\": next_times,\n }\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_next_executions\n\n# #endregion TranslateScheduleRoutesModule\n" + "body": "# #region TranslateScheduleRoutesModule [C:3] [TYPE Module] [SEMANTICS fastapi, translate, api, schedule, search]\n# @BRIEF Translation Schedule management routes.\n# @LAYER: API\n\nfrom fastapi import Depends, HTTPException, Query, status\nfrom sqlalchemy.orm import Session\n\nfrom ....core.config_manager import ConfigManager\nfrom ....core.database import get_db\nfrom ....core.logger import logger\nfrom ....dependencies import get_config_manager, get_current_user, has_permission\nfrom ....plugins.translate.scheduler import TranslationScheduler\nfrom ....schemas.auth import User\nfrom ....schemas.translate import ScheduleConfig\nfrom ._router import router\n\n# ============================================================\n# Schedule\n# ============================================================\n\n# #region get_schedule [C:4] [TYPE Function]\n# @BRIEF Get the schedule for a translation job.\n# @PRE: User has translate.schedule.view permission.\n# @POST: Returns the schedule configuration.\n@router.get(\"/jobs/{job_id}/schedule\")\nasync def get_schedule(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get schedule for a translation job.\"\"\"\n logger.reason(f\"get_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n schedule = scheduler.get_schedule(job_id)\n return {\n \"id\": schedule.id,\n \"job_id\": schedule.job_id,\n \"cron_expression\": schedule.cron_expression,\n \"timezone\": schedule.timezone,\n \"is_active\": schedule.is_active,\n \"execution_mode\": schedule.execution_mode,\n \"last_run_at\": schedule.last_run_at.isoformat() if schedule.last_run_at else None,\n \"next_run_at\": schedule.next_run_at.isoformat() if schedule.next_run_at else None,\n \"created_by\": schedule.created_by,\n \"created_at\": schedule.created_at.isoformat() if schedule.created_at else None,\n \"updated_at\": schedule.updated_at.isoformat() if schedule.updated_at else None,\n }\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_schedule\n\n\n# #region set_schedule [C:4] [TYPE Function]\n# @BRIEF Set or update the schedule for a translation job.\n# @PRE: User has translate.schedule.manage permission.\n# @POST: Schedule is created or updated.\n@router.put(\"/jobs/{job_id}/schedule\")\nasync def set_schedule(\n job_id: str,\n payload: ScheduleConfig,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"MANAGE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Set or update schedule for a translation job.\"\"\"\n logger.reason(f\"set_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n # Check if schedule already exists\n from ....models.translate import TranslationSchedule\n existing = db.query(TranslationSchedule).filter(\n TranslationSchedule.job_id == job_id\n ).first()\n execution_mode = getattr(payload, 'execution_mode', 'full')\n if existing:\n schedule = scheduler.update_schedule(\n job_id,\n cron_expression=payload.cron_expression,\n timezone_str=payload.timezone,\n is_active=payload.is_active,\n execution_mode=execution_mode,\n )\n else:\n schedule = scheduler.create_schedule(\n job_id,\n cron_expression=payload.cron_expression,\n timezone=payload.timezone,\n is_active=payload.is_active,\n execution_mode=execution_mode,\n )\n # Register with APScheduler via SchedulerService\n from ....dependencies import get_scheduler_service\n sched_svc = get_scheduler_service()\n sched_svc.add_translation_job(\n schedule_id=schedule.id,\n job_id=job_id,\n cron_expression=schedule.cron_expression,\n timezone=schedule.timezone,\n execution_mode=schedule.execution_mode,\n )\n return {\n \"id\": schedule.id,\n \"job_id\": schedule.job_id,\n \"cron_expression\": schedule.cron_expression,\n \"timezone\": schedule.timezone,\n \"is_active\": schedule.is_active,\n \"execution_mode\": schedule.execution_mode,\n \"last_run_at\": schedule.last_run_at.isoformat() if schedule.last_run_at else None,\n \"created_by\": schedule.created_by,\n \"created_at\": schedule.created_at.isoformat() if schedule.created_at else None,\n \"updated_at\": schedule.updated_at.isoformat() if schedule.updated_at else None,\n }\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion set_schedule\n\n\n# #region enable_schedule [C:4] [TYPE Function]\n# @BRIEF Enable a schedule for a translation job.\n# @PRE: User has translate.schedule.manage permission.\n# @POST: Schedule is enabled.\n@router.post(\"/jobs/{job_id}/schedule/enable\")\nasync def enable_schedule(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"MANAGE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Enable a schedule for a translation job.\"\"\"\n logger.reason(f\"enable_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n schedule = scheduler.set_schedule_active(job_id, is_active=True)\n from ....dependencies import get_scheduler_service\n sched_svc = get_scheduler_service()\n sched_svc.add_translation_job(\n schedule_id=schedule.id,\n job_id=job_id,\n cron_expression=schedule.cron_expression,\n timezone=schedule.timezone,\n execution_mode=schedule.execution_mode,\n )\n return {\"status\": \"enabled\", \"job_id\": job_id}\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion enable_schedule\n\n\n# #region disable_schedule [C:4] [TYPE Function]\n# @BRIEF Disable a schedule for a translation job.\n# @PRE: User has translate.schedule.manage permission.\n# @POST: Schedule is disabled.\n@router.post(\"/jobs/{job_id}/schedule/disable\")\nasync def disable_schedule(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"MANAGE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Disable a schedule for a translation job.\"\"\"\n logger.reason(f\"disable_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n scheduler.set_schedule_active(job_id, is_active=False)\n from ....dependencies import get_scheduler_service\n sched_svc = get_scheduler_service()\n sched_svc.remove_translation_job(schedule_id=job_id)\n return {\"status\": \"disabled\", \"job_id\": job_id}\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion disable_schedule\n\n\n# #region delete_schedule [C:4] [TYPE Function]\n# @BRIEF Delete the schedule for a translation job.\n# @PRE: User has translate.schedule.manage permission.\n# @POST: Schedule is removed.\n@router.delete(\"/jobs/{job_id}/schedule\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_schedule(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"MANAGE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Delete schedule for a translation job.\"\"\"\n logger.reason(f\"delete_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n scheduler.delete_schedule(job_id)\n from ....dependencies import get_scheduler_service\n sched_svc = get_scheduler_service()\n sched_svc.remove_translation_job(schedule_id=job_id)\n return None\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion delete_schedule\n\n\n# #region get_next_executions [C:4] [TYPE Function]\n# @BRIEF Preview next N executions for a job's schedule.\n# @PRE User has translate.schedule.view permission.\n# @POST Returns next execution times.\n# @COMPLEXITY 4\n\n@router.get(\"/jobs/{job_id}/schedule/next-executions\")\nasync def get_next_executions(\n job_id: str,\n n: int = Query(3, ge=1, le=10),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Preview next N executions for a job's schedule.\"\"\"\n logger.reason(f\"get_next_executions — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n schedule = scheduler.get_schedule(job_id)\n next_times = TranslationScheduler.get_next_executions(\n schedule.cron_expression, schedule.timezone, n=n\n )\n return {\n \"job_id\": job_id,\n \"cron_expression\": schedule.cron_expression,\n \"timezone\": schedule.timezone,\n \"next_executions\": next_times,\n }\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_next_executions\n\n# #endregion TranslateScheduleRoutesModule\n" }, { "contract_id": "get_schedule", @@ -23936,9 +23649,10 @@ "file_path": "backend/src/api/routes/translate/_schedule_routes.py", "start_line": 21, "end_line": 53, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns the schedule configuration.", "PRE": "User has translate.schedule.view permission.", "PURPOSE": "Get the schedule for a translation job." @@ -23946,27 +23660,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region get_schedule [TYPE Function]\n# @BRIEF Get the schedule for a translation job.\n# @PRE: User has translate.schedule.view permission.\n# @POST: Returns the schedule configuration.\n@router.get(\"/jobs/{job_id}/schedule\")\nasync def get_schedule(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get schedule for a translation job.\"\"\"\n logger.reason(f\"get_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n schedule = scheduler.get_schedule(job_id)\n return {\n \"id\": schedule.id,\n \"job_id\": schedule.job_id,\n \"cron_expression\": schedule.cron_expression,\n \"timezone\": schedule.timezone,\n \"is_active\": schedule.is_active,\n \"execution_mode\": schedule.execution_mode,\n \"last_run_at\": schedule.last_run_at.isoformat() if schedule.last_run_at else None,\n \"next_run_at\": schedule.next_run_at.isoformat() if schedule.next_run_at else None,\n \"created_by\": schedule.created_by,\n \"created_at\": schedule.created_at.isoformat() if schedule.created_at else None,\n \"updated_at\": schedule.updated_at.isoformat() if schedule.updated_at else None,\n }\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_schedule\n" + "body": "# #region get_schedule [C:4] [TYPE Function]\n# @BRIEF Get the schedule for a translation job.\n# @PRE: User has translate.schedule.view permission.\n# @POST: Returns the schedule configuration.\n@router.get(\"/jobs/{job_id}/schedule\")\nasync def get_schedule(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Get schedule for a translation job.\"\"\"\n logger.reason(f\"get_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n schedule = scheduler.get_schedule(job_id)\n return {\n \"id\": schedule.id,\n \"job_id\": schedule.job_id,\n \"cron_expression\": schedule.cron_expression,\n \"timezone\": schedule.timezone,\n \"is_active\": schedule.is_active,\n \"execution_mode\": schedule.execution_mode,\n \"last_run_at\": schedule.last_run_at.isoformat() if schedule.last_run_at else None,\n \"next_run_at\": schedule.next_run_at.isoformat() if schedule.next_run_at else None,\n \"created_by\": schedule.created_by,\n \"created_at\": schedule.created_at.isoformat() if schedule.created_at else None,\n \"updated_at\": schedule.updated_at.isoformat() if schedule.updated_at else None,\n }\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_schedule\n" }, { "contract_id": "set_schedule", @@ -23974,9 +23688,10 @@ "file_path": "backend/src/api/routes/translate/_schedule_routes.py", "start_line": 56, "end_line": 119, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Schedule is created or updated.", "PRE": "User has translate.schedule.manage permission.", "PURPOSE": "Set or update the schedule for a translation job." @@ -23984,27 +23699,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region set_schedule [TYPE Function]\n# @BRIEF Set or update the schedule for a translation job.\n# @PRE: User has translate.schedule.manage permission.\n# @POST: Schedule is created or updated.\n@router.put(\"/jobs/{job_id}/schedule\")\nasync def set_schedule(\n job_id: str,\n payload: ScheduleConfig,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"MANAGE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Set or update schedule for a translation job.\"\"\"\n logger.reason(f\"set_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n # Check if schedule already exists\n from ....models.translate import TranslationSchedule\n existing = db.query(TranslationSchedule).filter(\n TranslationSchedule.job_id == job_id\n ).first()\n execution_mode = getattr(payload, 'execution_mode', 'full')\n if existing:\n schedule = scheduler.update_schedule(\n job_id,\n cron_expression=payload.cron_expression,\n timezone_str=payload.timezone,\n is_active=payload.is_active,\n execution_mode=execution_mode,\n )\n else:\n schedule = scheduler.create_schedule(\n job_id,\n cron_expression=payload.cron_expression,\n timezone=payload.timezone,\n is_active=payload.is_active,\n execution_mode=execution_mode,\n )\n # Register with APScheduler via SchedulerService\n from ....dependencies import get_scheduler_service\n sched_svc = get_scheduler_service()\n sched_svc.add_translation_job(\n schedule_id=schedule.id,\n job_id=job_id,\n cron_expression=schedule.cron_expression,\n timezone=schedule.timezone,\n execution_mode=schedule.execution_mode,\n )\n return {\n \"id\": schedule.id,\n \"job_id\": schedule.job_id,\n \"cron_expression\": schedule.cron_expression,\n \"timezone\": schedule.timezone,\n \"is_active\": schedule.is_active,\n \"execution_mode\": schedule.execution_mode,\n \"last_run_at\": schedule.last_run_at.isoformat() if schedule.last_run_at else None,\n \"created_by\": schedule.created_by,\n \"created_at\": schedule.created_at.isoformat() if schedule.created_at else None,\n \"updated_at\": schedule.updated_at.isoformat() if schedule.updated_at else None,\n }\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion set_schedule\n" + "body": "# #region set_schedule [C:4] [TYPE Function]\n# @BRIEF Set or update the schedule for a translation job.\n# @PRE: User has translate.schedule.manage permission.\n# @POST: Schedule is created or updated.\n@router.put(\"/jobs/{job_id}/schedule\")\nasync def set_schedule(\n job_id: str,\n payload: ScheduleConfig,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"MANAGE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Set or update schedule for a translation job.\"\"\"\n logger.reason(f\"set_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n # Check if schedule already exists\n from ....models.translate import TranslationSchedule\n existing = db.query(TranslationSchedule).filter(\n TranslationSchedule.job_id == job_id\n ).first()\n execution_mode = getattr(payload, 'execution_mode', 'full')\n if existing:\n schedule = scheduler.update_schedule(\n job_id,\n cron_expression=payload.cron_expression,\n timezone_str=payload.timezone,\n is_active=payload.is_active,\n execution_mode=execution_mode,\n )\n else:\n schedule = scheduler.create_schedule(\n job_id,\n cron_expression=payload.cron_expression,\n timezone=payload.timezone,\n is_active=payload.is_active,\n execution_mode=execution_mode,\n )\n # Register with APScheduler via SchedulerService\n from ....dependencies import get_scheduler_service\n sched_svc = get_scheduler_service()\n sched_svc.add_translation_job(\n schedule_id=schedule.id,\n job_id=job_id,\n cron_expression=schedule.cron_expression,\n timezone=schedule.timezone,\n execution_mode=schedule.execution_mode,\n )\n return {\n \"id\": schedule.id,\n \"job_id\": schedule.job_id,\n \"cron_expression\": schedule.cron_expression,\n \"timezone\": schedule.timezone,\n \"is_active\": schedule.is_active,\n \"execution_mode\": schedule.execution_mode,\n \"last_run_at\": schedule.last_run_at.isoformat() if schedule.last_run_at else None,\n \"created_by\": schedule.created_by,\n \"created_at\": schedule.created_at.isoformat() if schedule.created_at else None,\n \"updated_at\": schedule.updated_at.isoformat() if schedule.updated_at else None,\n }\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))\n# #endregion set_schedule\n" }, { "contract_id": "enable_schedule", @@ -24012,9 +23727,10 @@ "file_path": "backend/src/api/routes/translate/_schedule_routes.py", "start_line": 122, "end_line": 151, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Schedule is enabled.", "PRE": "User has translate.schedule.manage permission.", "PURPOSE": "Enable a schedule for a translation job." @@ -24022,27 +23738,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region enable_schedule [TYPE Function]\n# @BRIEF Enable a schedule for a translation job.\n# @PRE: User has translate.schedule.manage permission.\n# @POST: Schedule is enabled.\n@router.post(\"/jobs/{job_id}/schedule/enable\")\nasync def enable_schedule(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"MANAGE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Enable a schedule for a translation job.\"\"\"\n logger.reason(f\"enable_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n schedule = scheduler.set_schedule_active(job_id, is_active=True)\n from ....dependencies import get_scheduler_service\n sched_svc = get_scheduler_service()\n sched_svc.add_translation_job(\n schedule_id=schedule.id,\n job_id=job_id,\n cron_expression=schedule.cron_expression,\n timezone=schedule.timezone,\n execution_mode=schedule.execution_mode,\n )\n return {\"status\": \"enabled\", \"job_id\": job_id}\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion enable_schedule\n" + "body": "# #region enable_schedule [C:4] [TYPE Function]\n# @BRIEF Enable a schedule for a translation job.\n# @PRE: User has translate.schedule.manage permission.\n# @POST: Schedule is enabled.\n@router.post(\"/jobs/{job_id}/schedule/enable\")\nasync def enable_schedule(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"MANAGE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Enable a schedule for a translation job.\"\"\"\n logger.reason(f\"enable_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n schedule = scheduler.set_schedule_active(job_id, is_active=True)\n from ....dependencies import get_scheduler_service\n sched_svc = get_scheduler_service()\n sched_svc.add_translation_job(\n schedule_id=schedule.id,\n job_id=job_id,\n cron_expression=schedule.cron_expression,\n timezone=schedule.timezone,\n execution_mode=schedule.execution_mode,\n )\n return {\"status\": \"enabled\", \"job_id\": job_id}\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion enable_schedule\n" }, { "contract_id": "disable_schedule", @@ -24050,9 +23766,10 @@ "file_path": "backend/src/api/routes/translate/_schedule_routes.py", "start_line": 154, "end_line": 177, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Schedule is disabled.", "PRE": "User has translate.schedule.manage permission.", "PURPOSE": "Disable a schedule for a translation job." @@ -24060,27 +23777,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region disable_schedule [TYPE Function]\n# @BRIEF Disable a schedule for a translation job.\n# @PRE: User has translate.schedule.manage permission.\n# @POST: Schedule is disabled.\n@router.post(\"/jobs/{job_id}/schedule/disable\")\nasync def disable_schedule(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"MANAGE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Disable a schedule for a translation job.\"\"\"\n logger.reason(f\"disable_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n scheduler.set_schedule_active(job_id, is_active=False)\n from ....dependencies import get_scheduler_service\n sched_svc = get_scheduler_service()\n sched_svc.remove_translation_job(schedule_id=job_id)\n return {\"status\": \"disabled\", \"job_id\": job_id}\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion disable_schedule\n" + "body": "# #region disable_schedule [C:4] [TYPE Function]\n# @BRIEF Disable a schedule for a translation job.\n# @PRE: User has translate.schedule.manage permission.\n# @POST: Schedule is disabled.\n@router.post(\"/jobs/{job_id}/schedule/disable\")\nasync def disable_schedule(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"MANAGE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Disable a schedule for a translation job.\"\"\"\n logger.reason(f\"disable_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n scheduler.set_schedule_active(job_id, is_active=False)\n from ....dependencies import get_scheduler_service\n sched_svc = get_scheduler_service()\n sched_svc.remove_translation_job(schedule_id=job_id)\n return {\"status\": \"disabled\", \"job_id\": job_id}\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion disable_schedule\n" }, { "contract_id": "delete_schedule", @@ -24088,9 +23805,10 @@ "file_path": "backend/src/api/routes/translate/_schedule_routes.py", "start_line": 180, "end_line": 203, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Schedule is removed.", "PRE": "User has translate.schedule.manage permission.", "PURPOSE": "Delete the schedule for a translation job." @@ -24098,37 +23816,38 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region delete_schedule [TYPE Function]\n# @BRIEF Delete the schedule for a translation job.\n# @PRE: User has translate.schedule.manage permission.\n# @POST: Schedule is removed.\n@router.delete(\"/jobs/{job_id}/schedule\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_schedule(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"MANAGE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Delete schedule for a translation job.\"\"\"\n logger.reason(f\"delete_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n scheduler.delete_schedule(job_id)\n from ....dependencies import get_scheduler_service\n sched_svc = get_scheduler_service()\n sched_svc.remove_translation_job(schedule_id=job_id)\n return None\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion delete_schedule\n" + "body": "# #region delete_schedule [C:4] [TYPE Function]\n# @BRIEF Delete the schedule for a translation job.\n# @PRE: User has translate.schedule.manage permission.\n# @POST: Schedule is removed.\n@router.delete(\"/jobs/{job_id}/schedule\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_schedule(\n job_id: str,\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"MANAGE\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Delete schedule for a translation job.\"\"\"\n logger.reason(f\"delete_schedule — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n scheduler.delete_schedule(job_id)\n from ....dependencies import get_scheduler_service\n sched_svc = get_scheduler_service()\n sched_svc.remove_translation_job(schedule_id=job_id)\n return None\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion delete_schedule\n" }, { "contract_id": "get_next_executions", "contract_type": "Function", "file_path": "backend/src/api/routes/translate/_schedule_routes.py", "start_line": 206, - "end_line": 235, - "tier": "TIER_1", - "complexity": 1, + "end_line": 237, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": "4", "POST": "Returns next execution times.", "PRE": "User has translate.schedule.view permission.", "PURPOSE": "Preview next N executions for a job's schedule." @@ -24136,27 +23855,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region get_next_executions [TYPE Function]\n# @BRIEF Preview next N executions for a job's schedule.\n# @PRE: User has translate.schedule.view permission.\n# @POST: Returns next execution times.\n@router.get(\"/jobs/{job_id}/schedule/next-executions\")\nasync def get_next_executions(\n job_id: str,\n n: int = Query(3, ge=1, le=10),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Preview next N executions for a job's schedule.\"\"\"\n logger.reason(f\"get_next_executions — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n schedule = scheduler.get_schedule(job_id)\n next_times = TranslationScheduler.get_next_executions(\n schedule.cron_expression, schedule.timezone, n=n\n )\n return {\n \"job_id\": job_id,\n \"cron_expression\": schedule.cron_expression,\n \"timezone\": schedule.timezone,\n \"next_executions\": next_times,\n }\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_next_executions\n" + "body": "# #region get_next_executions [C:4] [TYPE Function]\n# @BRIEF Preview next N executions for a job's schedule.\n# @PRE User has translate.schedule.view permission.\n# @POST Returns next execution times.\n# @COMPLEXITY 4\n\n@router.get(\"/jobs/{job_id}/schedule/next-executions\")\nasync def get_next_executions(\n job_id: str,\n n: int = Query(3, ge=1, le=10),\n current_user: User = Depends(get_current_user),\n _ = Depends(has_permission(\"translate.schedule\", \"VIEW\")),\n db: Session = Depends(get_db),\n config_manager: ConfigManager = Depends(get_config_manager),\n):\n \"\"\"Preview next N executions for a job's schedule.\"\"\"\n logger.reason(f\"get_next_executions — Job: {job_id}, User: {current_user.username}\", extra={\"src\": \"translate_routes\"})\n try:\n scheduler = TranslationScheduler(db, config_manager, current_user.username)\n schedule = scheduler.get_schedule(job_id)\n next_times = TranslationScheduler.get_next_executions(\n schedule.cron_expression, schedule.timezone, n=n\n )\n return {\n \"job_id\": job_id,\n \"cron_expression\": schedule.cron_expression,\n \"timezone\": schedule.timezone,\n \"next_executions\": next_times,\n }\n except ValueError as e:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))\n# #endregion get_next_executions\n" }, { "contract_id": "AppModule", @@ -47309,7 +47028,7 @@ "contract_type": "Module", "file_path": "backend/src/models/translate.py", "start_line": 1, - "end_line": 394, + "end_line": 397, "tier": "TIER_2", "complexity": 3, "metadata": { @@ -47320,34 +47039,15 @@ "relations": [ { "source_id": "TranslateModels", - "relation_type": "INHERITS_FROM", + "relation_type": "INHERITS", "target_id": "MappingModels", - "target_ref": "MappingModels:Base" - } - ], - "schema_warnings": [ - { - "code": "invalid_relation_predicate", - "tag": "RELATION", - "message": "Predicate INHERITS_FROM is not in allowed_predicates", - "detail": { - "allowed": [ - "DEPENDS_ON", - "CALLS", - "INHERITS", - "IMPLEMENTS", - "DISPATCHES", - "BINDS_TO", - "CALLED_BY", - "VERIFIES" - ], - "predicate": "INHERITS_FROM" - } + "target_ref": "[MappingModels]" } ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslateModels [C:3] [TYPE Module] [SEMANTICS sqlalchemy, translate, model, schema, dashboard, llm]\n# @BRIEF SQLAlchemy ORM models for LLM-based SQL/dashboard translation across dialects.\n# @LAYER: Domain\n# @RELATION INHERITS_FROM -> MappingModels:Base\n\nimport uuid\nfrom datetime import UTC, datetime\n\nfrom sqlalchemy import JSON, Boolean, Column, DateTime, Float, ForeignKey, Index, Integer, String, Text, UniqueConstraint\nfrom sqlalchemy.orm import relationship\n\nfrom .mapping import Base\n\n\ndef generate_uuid():\n return str(uuid.uuid4())\n\n\n# #region TranslationJob [TYPE Class]\n# @BRIEF A translation job representing a multi-dialect conversion task with column mappings, LLM config, and dictionary attachments.\n# @RATIONALE: Snapshot isolation — in-progress runs use config snapshot; config edits affect future runs only.\n# @REJECTED: Invalidating in-progress runs on config edit would break scheduled run continuity.\nclass TranslationJob(Base):\n __tablename__ = \"translation_jobs\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n name = Column(String, nullable=False)\n description = Column(Text, nullable=True)\n source_dialect = Column(String, nullable=False)\n target_dialect = Column(String, nullable=False)\n database_dialect = Column(String, nullable=True, comment=\"Detected dialect from Superset connection at save time\")\n status = Column(String, nullable=False, default=\"DRAFT\") # DRAFT, READY, RUNNING, COMPLETED, FAILED, CANCELLED\n\n # Datasource & target table configuration\n source_datasource_id = Column(String, nullable=True, comment=\"Superset datasource ID\")\n source_table = Column(String, nullable=True, comment=\"Source table name resolved from datasource\")\n target_schema = Column(String, nullable=True, comment=\"Target table schema\")\n target_table = Column(String, nullable=True, comment=\"Target table name\")\n\n # Column mapping\n source_key_cols = Column(JSON, nullable=True, comment=\"Source key column names for composite key\")\n target_key_cols = Column(JSON, nullable=True, comment=\"Target key column names for composite key\")\n translation_column = Column(String, nullable=True, comment=\"Source column whose values will be translated\")\n target_column = Column(String, nullable=True, comment=\"Target column for translated output (defaults to translation_column)\")\n target_language_column = Column(String, nullable=True, comment=\"Target column for language code (e.g. 'ru', 'en')\")\n target_source_column = Column(String, nullable=True, comment=\"Target column for source/original text\")\n target_source_language_column = Column(String, nullable=True, comment=\"Target column for detected source language (BCP-47)\")\n context_columns = Column(JSON, nullable=True, comment=\"Context column names included in LLM prompt\")\n\n # LLM & processing settings\n # source_language removed — deprecated, auto-detected per row by LLM; use TranslationLanguage.source_language_detected instead\n target_languages = Column(JSON, nullable=True, comment=\"List of BCP-47 target language codes (multi-language support)\")\n provider_id = Column(String, nullable=True, comment=\"LLM provider ID\")\n batch_size = Column(Integer, nullable=False, default=50, comment=\"Records per batch\")\n disable_reasoning = Column(Boolean, default=False, comment=\"If true, pass reasoning_effort:none to LLM to save output tokens\")\n upsert_strategy = Column(String, nullable=False, default=\"MERGE\", comment=\"MERGE, INSERT, UPDATE\")\n\n # Environment association\n environment_id = Column(String, nullable=True, comment=\"Superset environment ID for datasource access\")\n target_database_id = Column(String, nullable=True, comment=\"Superset database ID for SQL Lab insert target\")\n\n created_by = Column(String, nullable=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n updated_at = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))\n# #endregion TranslationJob\n\n\n# #region TranslationRun [TYPE Class]\n# @BRIEF Represents a single execution of a translation job, capturing status, timing, and Superset execution metadata.\nclass TranslationRun(Base):\n __tablename__ = \"translation_runs\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n job_id = Column(String, ForeignKey(\"translation_jobs.id\"), nullable=False, index=True)\n status = Column(String, nullable=False, default=\"PENDING\") # PENDING, RUNNING, COMPLETED, FAILED, CANCELLED\n trigger_type = Column(String, nullable=True, comment=\"manual, scheduled, retry, baseline_expired\")\n started_at = Column(DateTime, nullable=True)\n completed_at = Column(DateTime, nullable=True)\n error_message = Column(Text, nullable=True)\n total_records = Column(Integer, default=0)\n successful_records = Column(Integer, default=0)\n failed_records = Column(Integer, default=0)\n skipped_records = Column(Integer, default=0)\n insert_status = Column(String, nullable=True, comment=\"Status of the Superset insert/update operation\")\n superset_execution_id = Column(String, nullable=True, comment=\"Superset execution/task ID\")\n superset_execution_log = Column(JSON, nullable=True, comment=\"Superset execution log output\")\n config_snapshot = Column(JSON, nullable=True, comment=\"Snapshot of job config at run creation time\")\n key_hash = Column(String, nullable=True, comment=\"Hash of source key fields for dedup\")\n config_hash = Column(String, nullable=True, comment=\"Hash of translation configuration state\")\n dict_snapshot_hash = Column(String, nullable=True, comment=\"Hash of dictionary state at run time\")\n created_by = Column(String, nullable=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n\n language_stats = relationship(\"TranslationRunLanguageStats\", back_populates=\"run\")\n# #endregion TranslationRun\n\n\n# #region TranslationBatch [TYPE Class]\n# @BRIEF Groups translation records within a run into manageable batches with timing and record counts.\nclass TranslationBatch(Base):\n __tablename__ = \"translation_batches\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n run_id = Column(String, ForeignKey(\"translation_runs.id\"), nullable=False, index=True)\n batch_index = Column(Integer, nullable=False)\n status = Column(String, nullable=False, default=\"PENDING\")\n total_records = Column(Integer, default=0)\n successful_records = Column(Integer, default=0)\n failed_records = Column(Integer, default=0)\n started_at = Column(DateTime, nullable=True)\n completed_at = Column(DateTime, nullable=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n# #endregion TranslationBatch\n\n\n# #region TranslationRecord [TYPE Class]\n# @BRIEF Individual translation result for a single SQL statement or dashboard element, tracking source, target, and error state.\nclass TranslationRecord(Base):\n __tablename__ = \"translation_records\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n batch_id = Column(String, ForeignKey(\"translation_batches.id\"), nullable=False, index=True)\n run_id = Column(String, ForeignKey(\"translation_runs.id\"), nullable=False, index=True)\n source_sql = Column(Text, nullable=True)\n target_sql = Column(Text, nullable=True)\n source_object_type = Column(String, nullable=True) # query, dashboard, chart, dataset\n source_object_id = Column(String, nullable=True)\n source_object_name = Column(String, nullable=True)\n source_data = Column(JSON, nullable=True, comment=\"Original source row key columns for upsert matching\")\n status = Column(String, nullable=False, default=\"PENDING\") # PENDING, SUCCESS, FAILED, SKIPPED\n error_message = Column(Text, nullable=True)\n token_count_input = Column(Integer, nullable=True)\n token_count_output = Column(Integer, nullable=True)\n translation_duration_ms = Column(Integer, nullable=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n\n languages = relationship(\"TranslationLanguage\", back_populates=\"record\")\n\n __table_args__ = (\n Index(\"ix_translation_records_run_status\", \"run_id\", \"status\"),\n )\n# #endregion TranslationRecord\n\n\n# #region TranslationEvent [TYPE Class]\n# @BRIEF Audit/event log for translation operations, with optional run_id for context.\nclass TranslationEvent(Base):\n __tablename__ = \"translation_events\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n job_id = Column(String, ForeignKey(\"translation_jobs.id\"), nullable=False, index=True)\n run_id = Column(String, ForeignKey(\"translation_runs.id\"), nullable=True, index=True)\n event_type = Column(String, nullable=False) # JOB_CREATED, JOB_STARTED, JOB_COMPLETED, JOB_FAILED, etc.\n event_data = Column(JSON, nullable=True)\n created_by = Column(String, nullable=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n# #endregion TranslationEvent\n\n\n# #region TranslationPreviewSession [TYPE Class]\n# @BRIEF A preview session allowing users to review proposed translations before applying them.\nclass TranslationPreviewSession(Base):\n __tablename__ = \"translation_preview_sessions\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n job_id = Column(String, ForeignKey(\"translation_jobs.id\"), nullable=False, index=True)\n run_id = Column(String, ForeignKey(\"translation_runs.id\"), nullable=True)\n status = Column(String, nullable=False, default=\"ACTIVE\") # ACTIVE, APPLIED, DISCARDED, EXPIRED\n created_by = Column(String, nullable=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n expires_at = Column(DateTime, nullable=True)\n# #endregion TranslationPreviewSession\n\n\n# #region TranslationPreviewRecord [TYPE Class]\n# @BRIEF Individual preview entry within a preview session, showing original and translated content side by side.\nclass TranslationPreviewRecord(Base):\n __tablename__ = \"translation_preview_records\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n session_id = Column(String, ForeignKey(\"translation_preview_sessions.id\"), nullable=False, index=True)\n source_sql = Column(Text, nullable=True)\n target_sql = Column(Text, nullable=True)\n source_object_type = Column(String, nullable=True)\n source_object_id = Column(String, nullable=True)\n source_object_name = Column(String, nullable=True)\n source_data = Column(JSON, nullable=True, comment=\"Original source row key columns for upsert matching\")\n status = Column(String, nullable=False, default=\"PENDING\") # PENDING, APPROVED, REJECTED\n feedback = Column(Text, nullable=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n\n languages = relationship(\"TranslationPreviewLanguage\", back_populates=\"preview_record\")\n# #endregion TranslationPreviewRecord\n\n\n# #region TerminologyDictionary [TYPE Class]\n# @BRIEF A named collection of terminology mappings used during translation to ensure consistent term translation.\nclass TerminologyDictionary(Base):\n __tablename__ = \"terminology_dictionaries\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n name = Column(String, nullable=False)\n description = Column(Text, nullable=True)\n source_dialect = Column(String, nullable=False)\n target_dialect = Column(String, nullable=False)\n is_active = Column(Boolean, default=True)\n created_by = Column(String, nullable=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n updated_at = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))\n# #endregion TerminologyDictionary\n\n\n# #region DictionaryEntry [TYPE Class]\n# @BRIEF A single term mapping entry with case-insensitive unique constraint on source_term_normalized and origin tracking.\nclass DictionaryEntry(Base):\n __tablename__ = \"dictionary_entries\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n dictionary_id = Column(String, ForeignKey(\"terminology_dictionaries.id\"), nullable=False, index=True)\n source_term = Column(String, nullable=False)\n source_term_normalized = Column(String, nullable=False)\n target_term = Column(String, nullable=False)\n source_language = Column(String, nullable=False, comment=\"BCP-47 source language code\")\n target_language = Column(String, nullable=False, comment=\"BCP-47 target language code\")\n context_notes = Column(Text, nullable=True)\n context_data = Column(JSON, nullable=True, comment=\"Structured context for term usage\")\n usage_notes = Column(Text, nullable=True, comment=\"Usage guidance for the term mapping\")\n has_context = Column(Boolean, default=False, comment=\"Whether context_data is populated\")\n context_source = Column(String, nullable=True, comment=\"auto|auto_with_edits|manual|bulk\")\n origin_source_language = Column(String, nullable=True, comment=\"Original source language of the term\")\n origin_run_id = Column(String, nullable=True, comment=\"Run ID from which this correction originated\")\n origin_row_key = Column(String, nullable=True, comment=\"Row key within the run that triggered this correction\")\n origin_user_id = Column(String, nullable=True, comment=\"User who submitted the correction\")\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n updated_at = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))\n\n __table_args__ = (\n UniqueConstraint(\n \"dictionary_id\", \"source_term_normalized\", \"source_language\", \"target_language\",\n name=\"uq_dict_source_term_lang\"\n ),\n Index(\"idx_dict_entry_lang\", \"source_language\", \"target_language\"),\n Index(\"idx_dict_has_context\", \"has_context\"),\n )\n# #endregion DictionaryEntry\n\n\n# #region TranslationSchedule [TYPE Class]\n# @BRIEF Defines a cron-based schedule for recurring translation jobs.\nclass TranslationSchedule(Base):\n __tablename__ = \"translation_schedules\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n job_id = Column(String, ForeignKey(\"translation_jobs.id\"), nullable=False, index=True)\n cron_expression = Column(String, nullable=False)\n timezone = Column(String, nullable=False, default=\"UTC\")\n is_active = Column(Boolean, default=True)\n last_run_at = Column(DateTime, nullable=True)\n next_run_at = Column(DateTime, nullable=True)\n execution_mode = Column(String, nullable=False, default=\"full\", comment=\"full, new_key_only\")\n created_by = Column(String, nullable=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n updated_at = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))\n# #endregion TranslationSchedule\n\n\n# #region TranslationJobDictionary [TYPE Class]\n# @BRIEF Many-to-many association between translation jobs and terminology dictionaries.\nclass TranslationJobDictionary(Base):\n __tablename__ = \"translation_job_dictionaries\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n job_id = Column(String, ForeignKey(\"translation_jobs.id\"), nullable=False, index=True)\n dictionary_id = Column(String, ForeignKey(\"terminology_dictionaries.id\"), nullable=False, index=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n\n __table_args__ = (\n UniqueConstraint(\n \"job_id\", \"dictionary_id\",\n name=\"uq_job_dictionary\"\n ),\n )\n# #endregion TranslationJobDictionary\n\n\n# #region MetricSnapshot [TYPE Class]\n# @BRIEF Captures translation performance metrics at a point in time with config/content/dictionary hash keys for aggregation.\nclass MetricSnapshot(Base):\n __tablename__ = \"translation_metric_snapshots\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n job_id = Column(String, ForeignKey(\"translation_jobs.id\"), nullable=False, index=True)\n run_id = Column(String, ForeignKey(\"translation_runs.id\"), nullable=True, index=True)\n key_hash = Column(String, nullable=False, comment=\"Hash of dimension key fields for aggregation\")\n config_hash = Column(String, nullable=True, comment=\"Hash of translation configuration state\")\n dict_snapshot_hash = Column(String, nullable=True, comment=\"Hash of dictionary state at capture time\")\n covers_events_before = Column(DateTime, nullable=True, comment=\"Indicates snapshot covers events before this timestamp\")\n total_jobs = Column(Integer, default=0)\n total_runs = Column(Integer, default=0)\n total_records = Column(Integer, default=0)\n successful_records = Column(Integer, default=0)\n failed_records = Column(Integer, default=0)\n skipped_records = Column(Integer, default=0)\n avg_duration_ms = Column(Integer, nullable=True)\n p50_duration_ms = Column(Integer, nullable=True)\n p95_duration_ms = Column(Integer, nullable=True)\n p99_duration_ms = Column(Integer, nullable=True)\n per_language_metrics = Column(JSON, nullable=True, comment=\"Per-language cumulative metrics: {lang: {cumulative_tokens, cumulative_cost, runs}}\")\n snapshot_date = Column(DateTime, nullable=False, default=lambda: datetime.now(UTC))\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n\n __table_args__ = (\n Index(\"ix_metric_snapshots_job_date\", \"job_id\", \"snapshot_date\"),\n )\n# #endregion MetricSnapshot\n\n\n# #region TranslationLanguage [C:1] [TYPE Class]\n# @BRIEF Per-language translation result for a single record, supporting multi-language output.\nclass TranslationLanguage(Base):\n __tablename__ = \"translation_languages\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n record_id = Column(String, ForeignKey(\"translation_records.id\"), nullable=False)\n language_code = Column(String, nullable=False, comment=\"BCP-47 language code\")\n source_language_detected = Column(String, nullable=True, comment=\"BCP-47 or 'und' for undetermined\")\n translated_value = Column(Text, nullable=True, comment=\"LLM-generated translation\")\n user_edit = Column(Text, nullable=True, comment=\"User-edited translation\")\n final_value = Column(Text, nullable=True, comment=\"Final resolved value (translated or user edit)\")\n status = Column(String, default=\"pending\", comment=\"pending|translated|approved|edited|rejected|failed|skipped\")\n error_message = Column(Text, nullable=True)\n needs_review = Column(Boolean, default=False, comment=\"Flagged because source language could not be determined\")\n language_overridden = Column(Boolean, default=False, comment=\"Source language was manually overridden by user\")\n created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(UTC))\n\n record = relationship(\"TranslationRecord\", back_populates=\"languages\")\n\n __table_args__ = (\n UniqueConstraint(\"record_id\", \"language_code\", name=\"uq_record_language\"),\n Index(\"idx_tl_language\", \"language_code\"),\n Index(\"idx_tl_record_lang\", \"record_id\", \"language_code\"),\n )\n# #endregion TranslationLanguage\n\n\n# #region TranslationPreviewLanguage [C:1] [TYPE Class]\n# @BRIEF Per-language preview entry within a preview session.\nclass TranslationPreviewLanguage(Base):\n __tablename__ = \"translation_preview_languages\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n preview_record_id = Column(String, ForeignKey(\"translation_preview_records.id\"), nullable=False)\n language_code = Column(String, nullable=False, comment=\"BCP-47 language code\")\n source_language_detected = Column(String, nullable=True, comment=\"BCP-47 or 'und'\")\n translated_value = Column(Text, nullable=True)\n user_edit = Column(Text, nullable=True)\n final_value = Column(Text, nullable=True)\n status = Column(String, default=\"pending\", comment=\"pending|approved|edited|rejected\")\n needs_review = Column(Boolean, default=False, comment=\"Flagged because source language could not be determined\")\n created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(UTC))\n\n preview_record = relationship(\"TranslationPreviewRecord\", back_populates=\"languages\")\n\n __table_args__ = (\n UniqueConstraint(\"preview_record_id\", \"language_code\", name=\"uq_preview_record_language\"),\n )\n# #endregion TranslationPreviewLanguage\n\n\n# #region TranslationRunLanguageStats [C:1] [TYPE Class]\n# @BRIEF Per-language statistics for a translation run (row counts, tokens, cost).\nclass TranslationRunLanguageStats(Base):\n __tablename__ = \"translation_run_language_stats\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n run_id = Column(String, ForeignKey(\"translation_runs.id\"), nullable=False)\n language_code = Column(String, nullable=False, comment=\"BCP-47 language code\")\n total_rows = Column(Integer, default=0)\n translated_rows = Column(Integer, default=0)\n failed_rows = Column(Integer, default=0)\n skipped_rows = Column(Integer, default=0)\n token_count = Column(Integer, default=0)\n estimated_cost = Column(Float, default=0.0)\n\n run = relationship(\"TranslationRun\", back_populates=\"language_stats\")\n\n __table_args__ = (\n UniqueConstraint(\"run_id\", \"language_code\", name=\"uq_run_language\"),\n Index(\"idx_rls_run\", \"run_id\"),\n )\n# #endregion TranslationRunLanguageStats\n\n\n# #endregion TranslateModels\n" + "body": "# #region TranslateModels [C:3] [TYPE Module] [SEMANTICS sqlalchemy, translate, model, schema, dashboard, llm]\n# @BRIEF SQLAlchemy ORM models for LLM-based SQL/dashboard translation across dialects.\n# @LAYER: Domain\n# @RELATION INHERITS -> [MappingModels]\n\nimport uuid\nfrom datetime import UTC, datetime\n\nfrom sqlalchemy import JSON, Boolean, Column, DateTime, Float, ForeignKey, Index, Integer, String, Text, UniqueConstraint\nfrom sqlalchemy.orm import relationship\n\nfrom .mapping import Base\n\n\ndef generate_uuid():\n return str(uuid.uuid4())\n\n\n# #region TranslationJob [TYPE Class]\n# @BRIEF A translation job representing a multi-dialect conversion task with column mappings, LLM config, and dictionary attachments.\n# @RATIONALE: Snapshot isolation — in-progress runs use config snapshot; config edits affect future runs only.\n# @REJECTED: Invalidating in-progress runs on config edit would break scheduled run continuity.\nclass TranslationJob(Base):\n __tablename__ = \"translation_jobs\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n name = Column(String, nullable=False)\n description = Column(Text, nullable=True)\n source_dialect = Column(String, nullable=False)\n target_dialect = Column(String, nullable=False)\n database_dialect = Column(String, nullable=True, comment=\"Detected dialect from Superset connection at save time\")\n status = Column(String, nullable=False, default=\"DRAFT\") # DRAFT, READY, RUNNING, COMPLETED, FAILED, CANCELLED\n\n # Datasource & target table configuration\n source_datasource_id = Column(String, nullable=True, comment=\"Superset datasource ID\")\n source_table = Column(String, nullable=True, comment=\"Source table name resolved from datasource\")\n target_schema = Column(String, nullable=True, comment=\"Target table schema\")\n target_table = Column(String, nullable=True, comment=\"Target table name\")\n\n # Column mapping\n source_key_cols = Column(JSON, nullable=True, comment=\"Source key column names for composite key\")\n target_key_cols = Column(JSON, nullable=True, comment=\"Target key column names for composite key\")\n translation_column = Column(String, nullable=True, comment=\"Source column whose values will be translated\")\n target_column = Column(String, nullable=True, comment=\"Target column for translated output (defaults to translation_column)\")\n target_language_column = Column(String, nullable=True, comment=\"Target column for language code (e.g. 'ru', 'en')\")\n target_source_column = Column(String, nullable=True, comment=\"Target column for source/original text\")\n target_source_language_column = Column(String, nullable=True, comment=\"Target column for detected source language (BCP-47)\")\n context_columns = Column(JSON, nullable=True, comment=\"Context column names included in LLM prompt\")\n\n # LLM & processing settings\n # source_language removed — deprecated, auto-detected per row by LLM; use TranslationLanguage.source_language_detected instead\n target_languages = Column(JSON, nullable=True, comment=\"List of BCP-47 target language codes (multi-language support)\")\n provider_id = Column(String, nullable=True, comment=\"LLM provider ID\")\n batch_size = Column(Integer, nullable=False, default=50, comment=\"Records per batch\")\n disable_reasoning = Column(Boolean, default=False, comment=\"If true, pass reasoning_effort:none to LLM to save output tokens\")\n upsert_strategy = Column(String, nullable=False, default=\"MERGE\", comment=\"MERGE, INSERT, UPDATE\")\n\n # Environment association\n environment_id = Column(String, nullable=True, comment=\"Superset environment ID for datasource access\")\n target_database_id = Column(String, nullable=True, comment=\"Superset database ID for SQL Lab insert target\")\n\n created_by = Column(String, nullable=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n updated_at = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))\n# #endregion TranslationJob\n\n\n# #region TranslationRun [TYPE Class]\n# @BRIEF Represents a single execution of a translation job, capturing status, timing, and Superset execution metadata.\nclass TranslationRun(Base):\n __tablename__ = \"translation_runs\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n job_id = Column(String, ForeignKey(\"translation_jobs.id\"), nullable=False, index=True)\n status = Column(String, nullable=False, default=\"PENDING\") # PENDING, RUNNING, COMPLETED, FAILED, CANCELLED\n trigger_type = Column(String, nullable=True, comment=\"manual, scheduled, retry, baseline_expired\")\n started_at = Column(DateTime, nullable=True)\n completed_at = Column(DateTime, nullable=True)\n error_message = Column(Text, nullable=True)\n total_records = Column(Integer, default=0)\n successful_records = Column(Integer, default=0)\n failed_records = Column(Integer, default=0)\n skipped_records = Column(Integer, default=0)\n insert_status = Column(String, nullable=True, comment=\"Status of the Superset insert/update operation\")\n superset_execution_id = Column(String, nullable=True, comment=\"Superset execution/task ID\")\n superset_execution_log = Column(JSON, nullable=True, comment=\"Superset execution log output\")\n config_snapshot = Column(JSON, nullable=True, comment=\"Snapshot of job config at run creation time\")\n key_hash = Column(String, nullable=True, comment=\"Hash of source key fields for dedup\")\n config_hash = Column(String, nullable=True, comment=\"Hash of translation configuration state\")\n dict_snapshot_hash = Column(String, nullable=True, comment=\"Hash of dictionary state at run time\")\n created_by = Column(String, nullable=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n\n language_stats = relationship(\"TranslationRunLanguageStats\", back_populates=\"run\")\n# #endregion TranslationRun\n\n\n# #region TranslationBatch [TYPE Class]\n# @BRIEF Groups translation records within a run into manageable batches with timing and record counts.\nclass TranslationBatch(Base):\n __tablename__ = \"translation_batches\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n run_id = Column(String, ForeignKey(\"translation_runs.id\"), nullable=False, index=True)\n batch_index = Column(Integer, nullable=False)\n status = Column(String, nullable=False, default=\"PENDING\")\n total_records = Column(Integer, default=0)\n successful_records = Column(Integer, default=0)\n failed_records = Column(Integer, default=0)\n started_at = Column(DateTime, nullable=True)\n completed_at = Column(DateTime, nullable=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n# #endregion TranslationBatch\n\n\n# #region TranslationRecord [TYPE Class]\n# @BRIEF Individual translation result for a single SQL statement or dashboard element, tracking source, target, and error state.\nclass TranslationRecord(Base):\n __tablename__ = \"translation_records\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n batch_id = Column(String, ForeignKey(\"translation_batches.id\"), nullable=False, index=True)\n run_id = Column(String, ForeignKey(\"translation_runs.id\"), nullable=False, index=True)\n source_sql = Column(Text, nullable=True)\n target_sql = Column(Text, nullable=True)\n source_object_type = Column(String, nullable=True) # query, dashboard, chart, dataset\n source_object_id = Column(String, nullable=True)\n source_object_name = Column(String, nullable=True)\n source_data = Column(JSON, nullable=True, comment=\"Original source row key columns for upsert matching\")\n status = Column(String, nullable=False, default=\"PENDING\") # PENDING, SUCCESS, FAILED, SKIPPED\n error_message = Column(Text, nullable=True)\n token_count_input = Column(Integer, nullable=True)\n token_count_output = Column(Integer, nullable=True)\n translation_duration_ms = Column(Integer, nullable=True)\n source_hash = Column(String, nullable=True,\n comment=\"SHA256(source_text+context+dict_snapshot_hash+config_hash) for cache dedup — excludes key/identifier columns\")\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n\n languages = relationship(\"TranslationLanguage\", back_populates=\"record\")\n\n __table_args__ = (\n Index(\"ix_translation_records_run_status\", \"run_id\", \"status\"),\n Index(\"ix_translation_records_source_hash_status\", \"source_hash\", \"status\"),\n )\n# #endregion TranslationRecord\n\n\n# #region TranslationEvent [TYPE Class]\n# @BRIEF Audit/event log for translation operations, with optional run_id for context.\nclass TranslationEvent(Base):\n __tablename__ = \"translation_events\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n job_id = Column(String, ForeignKey(\"translation_jobs.id\"), nullable=False, index=True)\n run_id = Column(String, ForeignKey(\"translation_runs.id\"), nullable=True, index=True)\n event_type = Column(String, nullable=False) # JOB_CREATED, JOB_STARTED, JOB_COMPLETED, JOB_FAILED, etc.\n event_data = Column(JSON, nullable=True)\n created_by = Column(String, nullable=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n# #endregion TranslationEvent\n\n\n# #region TranslationPreviewSession [TYPE Class]\n# @BRIEF A preview session allowing users to review proposed translations before applying them.\nclass TranslationPreviewSession(Base):\n __tablename__ = \"translation_preview_sessions\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n job_id = Column(String, ForeignKey(\"translation_jobs.id\"), nullable=False, index=True)\n run_id = Column(String, ForeignKey(\"translation_runs.id\"), nullable=True)\n status = Column(String, nullable=False, default=\"ACTIVE\") # ACTIVE, APPLIED, DISCARDED, EXPIRED\n created_by = Column(String, nullable=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n expires_at = Column(DateTime, nullable=True)\n# #endregion TranslationPreviewSession\n\n\n# #region TranslationPreviewRecord [TYPE Class]\n# @BRIEF Individual preview entry within a preview session, showing original and translated content side by side.\nclass TranslationPreviewRecord(Base):\n __tablename__ = \"translation_preview_records\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n session_id = Column(String, ForeignKey(\"translation_preview_sessions.id\"), nullable=False, index=True)\n source_sql = Column(Text, nullable=True)\n target_sql = Column(Text, nullable=True)\n source_object_type = Column(String, nullable=True)\n source_object_id = Column(String, nullable=True)\n source_object_name = Column(String, nullable=True)\n source_data = Column(JSON, nullable=True, comment=\"Original source row key columns for upsert matching\")\n status = Column(String, nullable=False, default=\"PENDING\") # PENDING, APPROVED, REJECTED\n feedback = Column(Text, nullable=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n\n languages = relationship(\"TranslationPreviewLanguage\", back_populates=\"preview_record\")\n# #endregion TranslationPreviewRecord\n\n\n# #region TerminologyDictionary [TYPE Class]\n# @BRIEF A named collection of terminology mappings used during translation to ensure consistent term translation.\nclass TerminologyDictionary(Base):\n __tablename__ = \"terminology_dictionaries\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n name = Column(String, nullable=False)\n description = Column(Text, nullable=True)\n source_dialect = Column(String, nullable=False)\n target_dialect = Column(String, nullable=False)\n is_active = Column(Boolean, default=True)\n created_by = Column(String, nullable=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n updated_at = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))\n# #endregion TerminologyDictionary\n\n\n# #region DictionaryEntry [TYPE Class]\n# @BRIEF A single term mapping entry with case-insensitive unique constraint on source_term_normalized and origin tracking.\nclass DictionaryEntry(Base):\n __tablename__ = \"dictionary_entries\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n dictionary_id = Column(String, ForeignKey(\"terminology_dictionaries.id\"), nullable=False, index=True)\n source_term = Column(String, nullable=False)\n source_term_normalized = Column(String, nullable=False)\n target_term = Column(String, nullable=False)\n source_language = Column(String, nullable=False, comment=\"BCP-47 source language code\")\n target_language = Column(String, nullable=False, comment=\"BCP-47 target language code\")\n context_notes = Column(Text, nullable=True)\n context_data = Column(JSON, nullable=True, comment=\"Structured context for term usage\")\n usage_notes = Column(Text, nullable=True, comment=\"Usage guidance for the term mapping\")\n has_context = Column(Boolean, default=False, comment=\"Whether context_data is populated\")\n context_source = Column(String, nullable=True, comment=\"auto|auto_with_edits|manual|bulk\")\n origin_source_language = Column(String, nullable=True, comment=\"Original source language of the term\")\n origin_run_id = Column(String, nullable=True, comment=\"Run ID from which this correction originated\")\n origin_row_key = Column(String, nullable=True, comment=\"Row key within the run that triggered this correction\")\n origin_user_id = Column(String, nullable=True, comment=\"User who submitted the correction\")\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n updated_at = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))\n\n __table_args__ = (\n UniqueConstraint(\n \"dictionary_id\", \"source_term_normalized\", \"source_language\", \"target_language\",\n name=\"uq_dict_source_term_lang\"\n ),\n Index(\"idx_dict_entry_lang\", \"source_language\", \"target_language\"),\n Index(\"idx_dict_has_context\", \"has_context\"),\n )\n# #endregion DictionaryEntry\n\n\n# #region TranslationSchedule [TYPE Class]\n# @BRIEF Defines a cron-based schedule for recurring translation jobs.\nclass TranslationSchedule(Base):\n __tablename__ = \"translation_schedules\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n job_id = Column(String, ForeignKey(\"translation_jobs.id\"), nullable=False, index=True)\n cron_expression = Column(String, nullable=False)\n timezone = Column(String, nullable=False, default=\"UTC\")\n is_active = Column(Boolean, default=True)\n last_run_at = Column(DateTime, nullable=True)\n next_run_at = Column(DateTime, nullable=True)\n execution_mode = Column(String, nullable=False, default=\"full\", comment=\"full, new_key_only\")\n created_by = Column(String, nullable=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n updated_at = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))\n# #endregion TranslationSchedule\n\n\n# #region TranslationJobDictionary [TYPE Class]\n# @BRIEF Many-to-many association between translation jobs and terminology dictionaries.\nclass TranslationJobDictionary(Base):\n __tablename__ = \"translation_job_dictionaries\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n job_id = Column(String, ForeignKey(\"translation_jobs.id\"), nullable=False, index=True)\n dictionary_id = Column(String, ForeignKey(\"terminology_dictionaries.id\"), nullable=False, index=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n\n __table_args__ = (\n UniqueConstraint(\n \"job_id\", \"dictionary_id\",\n name=\"uq_job_dictionary\"\n ),\n )\n# #endregion TranslationJobDictionary\n\n\n# #region MetricSnapshot [TYPE Class]\n# @BRIEF Captures translation performance metrics at a point in time with config/content/dictionary hash keys for aggregation.\nclass MetricSnapshot(Base):\n __tablename__ = \"translation_metric_snapshots\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n job_id = Column(String, ForeignKey(\"translation_jobs.id\"), nullable=False, index=True)\n run_id = Column(String, ForeignKey(\"translation_runs.id\"), nullable=True, index=True)\n key_hash = Column(String, nullable=False, comment=\"Hash of dimension key fields for aggregation\")\n config_hash = Column(String, nullable=True, comment=\"Hash of translation configuration state\")\n dict_snapshot_hash = Column(String, nullable=True, comment=\"Hash of dictionary state at capture time\")\n covers_events_before = Column(DateTime, nullable=True, comment=\"Indicates snapshot covers events before this timestamp\")\n total_jobs = Column(Integer, default=0)\n total_runs = Column(Integer, default=0)\n total_records = Column(Integer, default=0)\n successful_records = Column(Integer, default=0)\n failed_records = Column(Integer, default=0)\n skipped_records = Column(Integer, default=0)\n avg_duration_ms = Column(Integer, nullable=True)\n p50_duration_ms = Column(Integer, nullable=True)\n p95_duration_ms = Column(Integer, nullable=True)\n p99_duration_ms = Column(Integer, nullable=True)\n per_language_metrics = Column(JSON, nullable=True, comment=\"Per-language cumulative metrics: {lang: {cumulative_tokens, cumulative_cost, runs}}\")\n snapshot_date = Column(DateTime, nullable=False, default=lambda: datetime.now(UTC))\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n\n __table_args__ = (\n Index(\"ix_metric_snapshots_job_date\", \"job_id\", \"snapshot_date\"),\n )\n# #endregion MetricSnapshot\n\n\n# #region TranslationLanguage [C:1] [TYPE Class]\n# @BRIEF Per-language translation result for a single record, supporting multi-language output.\nclass TranslationLanguage(Base):\n __tablename__ = \"translation_languages\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n record_id = Column(String, ForeignKey(\"translation_records.id\"), nullable=False)\n language_code = Column(String, nullable=False, comment=\"BCP-47 language code\")\n source_language_detected = Column(String, nullable=True, comment=\"BCP-47 or 'und' for undetermined\")\n translated_value = Column(Text, nullable=True, comment=\"LLM-generated translation\")\n user_edit = Column(Text, nullable=True, comment=\"User-edited translation\")\n final_value = Column(Text, nullable=True, comment=\"Final resolved value (translated or user edit)\")\n status = Column(String, default=\"pending\", comment=\"pending|translated|approved|edited|rejected|failed|skipped\")\n error_message = Column(Text, nullable=True)\n needs_review = Column(Boolean, default=False, comment=\"Flagged because source language could not be determined\")\n language_overridden = Column(Boolean, default=False, comment=\"Source language was manually overridden by user\")\n created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(UTC))\n\n record = relationship(\"TranslationRecord\", back_populates=\"languages\")\n\n __table_args__ = (\n UniqueConstraint(\"record_id\", \"language_code\", name=\"uq_record_language\"),\n Index(\"idx_tl_language\", \"language_code\"),\n Index(\"idx_tl_record_lang\", \"record_id\", \"language_code\"),\n )\n# #endregion TranslationLanguage\n\n\n# #region TranslationPreviewLanguage [C:1] [TYPE Class]\n# @BRIEF Per-language preview entry within a preview session.\nclass TranslationPreviewLanguage(Base):\n __tablename__ = \"translation_preview_languages\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n preview_record_id = Column(String, ForeignKey(\"translation_preview_records.id\"), nullable=False)\n language_code = Column(String, nullable=False, comment=\"BCP-47 language code\")\n source_language_detected = Column(String, nullable=True, comment=\"BCP-47 or 'und'\")\n translated_value = Column(Text, nullable=True)\n user_edit = Column(Text, nullable=True)\n final_value = Column(Text, nullable=True)\n status = Column(String, default=\"pending\", comment=\"pending|approved|edited|rejected\")\n needs_review = Column(Boolean, default=False, comment=\"Flagged because source language could not be determined\")\n created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(UTC))\n\n preview_record = relationship(\"TranslationPreviewRecord\", back_populates=\"languages\")\n\n __table_args__ = (\n UniqueConstraint(\"preview_record_id\", \"language_code\", name=\"uq_preview_record_language\"),\n )\n# #endregion TranslationPreviewLanguage\n\n\n# #region TranslationRunLanguageStats [C:1] [TYPE Class]\n# @BRIEF Per-language statistics for a translation run (row counts, tokens, cost).\nclass TranslationRunLanguageStats(Base):\n __tablename__ = \"translation_run_language_stats\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n run_id = Column(String, ForeignKey(\"translation_runs.id\"), nullable=False)\n language_code = Column(String, nullable=False, comment=\"BCP-47 language code\")\n total_rows = Column(Integer, default=0)\n translated_rows = Column(Integer, default=0)\n failed_rows = Column(Integer, default=0)\n skipped_rows = Column(Integer, default=0)\n token_count = Column(Integer, default=0)\n estimated_cost = Column(Float, default=0.0)\n\n run = relationship(\"TranslationRun\", back_populates=\"language_stats\")\n\n __table_args__ = (\n UniqueConstraint(\"run_id\", \"language_code\", name=\"uq_run_language\"),\n Index(\"idx_rls_run\", \"run_id\"),\n )\n# #endregion TranslationRunLanguageStats\n\n\n# #endregion TranslateModels\n" }, { "contract_id": "TranslationJob", @@ -47407,7 +47107,7 @@ "contract_type": "Class", "file_path": "backend/src/models/translate.py", "start_line": 116, - "end_line": 142, + "end_line": 145, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -47417,14 +47117,14 @@ "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslationRecord [TYPE Class]\n# @BRIEF Individual translation result for a single SQL statement or dashboard element, tracking source, target, and error state.\nclass TranslationRecord(Base):\n __tablename__ = \"translation_records\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n batch_id = Column(String, ForeignKey(\"translation_batches.id\"), nullable=False, index=True)\n run_id = Column(String, ForeignKey(\"translation_runs.id\"), nullable=False, index=True)\n source_sql = Column(Text, nullable=True)\n target_sql = Column(Text, nullable=True)\n source_object_type = Column(String, nullable=True) # query, dashboard, chart, dataset\n source_object_id = Column(String, nullable=True)\n source_object_name = Column(String, nullable=True)\n source_data = Column(JSON, nullable=True, comment=\"Original source row key columns for upsert matching\")\n status = Column(String, nullable=False, default=\"PENDING\") # PENDING, SUCCESS, FAILED, SKIPPED\n error_message = Column(Text, nullable=True)\n token_count_input = Column(Integer, nullable=True)\n token_count_output = Column(Integer, nullable=True)\n translation_duration_ms = Column(Integer, nullable=True)\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n\n languages = relationship(\"TranslationLanguage\", back_populates=\"record\")\n\n __table_args__ = (\n Index(\"ix_translation_records_run_status\", \"run_id\", \"status\"),\n )\n# #endregion TranslationRecord\n" + "body": "# #region TranslationRecord [TYPE Class]\n# @BRIEF Individual translation result for a single SQL statement or dashboard element, tracking source, target, and error state.\nclass TranslationRecord(Base):\n __tablename__ = \"translation_records\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n batch_id = Column(String, ForeignKey(\"translation_batches.id\"), nullable=False, index=True)\n run_id = Column(String, ForeignKey(\"translation_runs.id\"), nullable=False, index=True)\n source_sql = Column(Text, nullable=True)\n target_sql = Column(Text, nullable=True)\n source_object_type = Column(String, nullable=True) # query, dashboard, chart, dataset\n source_object_id = Column(String, nullable=True)\n source_object_name = Column(String, nullable=True)\n source_data = Column(JSON, nullable=True, comment=\"Original source row key columns for upsert matching\")\n status = Column(String, nullable=False, default=\"PENDING\") # PENDING, SUCCESS, FAILED, SKIPPED\n error_message = Column(Text, nullable=True)\n token_count_input = Column(Integer, nullable=True)\n token_count_output = Column(Integer, nullable=True)\n translation_duration_ms = Column(Integer, nullable=True)\n source_hash = Column(String, nullable=True,\n comment=\"SHA256(source_text+context+dict_snapshot_hash+config_hash) for cache dedup — excludes key/identifier columns\")\n created_at = Column(DateTime, default=lambda: datetime.now(UTC))\n\n languages = relationship(\"TranslationLanguage\", back_populates=\"record\")\n\n __table_args__ = (\n Index(\"ix_translation_records_run_status\", \"run_id\", \"status\"),\n Index(\"ix_translation_records_source_hash_status\", \"source_hash\", \"status\"),\n )\n# #endregion TranslationRecord\n" }, { "contract_id": "TranslationEvent", "contract_type": "Class", "file_path": "backend/src/models/translate.py", - "start_line": 145, - "end_line": 157, + "start_line": 148, + "end_line": 160, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -47440,8 +47140,8 @@ "contract_id": "TranslationPreviewSession", "contract_type": "Class", "file_path": "backend/src/models/translate.py", - "start_line": 160, - "end_line": 172, + "start_line": 163, + "end_line": 175, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -47457,8 +47157,8 @@ "contract_id": "TranslationPreviewRecord", "contract_type": "Class", "file_path": "backend/src/models/translate.py", - "start_line": 175, - "end_line": 193, + "start_line": 178, + "end_line": 196, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -47474,8 +47174,8 @@ "contract_id": "TerminologyDictionary", "contract_type": "Class", "file_path": "backend/src/models/translate.py", - "start_line": 196, - "end_line": 210, + "start_line": 199, + "end_line": 213, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -47491,8 +47191,8 @@ "contract_id": "DictionaryEntry", "contract_type": "Class", "file_path": "backend/src/models/translate.py", - "start_line": 213, - "end_line": 245, + "start_line": 216, + "end_line": 248, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -47508,8 +47208,8 @@ "contract_id": "TranslationSchedule", "contract_type": "Class", "file_path": "backend/src/models/translate.py", - "start_line": 248, - "end_line": 264, + "start_line": 251, + "end_line": 267, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -47525,8 +47225,8 @@ "contract_id": "TranslationJobDictionary", "contract_type": "Class", "file_path": "backend/src/models/translate.py", - "start_line": 267, - "end_line": 283, + "start_line": 270, + "end_line": 286, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -47542,8 +47242,8 @@ "contract_id": "MetricSnapshot", "contract_type": "Class", "file_path": "backend/src/models/translate.py", - "start_line": 286, - "end_line": 315, + "start_line": 289, + "end_line": 318, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -47559,8 +47259,8 @@ "contract_id": "TranslationLanguage", "contract_type": "Class", "file_path": "backend/src/models/translate.py", - "start_line": 318, - "end_line": 343, + "start_line": 321, + "end_line": 346, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -47577,8 +47277,8 @@ "contract_id": "TranslationPreviewLanguage", "contract_type": "Class", "file_path": "backend/src/models/translate.py", - "start_line": 346, - "end_line": 367, + "start_line": 349, + "end_line": 370, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -47595,8 +47295,8 @@ "contract_id": "TranslationRunLanguageStats", "contract_type": "Class", "file_path": "backend/src/models/translate.py", - "start_line": 370, - "end_line": 391, + "start_line": 373, + "end_line": 394, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -48126,7 +47826,7 @@ "contract_type": "Module", "file_path": "backend/src/plugins/llm_analysis/models.py", "start_line": 1, - "end_line": 64, + "end_line": 63, "tier": "TIER_2", "complexity": 3, "metadata": { @@ -48140,31 +47840,19 @@ "relation_type": "DEPENDS_ON", "target_id": "pydantic", "target_ref": "pydantic" - }, - { - "source_id": "LLMAnalysisModels", - "relation_type": "DEPENDS_on", - "target_id": "pydantic", - "target_ref": "pydantic" - }, - { - "source_id": "LLMAnalysisModels", - "relation_type": "DEPENDs_on", - "target_id": "pydantic", - "target_ref": "pydantic" } ], "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region LLMAnalysisModels [C:3] [TYPE Module] [SEMANTICS pydantic, llm, plugin, model, provider-type]\n# @BRIEF Define Pydantic models for LLM Analysis plugin.\n# @LAYER: Domain\n# @RELATION DEPENDS_ON -> pydantic\n# @RELATION DEPENDS_on -> pydantic\n# @RELATION DEPENDs_on -> pydantic\n\nfrom datetime import datetime\nfrom enum import Enum\n\nfrom pydantic import BaseModel, Field\n\n\n# #region LLMProviderType [TYPE Class]\n# @BRIEF Enum for supported LLM providers.\nclass LLMProviderType(str, Enum):\n OPENAI = \"openai\"\n OPENROUTER = \"openrouter\"\n KILO = \"kilo\"\n# #endregion LLMProviderType\n\n# #region LLMProviderConfig [TYPE Class]\n# @BRIEF Configuration for an LLM provider.\nclass LLMProviderConfig(BaseModel):\n id: str | None = None\n provider_type: LLMProviderType\n name: str\n base_url: str\n api_key: str | None = None\n default_model: str\n is_active: bool = True\n# #endregion LLMProviderConfig\n\n# #region ValidationStatus [TYPE Class]\n# @BRIEF Enum for dashboard validation status.\nclass ValidationStatus(str, Enum):\n PASS = \"PASS\"\n WARN = \"WARN\"\n FAIL = \"FAIL\"\n UNKNOWN = \"UNKNOWN\"\n# #endregion ValidationStatus\n\n# #region DetectedIssue [TYPE Class]\n# @BRIEF Model for a single issue detected during validation.\nclass DetectedIssue(BaseModel):\n severity: ValidationStatus\n message: str\n location: str | None = None\n# #endregion DetectedIssue\n\n# #region ValidationResult [TYPE Class]\n# @BRIEF Model for dashboard validation result.\nclass ValidationResult(BaseModel):\n id: str | None = None\n dashboard_id: str\n timestamp: datetime = Field(default_factory=datetime.utcnow)\n status: ValidationStatus\n screenshot_path: str | None = None\n issues: list[DetectedIssue]\n summary: str\n raw_response: str | None = None\n# #endregion ValidationResult\n\n# #endregion LLMAnalysisModels\n" + "body": "# #region LLMAnalysisModels [C:3] [TYPE Module] [SEMANTICS pydantic, llm, plugin, model, provider-type]\n# @BRIEF Define Pydantic models for LLM Analysis plugin.\n# @LAYER: Domain\n# @RELATION DEPENDS_ON -> pydantic\n\nfrom datetime import datetime\nfrom enum import Enum\n\nfrom pydantic import BaseModel, Field\n\n\n# #region LLMProviderType [TYPE Class]\n# @BRIEF Enum for supported LLM providers.\nclass LLMProviderType(str, Enum):\n OPENAI = \"openai\"\n OPENROUTER = \"openrouter\"\n KILO = \"kilo\"\n LITELLM = \"litellm\"\n# #endregion LLMProviderType\n\n# #region LLMProviderConfig [TYPE Class]\n# @BRIEF Configuration for an LLM provider.\nclass LLMProviderConfig(BaseModel):\n id: str | None = None\n provider_type: LLMProviderType\n name: str\n base_url: str\n api_key: str | None = None\n default_model: str\n is_active: bool = True\n# #endregion LLMProviderConfig\n\n# #region ValidationStatus [TYPE Class]\n# @BRIEF Enum for dashboard validation status.\nclass ValidationStatus(str, Enum):\n PASS = \"PASS\"\n WARN = \"WARN\"\n FAIL = \"FAIL\"\n UNKNOWN = \"UNKNOWN\"\n# #endregion ValidationStatus\n\n# #region DetectedIssue [TYPE Class]\n# @BRIEF Model for a single issue detected during validation.\nclass DetectedIssue(BaseModel):\n severity: ValidationStatus\n message: str\n location: str | None = None\n# #endregion DetectedIssue\n\n# #region ValidationResult [TYPE Class]\n# @BRIEF Model for dashboard validation result.\nclass ValidationResult(BaseModel):\n id: str | None = None\n dashboard_id: str\n timestamp: datetime = Field(default_factory=datetime.utcnow)\n status: ValidationStatus\n screenshot_path: str | None = None\n issues: list[DetectedIssue]\n summary: str\n raw_response: str | None = None\n# #endregion ValidationResult\n\n# #endregion LLMAnalysisModels\n" }, { "contract_id": "LLMProviderType", "contract_type": "Class", "file_path": "backend/src/plugins/llm_analysis/models.py", - "start_line": 14, - "end_line": 20, + "start_line": 12, + "end_line": 19, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -48174,14 +47862,14 @@ "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region LLMProviderType [TYPE Class]\n# @BRIEF Enum for supported LLM providers.\nclass LLMProviderType(str, Enum):\n OPENAI = \"openai\"\n OPENROUTER = \"openrouter\"\n KILO = \"kilo\"\n# #endregion LLMProviderType\n" + "body": "# #region LLMProviderType [TYPE Class]\n# @BRIEF Enum for supported LLM providers.\nclass LLMProviderType(str, Enum):\n OPENAI = \"openai\"\n OPENROUTER = \"openrouter\"\n KILO = \"kilo\"\n LITELLM = \"litellm\"\n# #endregion LLMProviderType\n" }, { "contract_id": "LLMProviderConfig", "contract_type": "Class", "file_path": "backend/src/plugins/llm_analysis/models.py", - "start_line": 22, - "end_line": 32, + "start_line": 21, + "end_line": 31, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -48197,8 +47885,8 @@ "contract_id": "ValidationStatus", "contract_type": "Class", "file_path": "backend/src/plugins/llm_analysis/models.py", - "start_line": 34, - "end_line": 41, + "start_line": 33, + "end_line": 40, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -48214,8 +47902,8 @@ "contract_id": "DetectedIssue", "contract_type": "Class", "file_path": "backend/src/plugins/llm_analysis/models.py", - "start_line": 43, - "end_line": 49, + "start_line": 42, + "end_line": 48, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -48231,8 +47919,8 @@ "contract_id": "ValidationResult", "contract_type": "Class", "file_path": "backend/src/plugins/llm_analysis/models.py", - "start_line": 51, - "end_line": 62, + "start_line": 50, + "end_line": 61, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -48543,7 +48231,7 @@ "contract_type": "Module", "file_path": "backend/src/plugins/llm_analysis/service.py", "start_line": 1, - "end_line": 978, + "end_line": 981, "tier": "TIER_2", "complexity": 3, "metadata": { @@ -48585,7 +48273,7 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region LLMAnalysisService [C:3] [TYPE Module] [SEMANTICS llm, screenshot, playwright, openai, tenacity]\n# @BRIEF Services for LLM interaction and dashboard screenshots.\n# @LAYER: Domain\n# @RELATION DEPENDS_ON -> playwright\n# @RELATION DEPENDS_ON -> openai\n# @RELATION DEPENDS_ON -> tenacity\n# @INVARIANT: Screenshots must be 1920px width and capture full page height.\n\nimport asyncio\nimport base64\nimport io\nimport json\nimport os\nfrom typing import Any\nfrom urllib.parse import urlsplit\n\nimport httpx\nfrom openai import AsyncOpenAI, RateLimitError\nfrom openai import AuthenticationError as OpenAIAuthenticationError\nfrom PIL import Image\nfrom playwright.async_api import async_playwright\nfrom tenacity import retry, retry_if_exception, stop_after_attempt, wait_exponential\n\nfrom ...core.config_models import Environment\nfrom ...core.logger import belief_scope, logger\nfrom ...services.llm_prompt_templates import DEFAULT_LLM_PROMPTS, render_prompt\nfrom .models import LLMProviderType\n\n\n# #region ScreenshotService [TYPE Class]\n# @BRIEF Handles capturing screenshots of Superset dashboards.\nclass ScreenshotService:\n # region ScreenshotService.__init__ [TYPE Function]\n # @PURPOSE: Initializes the ScreenshotService with environment configuration.\n # @PRE: env is a valid Environment object.\n def __init__(self, env: Environment):\n self.env = env\n # endregion ScreenshotService.__init__\n\n # region ScreenshotService._find_first_visible_locator [TYPE Function]\n # @PURPOSE: Resolve the first visible locator from multiple Playwright locator strategies.\n # @PRE: candidates is a non-empty list of locator-like objects.\n # @POST: Returns a locator ready for interaction or None when nothing matches.\n async def _find_first_visible_locator(self, candidates) -> Any:\n for locator in candidates:\n try:\n match_count = await locator.count()\n for index in range(match_count):\n candidate = locator.nth(index)\n if await candidate.is_visible():\n return candidate\n except Exception:\n continue\n return None\n # endregion ScreenshotService._find_first_visible_locator\n\n # region ScreenshotService._iter_login_roots [TYPE Function]\n # @PURPOSE: Enumerate page and child frames where login controls may be rendered.\n # @PRE: page is a Playwright page-like object.\n # @POST: Returns ordered roots starting with main page followed by frames.\n def _iter_login_roots(self, page) -> list[Any]:\n roots = [page]\n page_frames = getattr(page, \"frames\", [])\n try:\n for frame in page_frames:\n if frame not in roots:\n roots.append(frame)\n except Exception:\n pass\n return roots\n # endregion ScreenshotService._iter_login_roots\n\n # region ScreenshotService._extract_hidden_login_fields [TYPE Function]\n # @PURPOSE: Collect hidden form fields required for direct login POST fallback.\n # @PRE: Login page is loaded.\n # @POST: Returns hidden input name/value mapping aggregated from page and child frames.\n async def _extract_hidden_login_fields(self, page) -> dict[str, str]:\n hidden_fields: dict[str, str] = {}\n for root in self._iter_login_roots(page):\n try:\n locator = root.locator(\"input[type='hidden'][name]\")\n count = await locator.count()\n for index in range(count):\n candidate = locator.nth(index)\n field_name = str(await candidate.get_attribute(\"name\") or \"\").strip()\n if not field_name or field_name in hidden_fields:\n continue\n hidden_fields[field_name] = str(await candidate.input_value()).strip()\n except Exception:\n continue\n return hidden_fields\n # endregion ScreenshotService._extract_hidden_login_fields\n\n # region ScreenshotService._extract_csrf_token [TYPE Function]\n # @PURPOSE: Resolve CSRF token value from main page or embedded login frame.\n # @PRE: Login page is loaded.\n # @POST: Returns first non-empty csrf token or empty string.\n async def _extract_csrf_token(self, page) -> str:\n hidden_fields = await self._extract_hidden_login_fields(page)\n return str(hidden_fields.get(\"csrf_token\") or \"\").strip()\n # endregion ScreenshotService._extract_csrf_token\n\n # region ScreenshotService._response_looks_like_login_page [TYPE Function]\n # @PURPOSE: Detect when fallback login POST returned the login form again instead of an authenticated page.\n # @PRE: response_text is normalized HTML or text from login POST response.\n # @POST: Returns True when login-page markers dominate the response body.\n def _response_looks_like_login_page(self, response_text: str) -> bool:\n normalized = str(response_text or \"\").strip().lower()\n if not normalized:\n return False\n\n markers = [\n \"enter your login and password below\",\n \"username:\",\n \"password:\",\n \"sign in\",\n 'name=\"csrf_token\"',\n ]\n return sum(marker in normalized for marker in markers) >= 3\n # endregion ScreenshotService._response_looks_like_login_page\n\n # region ScreenshotService._redirect_looks_authenticated [TYPE Function]\n # @PURPOSE: Treat non-login redirects after form POST as successful authentication without waiting for redirect target.\n # @PRE: redirect_location may be empty or relative.\n # @POST: Returns True when redirect target does not point back to login flow.\n def _redirect_looks_authenticated(self, redirect_location: str) -> bool:\n normalized = str(redirect_location or \"\").strip().lower()\n if not normalized:\n return True\n return \"/login\" not in normalized\n # endregion ScreenshotService._redirect_looks_authenticated\n\n # region ScreenshotService._submit_login_via_form_post [TYPE Function]\n # @PURPOSE: Fallback login path that submits credentials directly with csrf token.\n # @PRE: login_url is same-origin and csrf token can be read from DOM.\n # @POST: Browser context receives authenticated cookies when login succeeds.\n async def _submit_login_via_form_post(self, page, login_url: str) -> bool:\n hidden_fields = await self._extract_hidden_login_fields(page)\n csrf_token = str(hidden_fields.get(\"csrf_token\") or \"\").strip()\n if not csrf_token:\n logger.warning(\"[DEBUG] Direct form login fallback skipped: csrf_token not found\")\n return False\n\n try:\n request_context = page.context.request\n except Exception as context_error:\n logger.warning(f\"[DEBUG] Direct form login fallback skipped: request context unavailable: {context_error}\")\n return False\n\n parsed_url = urlsplit(login_url)\n origin = f\"{parsed_url.scheme}://{parsed_url.netloc}\" if parsed_url.scheme and parsed_url.netloc else login_url\n payload = dict(hidden_fields)\n payload[\"username\"] = self.env.username\n payload[\"password\"] = self.env.password\n logger.info(\n f\"[DEBUG] Attempting direct form login fallback via browser context request with hidden fields: {sorted(hidden_fields.keys())}\"\n )\n\n response = await request_context.post(\n login_url,\n form=payload,\n headers={\n \"Origin\": origin,\n \"Referer\": login_url,\n },\n timeout=10000,\n fail_on_status_code=False,\n max_redirects=0,\n )\n response_url = str(getattr(response, \"url\", \"\") or \"\")\n response_status = int(getattr(response, \"status\", 0) or 0)\n response_headers = dict(getattr(response, \"headers\", {}) or {})\n redirect_location = str(\n response_headers.get(\"location\")\n or response_headers.get(\"Location\")\n or \"\"\n ).strip()\n redirect_statuses = {301, 302, 303, 307, 308}\n if response_status in redirect_statuses:\n redirect_authenticated = self._redirect_looks_authenticated(redirect_location)\n logger.info(\n f\"[DEBUG] Direct form login fallback redirect response: status={response_status} url={response_url} location={redirect_location!r} authenticated={redirect_authenticated}\"\n )\n return redirect_authenticated\n\n response_text = await response.text()\n text_snippet = \" \".join(response_text.split())[:200]\n looks_like_login_page = self._response_looks_like_login_page(response_text)\n logger.info(\n f\"[DEBUG] Direct form login fallback response: status={response_status} url={response_url} login_markup={looks_like_login_page} snippet={text_snippet!r}\"\n )\n return not looks_like_login_page\n # endregion ScreenshotService._submit_login_via_form_post\n\n # region ScreenshotService._find_login_field_locator [TYPE Function]\n # @PURPOSE: Resolve login form input using semantic label text plus generic visible-input fallbacks.\n # @PRE: field_name is `username` or `password`.\n # @POST: Returns a locator for the corresponding input or None.\n async def _find_login_field_locator(self, page, field_name: str) -> Any:\n normalized = str(field_name or \"\").strip().lower()\n for root in self._iter_login_roots(page):\n if normalized == \"username\":\n input_candidates = [\n root.get_by_label(\"Username\", exact=False),\n root.get_by_label(\"Login\", exact=False),\n root.locator(\"label:text-matches('Username|Login', 'i')\").locator(\"xpath=following::input[1]\"),\n root.locator(\"text=/Username|Login/i\").locator(\"xpath=following::input[1]\"),\n root.locator(\"input[name='username']\"),\n root.locator(\"input#username\"),\n root.locator(\"input[placeholder*='Username']\"),\n root.locator(\"input[type='text']\"),\n root.locator(\"input:not([type='password'])\"),\n ]\n locator = await self._find_first_visible_locator(input_candidates)\n if locator:\n return locator\n\n if normalized == \"password\":\n input_candidates = [\n root.get_by_label(\"Password\", exact=False),\n root.locator(\"label:text-matches('Password', 'i')\").locator(\"xpath=following::input[1]\"),\n root.locator(\"text=/Password/i\").locator(\"xpath=following::input[1]\"),\n root.locator(\"input[name='password']\"),\n root.locator(\"input#password\"),\n root.locator(\"input[placeholder*='Password']\"),\n root.locator(\"input[type='password']\"),\n ]\n locator = await self._find_first_visible_locator(input_candidates)\n if locator:\n return locator\n\n return None\n # endregion ScreenshotService._find_login_field_locator\n\n # region ScreenshotService._find_submit_locator [TYPE Function]\n # @PURPOSE: Resolve login submit button from main page or embedded auth frame.\n # @PRE: page is ready for login interaction.\n # @POST: Returns visible submit locator or None.\n async def _find_submit_locator(self, page) -> Any:\n selectors = [\n lambda root: root.get_by_role(\"button\", name=\"Sign in\", exact=False),\n lambda root: root.get_by_role(\"button\", name=\"Login\", exact=False),\n lambda root: root.locator(\"button[type='submit']\"),\n lambda root: root.locator(\"button#submit\"),\n lambda root: root.locator(\".btn-primary\"),\n lambda root: root.locator(\"input[type='submit']\"),\n ]\n for root in self._iter_login_roots(page):\n locator = await self._find_first_visible_locator([factory(root) for factory in selectors])\n if locator:\n return locator\n return None\n # endregion ScreenshotService._find_submit_locator\n\n # region ScreenshotService._goto_resilient [TYPE Function]\n # @PURPOSE: Navigate without relying on networkidle for pages with long-polling or persistent requests.\n # @PRE: page is a valid Playwright page and url is non-empty.\n # @POST: Returns last navigation response or raises when both primary and fallback waits fail.\n async def _goto_resilient(\n self,\n page,\n url: str,\n primary_wait_until: str = \"domcontentloaded\",\n fallback_wait_until: str = \"load\",\n timeout: int = 60000,\n ):\n try:\n return await page.goto(url, wait_until=primary_wait_until, timeout=timeout)\n except Exception as primary_error:\n logger.warning(\n f\"[ScreenshotService._goto_resilient] Primary navigation wait '{primary_wait_until}' failed for {url}: {primary_error}\"\n )\n return await page.goto(url, wait_until=fallback_wait_until, timeout=timeout)\n # endregion ScreenshotService._goto_resilient\n\n # region ScreenshotService.capture_dashboard [TYPE Function]\n # @PURPOSE: Captures a full-page screenshot of a dashboard using Playwright and CDP.\n # @PRE: dashboard_id is a valid string, output_path is a writable path.\n # @POST: Returns True if screenshot is saved successfully.\n # @SIDE_EFFECT: Launches a browser, performs UI login, switches tabs, and writes a PNG file.\n # @UX_STATE: [Navigating] -> Loading dashboard UI\n # @UX_STATE: [TabSwitching] -> Iterating through dashboard tabs to trigger lazy loading\n # @UX_STATE: [CalculatingHeight] -> Determining dashboard dimensions\n # @UX_STATE: [Capturing] -> Executing CDP screenshot\n async def capture_dashboard(self, dashboard_id: str, output_path: str) -> bool:\n with belief_scope(\"capture_dashboard\", f\"dashboard_id={dashboard_id}\"):\n logger.info(f\"Capturing screenshot for dashboard {dashboard_id}\")\n async with async_playwright() as p:\n browser = await p.chromium.launch(\n headless=True,\n args=[\n \"--disable-blink-features=AutomationControlled\",\n \"--disable-infobars\",\n \"--no-sandbox\"\n ]\n )\n # Set a realistic user agent to avoid 403 Forbidden from OpenResty/WAF\n user_agent = \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36\"\n # Construct base UI URL from environment (strip /api/v1 suffix)\n base_ui_url = self.env.url.rstrip(\"/\")\n if base_ui_url.endswith(\"/api/v1\"):\n base_ui_url = base_ui_url[:-len(\"/api/v1\")]\n\n # Create browser context with realistic headers\n context = await browser.new_context(\n viewport={'width': 1280, 'height': 720},\n user_agent=user_agent,\n extra_http_headers={\n \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7\",\n \"Accept-Language\": \"ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7\",\n \"Upgrade-Insecure-Requests\": \"1\",\n \"Sec-Fetch-Dest\": \"document\",\n \"Sec-Fetch-Mode\": \"navigate\",\n \"Sec-Fetch-Site\": \"none\",\n \"Sec-Fetch-User\": \"?1\"\n }\n )\n logger.info(\"Browser context created successfully\")\n\n page = await context.new_page()\n # Bypass navigator.webdriver detection\n await page.add_init_script(\"delete Object.getPrototypeOf(navigator).webdriver\")\n\n # 1. Navigate to login page and authenticate\n login_url = f\"{base_ui_url.rstrip('/')}/login/\"\n logger.info(f\"[DEBUG] Navigating to login page: {login_url}\")\n\n response = await self._goto_resilient(\n page,\n login_url,\n primary_wait_until=\"domcontentloaded\",\n fallback_wait_until=\"load\",\n timeout=60000,\n )\n if response:\n logger.info(f\"[DEBUG] Login page response status: {response.status}\")\n\n # Wait for login form to be ready\n await page.wait_for_load_state(\"domcontentloaded\")\n\n # More exhaustive list of selectors for various Superset versions/themes\n selectors = {\n \"username\": ['input[name=\"username\"]', 'input#username', 'input[placeholder*=\"Username\"]', 'input[type=\"text\"]'],\n \"password\": ['input[name=\"password\"]', 'input#password', 'input[placeholder*=\"Password\"]', 'input[type=\"password\"]'],\n \"submit\": ['button[type=\"submit\"]', 'button#submit', '.btn-primary', 'input[type=\"submit\"]']\n }\n logger.info(\"[DEBUG] Attempting to find login form elements...\")\n\n try:\n used_direct_form_login = False\n # Find and fill username\n username_locator = await self._find_login_field_locator(page, \"username\")\n\n if not username_locator:\n roots = self._iter_login_roots(page)\n logger.info(f\"[DEBUG] Found {len(roots)} login roots including child frames\")\n for root_index, root in enumerate(roots[:5]):\n all_inputs = await root.locator('input').all()\n logger.info(f\"[DEBUG] Root {root_index}: found {len(all_inputs)} input fields\")\n for i, inp in enumerate(all_inputs[:5]): # Log first 5\n inp_type = await inp.get_attribute('type')\n inp_name = await inp.get_attribute('name')\n inp_id = await inp.get_attribute('id')\n logger.info(f\"[DEBUG] Root {root_index} input {i}: type={inp_type}, name={inp_name}, id={inp_id}\")\n used_direct_form_login = await self._submit_login_via_form_post(page, login_url)\n if not used_direct_form_login:\n raise RuntimeError(\"Could not find username input field on login page\")\n username_locator = None\n\n if username_locator is not None:\n logger.info(\"[DEBUG] Filling username field\")\n await username_locator.fill(self.env.username)\n\n # Find and fill password\n password_locator = await self._find_login_field_locator(page, \"password\") if username_locator is not None else None\n\n if username_locator is not None and not password_locator:\n raise RuntimeError(\"Could not find password input field on login page\")\n\n if password_locator is not None:\n logger.info(\"[DEBUG] Filling password field\")\n await password_locator.fill(self.env.password)\n\n # Click submit\n submit_locator = await self._find_submit_locator(page) if username_locator is not None else None\n\n if username_locator is not None and not submit_locator:\n raise RuntimeError(\"Could not find submit button on login page\")\n\n if submit_locator is not None:\n logger.info(\"[DEBUG] Clicking submit button\")\n await submit_locator.click()\n\n # Wait for navigation after login\n if not used_direct_form_login:\n try:\n await page.wait_for_load_state(\"load\", timeout=30000)\n except Exception as load_wait_error:\n logger.warning(f\"[DEBUG] Login post-submit load wait timed out: {load_wait_error}\")\n\n # Check if login was successful\n if not used_direct_form_login and \"/login\" in page.url:\n # Check for error messages on page\n error_msg = await page.locator(\".alert-danger, .error-message\").text_content() if await page.locator(\".alert-danger, .error-message\").count() > 0 else \"Unknown error\"\n logger.error(f\"[DEBUG] Login failed. Still on login page. Error: {error_msg}\")\n debug_path = output_path.replace(\".png\", \"_debug_failed_login.png\")\n await page.screenshot(path=debug_path)\n raise RuntimeError(f\"Login failed: {error_msg}. Debug screenshot saved to {debug_path}\")\n\n logger.info(f\"[DEBUG] Login successful. Current URL: {page.url}\")\n\n # Check cookies after successful login\n page_cookies = await context.cookies()\n logger.info(f\"[DEBUG] Cookies after login: {len(page_cookies)}\")\n for c in page_cookies:\n logger.info(f\"[DEBUG] Cookie: name={c['name']}, domain={c['domain']}, value={c.get('value', '')[:20]}...\")\n\n except Exception as e:\n page_title = await page.title()\n logger.error(f\"UI Login failed. Page title: {page_title}, URL: {page.url}, Error: {e!s}\")\n debug_path = output_path.replace(\".png\", \"_debug_failed_login.png\")\n await page.screenshot(path=debug_path)\n raise RuntimeError(f\"Login failed: {e!s}. Debug screenshot saved to {debug_path}\")\n\n # 2. Navigate to dashboard\n # @UX_STATE: [Navigating] -> Loading dashboard UI\n dashboard_url = f\"{base_ui_url.rstrip('/')}/superset/dashboard/{dashboard_id}/?standalone=true\"\n\n if base_ui_url.startswith(\"https://\") and dashboard_url.startswith(\"http://\"):\n dashboard_url = dashboard_url.replace(\"http://\", \"https://\")\n\n logger.info(f\"[DEBUG] Navigating to dashboard: {dashboard_url}\")\n\n # Dashboard pages can keep polling/network activity open indefinitely.\n response = await self._goto_resilient(\n page,\n dashboard_url,\n primary_wait_until=\"domcontentloaded\",\n fallback_wait_until=\"load\",\n timeout=60000,\n )\n\n if response:\n logger.info(f\"[DEBUG] Dashboard navigation response status: {response.status}, URL: {response.url}\")\n\n if \"/login\" in page.url:\n debug_path = output_path.replace(\".png\", \"_debug_failed_dashboard_auth.png\")\n await page.screenshot(path=debug_path)\n raise RuntimeError(\n f\"Dashboard navigation redirected to login page after authentication. Debug screenshot saved to {debug_path}\"\n )\n\n try:\n # Wait for the dashboard grid to be present\n await page.wait_for_selector('.dashboard-component, .dashboard-header, [data-test=\"dashboard-grid\"]', timeout=30000)\n logger.info(\"[DEBUG] Dashboard container loaded\")\n\n # Wait for charts to finish loading (Superset uses loading spinners/skeletons)\n # We wait until loading indicators disappear or a timeout occurs\n try:\n # Wait for loading indicators to disappear\n await page.wait_for_selector('.loading, .ant-skeleton, .spinner', state=\"hidden\", timeout=60000)\n logger.info(\"[DEBUG] Loading indicators hidden\")\n except Exception:\n logger.warning(\"[DEBUG] Timeout waiting for loading indicators to hide\")\n\n # Wait for charts to actually render their content (e.g., ECharts, NVD3)\n # We look for common chart containers that should have content\n try:\n await page.wait_for_selector('.chart-container canvas, .slice_container svg, .superset-chart-canvas, .grid-content .chart-container', timeout=60000)\n logger.info(\"[DEBUG] Chart content detected\")\n except Exception:\n logger.warning(\"[DEBUG] Timeout waiting for chart content\")\n\n # Additional check: wait for all chart containers to have non-empty content\n logger.info(\"[DEBUG] Waiting for all charts to have rendered content...\")\n await page.wait_for_function(\"\"\"() => {\n const charts = document.querySelectorAll('.chart-container, .slice_container');\n if (charts.length === 0) return true; // No charts to wait for\n \n // Check if all charts have rendered content (canvas, svg, or non-empty div)\n return Array.from(charts).every(chart => {\n const hasCanvas = chart.querySelector('canvas') !== null;\n const hasSvg = chart.querySelector('svg') !== null;\n const hasContent = chart.innerText.trim().length > 0 || chart.children.length > 0;\n return hasCanvas || hasSvg || hasContent;\n });\n }\"\"\", timeout=60000)\n logger.info(\"[DEBUG] All charts have rendered content\")\n\n # Scroll to bottom and back to top to trigger lazy loading of all charts\n logger.info(\"[DEBUG] Scrolling to trigger lazy loading...\")\n await page.evaluate(\"\"\"async () => {\n const delay = ms => new Promise(resolve => setTimeout(resolve, ms));\n for (let i = 0; i < document.body.scrollHeight; i += 500) {\n window.scrollTo(0, i);\n await delay(100);\n }\n window.scrollTo(0, 0);\n await delay(500);\n }\"\"\")\n\n except Exception as e:\n logger.warning(f\"[DEBUG] Dashboard content wait failed: {e}, proceeding anyway after delay\")\n\n # Final stabilization delay - increased for complex dashboards\n logger.info(\"[DEBUG] Final stabilization delay...\")\n await asyncio.sleep(15)\n\n # Logic to handle tabs and full-page capture\n try:\n # 1. Handle Tabs (Recursive switching)\n # @UX_STATE: [TabSwitching] -> Iterating through dashboard tabs to trigger lazy loading\n processed_tabs = set()\n\n async def switch_tabs(depth=0):\n if depth > 3:\n return # Limit recursion depth\n\n tab_selectors = [\n '.ant-tabs-nav-list .ant-tabs-tab',\n '.dashboard-component-tabs .ant-tabs-tab',\n '[data-test=\"dashboard-component-tabs\"] .ant-tabs-tab'\n ]\n\n found_tabs = []\n for selector in tab_selectors:\n found_tabs = await page.locator(selector).all()\n if found_tabs:\n break\n\n if found_tabs:\n logger.info(f\"[DEBUG][TabSwitching] Found {len(found_tabs)} tabs at depth {depth}\")\n for i, tab in enumerate(found_tabs):\n try:\n tab_text = (await tab.inner_text()).strip()\n tab_id = f\"{depth}_{i}_{tab_text}\"\n\n if tab_id in processed_tabs:\n continue\n\n if await tab.is_visible():\n logger.info(f\"[DEBUG][TabSwitching] Switching to tab: {tab_text}\")\n processed_tabs.add(tab_id)\n\n is_active = \"ant-tabs-tab-active\" in (await tab.get_attribute(\"class\") or \"\")\n if not is_active:\n await tab.click()\n await asyncio.sleep(2) # Wait for content to render\n\n await switch_tabs(depth + 1)\n except Exception as tab_e:\n logger.warning(f\"[DEBUG][TabSwitching] Failed to process tab {i}: {tab_e}\")\n\n try:\n first_tab = found_tabs[0]\n if \"ant-tabs-tab-active\" not in (await first_tab.get_attribute(\"class\") or \"\"):\n await first_tab.click()\n await asyncio.sleep(1)\n except Exception:\n pass\n\n await switch_tabs()\n\n # 2. Calculate full height for screenshot\n # @UX_STATE: [CalculatingHeight] -> Determining dashboard dimensions\n full_height = await page.evaluate(\"\"\"() => {\n const body = document.body;\n const html = document.documentElement;\n const dashboardContent = document.querySelector('.dashboard-content');\n \n return Math.max(\n body.scrollHeight, body.offsetHeight,\n html.clientHeight, html.scrollHeight, html.offsetHeight,\n dashboardContent ? dashboardContent.scrollHeight + 100 : 0\n );\n }\"\"\")\n logger.info(f\"[DEBUG] Calculated full height: {full_height}\")\n\n # DIAGNOSTIC: Count chart elements before resize\n chart_count_before = await page.evaluate(\"\"\"() => {\n return {\n chartContainers: document.querySelectorAll('.chart-container, .slice_container').length,\n canvasElements: document.querySelectorAll('canvas').length,\n svgElements: document.querySelectorAll('.chart-container svg, .slice_container svg').length,\n visibleCharts: document.querySelectorAll('.chart-container:visible, .slice_container:visible').length\n };\n }\"\"\")\n logger.info(f\"[DIAGNOSTIC] Chart elements BEFORE viewport resize: {chart_count_before}\")\n\n # DIAGNOSTIC: Capture pre-resize screenshot for comparison\n pre_resize_path = output_path.replace(\".png\", \"_preresize.png\")\n try:\n await page.screenshot(path=pre_resize_path, full_page=False, timeout=10000)\n import os\n pre_resize_size = os.path.getsize(pre_resize_path) if os.path.exists(pre_resize_path) else 0\n logger.info(f\"[DIAGNOSTIC] Pre-resize screenshot saved: {pre_resize_path} ({pre_resize_size} bytes)\")\n except Exception as pre_e:\n logger.warning(f\"[DIAGNOSTIC] Failed to capture pre-resize screenshot: {pre_e}\")\n\n logger.info(f\"[DIAGNOSTIC] Resizing viewport from current to 1920x{int(full_height)}\")\n await page.set_viewport_size({\"width\": 1920, \"height\": int(full_height)})\n\n # DIAGNOSTIC: Increased wait time and log timing\n logger.info(\"[DIAGNOSTIC] Waiting 10 seconds after viewport resize for re-render...\")\n await asyncio.sleep(10)\n logger.info(\"[DIAGNOSTIC] Wait completed\")\n\n # DIAGNOSTIC: Count chart elements after resize and wait\n chart_count_after = await page.evaluate(\"\"\"() => {\n return {\n chartContainers: document.querySelectorAll('.chart-container, .slice_container').length,\n canvasElements: document.querySelectorAll('canvas').length,\n svgElements: document.querySelectorAll('.chart-container svg, .slice_container svg').length,\n visibleCharts: document.querySelectorAll('.chart-container:visible, .slice_container:visible').length\n };\n }\"\"\")\n logger.info(f\"[DIAGNOSTIC] Chart elements AFTER viewport resize + wait: {chart_count_after}\")\n\n # DIAGNOSTIC: Check if any charts have error states\n chart_errors = await page.evaluate(\"\"\"() => {\n const errors = [];\n document.querySelectorAll('.chart-container, .slice_container').forEach((chart, i) => {\n const errorEl = chart.querySelector('.error, .alert-danger, .ant-alert-error');\n if (errorEl) {\n errors.push({index: i, text: errorEl.innerText.substring(0, 100)});\n }\n });\n return errors;\n }\"\"\")\n if chart_errors:\n logger.warning(f\"[DIAGNOSTIC] Charts with error states detected: {chart_errors}\")\n else:\n logger.info(\"[DIAGNOSTIC] No chart error states detected\")\n\n # 3. Take screenshot using CDP to bypass Playwright's font loading wait\n # @UX_STATE: [Capturing] -> Executing CDP screenshot\n logger.info(\"[DEBUG] Attempting full-page screenshot via CDP...\")\n cdp = await page.context.new_cdp_session(page)\n\n screenshot_data = await cdp.send(\"Page.captureScreenshot\", {\n \"format\": \"png\",\n \"fromSurface\": True,\n \"captureBeyondViewport\": True\n })\n\n image_data = base64.b64decode(screenshot_data[\"data\"])\n\n with open(output_path, 'wb') as f:\n f.write(image_data)\n\n # DIAGNOSTIC: Verify screenshot file\n import os\n final_size = os.path.getsize(output_path) if os.path.exists(output_path) else 0\n logger.info(f\"[DIAGNOSTIC] Final screenshot saved: {output_path}\")\n logger.info(f\"[DIAGNOSTIC] Final screenshot size: {final_size} bytes ({final_size / 1024:.2f} KB)\")\n\n # DIAGNOSTIC: Get image dimensions\n try:\n with Image.open(output_path) as final_img:\n logger.info(f\"[DIAGNOSTIC] Final screenshot dimensions: {final_img.width}x{final_img.height}\")\n except Exception as img_err:\n logger.warning(f\"[DIAGNOSTIC] Could not read final image dimensions: {img_err}\")\n\n logger.info(f\"Full-page screenshot saved to {output_path} (via CDP)\")\n except Exception as e:\n logger.error(f\"[DEBUG] Full-page/Tab capture failed: {e}\")\n try:\n await page.screenshot(path=output_path, full_page=True, timeout=10000)\n except Exception as e2:\n logger.error(f\"[DEBUG] Fallback screenshot also failed: {e2}\")\n await page.screenshot(path=output_path, timeout=5000)\n\n await browser.close()\n return True\n # endregion ScreenshotService.capture_dashboard\n# #endregion ScreenshotService\n\n# #region LLMClient [TYPE Class]\n# @BRIEF Wrapper for LLM provider APIs.\nclass LLMClient:\n # region LLMClient.__init__ [TYPE Function]\n # @PURPOSE: Initializes the LLMClient with provider settings.\n # @PRE: api_key, base_url, and default_model are non-empty strings.\n def __init__(self, provider_type: LLMProviderType, api_key: str, base_url: str, default_model: str):\n self.provider_type = provider_type\n normalized_key = (api_key or \"\").strip()\n if normalized_key.lower().startswith(\"bearer \"):\n normalized_key = normalized_key[7:].strip()\n self.api_key = normalized_key\n self.base_url = base_url\n self.default_model = default_model\n\n # DEBUG: Log initialization parameters (without exposing full API key)\n logger.info(\"[LLMClient.__init__] Initializing LLM client:\")\n logger.info(f\"[LLMClient.__init__] Provider Type: {provider_type}\")\n logger.info(f\"[LLMClient.__init__] Base URL: {base_url}\")\n logger.info(f\"[LLMClient.__init__] Default Model: {default_model}\")\n logger.info(f\"[LLMClient.__init__] API Key (first 8 chars): {self.api_key[:8] if self.api_key and len(self.api_key) > 8 else 'EMPTY_OR_NONE'}...\")\n logger.info(f\"[LLMClient.__init__] API Key Length: {len(self.api_key) if self.api_key else 0}\")\n\n # Some OpenAI-compatible gateways are strict about auth header naming.\n default_headers = {\"Authorization\": f\"Bearer {self.api_key}\"}\n if self.provider_type == LLMProviderType.OPENROUTER:\n default_headers[\"HTTP-Referer\"] = (\n os.getenv(\"OPENROUTER_SITE_URL\", \"\").strip()\n or os.getenv(\"APP_BASE_URL\", \"\").strip()\n or \"http://localhost:8000\"\n )\n default_headers[\"X-Title\"] = os.getenv(\"OPENROUTER_APP_NAME\", \"\").strip() or \"ss-tools\"\n if self.provider_type == LLMProviderType.KILO:\n default_headers[\"Authentication\"] = f\"Bearer {self.api_key}\"\n default_headers[\"X-API-Key\"] = self.api_key\n\n http_client = httpx.AsyncClient(headers=default_headers, timeout=120.0)\n self.client = AsyncOpenAI(\n api_key=self.api_key,\n base_url=base_url,\n default_headers=default_headers,\n http_client=http_client,\n )\n # endregion LLMClient.__init__\n\n # region LLMClient._supports_json_response_format [TYPE Function]\n # @PURPOSE: Detect whether provider/model is likely compatible with response_format=json_object.\n # @PRE: Client initialized with base_url and default_model.\n # @POST: Returns False for known-incompatible combinations to avoid avoidable 400 errors.\n def _supports_json_response_format(self) -> bool:\n base = (self.base_url or \"\").lower()\n model = (self.default_model or \"\").lower()\n\n # OpenRouter routes to many upstream providers; some models reject json_object mode.\n if \"openrouter.ai\" in base:\n incompatible_tokens = (\n \"stepfun/\",\n \"step-\",\n \":free\",\n )\n if any(token in model for token in incompatible_tokens):\n return False\n return True\n # endregion LLMClient._supports_json_response_format\n\n # region LLMClient.get_json_completion [TYPE Function]\n # @PURPOSE: Helper to handle LLM calls with JSON mode and fallback parsing.\n # @PRE: messages is a list of valid message dictionaries.\n # @POST: Returns a parsed JSON dictionary.\n # @SIDE_EFFECT: Calls external LLM API.\n def _should_retry(exception: Exception) -> bool:\n \"\"\"Custom retry predicate that excludes authentication errors.\"\"\"\n # Don't retry on authentication errors\n if isinstance(exception, OpenAIAuthenticationError):\n return False\n # Retry on rate limit errors and other exceptions\n return isinstance(exception, (RateLimitError, Exception))\n\n @retry(\n stop=stop_after_attempt(5),\n wait=wait_exponential(multiplier=2, min=5, max=60),\n retry=retry_if_exception(_should_retry),\n reraise=True\n )\n async def get_json_completion(self, messages: list[dict[str, Any]]) -> dict[str, Any]:\n with belief_scope(\"get_json_completion\"):\n response = None\n try:\n use_json_mode = self._supports_json_response_format()\n try:\n logger.info(\n f\"[get_json_completion] Attempting LLM call for model: {self.default_model} \"\n f\"(json_mode={'on' if use_json_mode else 'off'})\"\n )\n logger.info(f\"[get_json_completion] Base URL being used: {self.base_url}\")\n logger.info(f\"[get_json_completion] Number of messages: {len(messages)}\")\n logger.info(f\"[get_json_completion] API Key present: {bool(self.api_key and len(self.api_key) > 0)}\")\n\n if use_json_mode:\n response = await self.client.chat.completions.create(\n model=self.default_model,\n messages=messages,\n response_format={\"type\": \"json_object\"}\n )\n else:\n response = await self.client.chat.completions.create(\n model=self.default_model,\n messages=messages\n )\n except Exception as e:\n if use_json_mode and (\n \"JSON mode is not enabled\" in str(e)\n or \"json_object is not supported\" in str(e).lower()\n or \"response_format\" in str(e).lower()\n or \"400\" in str(e)\n ):\n logger.warning(f\"[get_json_completion] JSON mode failed or not supported: {e!s}. Falling back to plain text response.\")\n response = await self.client.chat.completions.create(\n model=self.default_model,\n messages=messages\n )\n else:\n raise e\n\n logger.debug(f\"[get_json_completion] LLM Response: {response}\")\n except OpenAIAuthenticationError as e:\n logger.error(f\"[get_json_completion] Authentication error: {e!s}\")\n # Do not retry on auth errors - re-raise to stop retry\n raise\n except RateLimitError as e:\n logger.warning(f\"[get_json_completion] Rate limit hit: {e!s}\")\n\n # Extract retry_delay from error metadata if available\n retry_delay = 5.0 # Default fallback\n try:\n # Based on logs, the raw response is in e.body or e.response.json()\n # The logs show 'metadata': {'raw': '...'} which suggests a proxy or specific client wrapper\n # Let's try to find the 'retryDelay' in the error message or response\n import re\n\n # Try to find \"retryDelay\": \"XXs\" in the string representation of the error\n error_str = str(e)\n match = re.search(r'\"retryDelay\":\\s*\"(\\d+)s\"', error_str)\n if match:\n retry_delay = float(match.group(1))\n else:\n # Try to parse from response if it's a standard OpenAI-like error with body\n if hasattr(e, 'body') and isinstance(e.body, dict):\n # Some providers put it in details\n details = e.body.get('error', {}).get('details', [])\n for detail in details:\n if detail.get('@type') == 'type.googleapis.com/google.rpc.RetryInfo':\n delay_str = detail.get('retryDelay', '5s')\n retry_delay = float(delay_str.rstrip('s'))\n break\n except Exception as parse_e:\n logger.debug(f\"[get_json_completion] Failed to parse retry delay: {parse_e}\")\n\n # Add a small safety margin (0.5s) as requested\n wait_time = retry_delay + 0.5\n logger.info(f\"[get_json_completion] Waiting for {wait_time}s before retry...\")\n await asyncio.sleep(wait_time)\n raise\n except Exception as e:\n logger.error(f\"[get_json_completion] LLM call failed: {e!s}\")\n raise\n\n if not response or not hasattr(response, 'choices') or not response.choices:\n raise RuntimeError(f\"Invalid LLM response: {response}\")\n\n content = response.choices[0].message.content\n logger.debug(f\"[get_json_completion] Raw content to parse: {content}\")\n\n try:\n return json.loads(content)\n except json.JSONDecodeError:\n logger.warning(\"[get_json_completion] Failed to parse JSON directly, attempting to extract from code blocks\")\n if \"```json\" in content:\n json_str = content.split(\"```json\")[1].split(\"```\")[0].strip()\n return json.loads(json_str)\n elif \"```\" in content:\n json_str = content.split(\"```\")[1].split(\"```\")[0].strip()\n return json.loads(json_str)\n else:\n raise\n # endregion LLMClient.get_json_completion\n\n # region LLMClient.test_runtime_connection [TYPE Function]\n # @PURPOSE: Validate provider credentials using the same chat completions transport as runtime analysis.\n # @PRE: Client is initialized with provider credentials and default_model.\n # @POST: Returns lightweight JSON payload when runtime auth/model path is valid.\n # @SIDE_EFFECT: Calls external LLM API.\n async def test_runtime_connection(self) -> dict[str, Any]:\n with belief_scope(\"test_runtime_connection\"):\n messages = [\n {\n \"role\": \"user\",\n \"content\": 'Return exactly this JSON object and nothing else: {\"ok\": true}',\n }\n ]\n return await self.get_json_completion(messages)\n # endregion LLMClient.test_runtime_connection\n\n # region LLMClient.fetch_models [TYPE Function]\n # @PURPOSE: Fetch available models from the provider's API.\n # @PRE: Client is initialized with provider credentials.\n # @POST: Returns a list of model ID strings.\n # @SIDE_EFFECT: Calls external LLM API /v1/models endpoint.\n async def fetch_models(self) -> list[str]:\n with belief_scope(\"LLMClient.fetch_models\"):\n try:\n response = await self.client.models.list()\n model_ids = [m.id for m in response.data]\n model_ids.sort()\n logger.reason(\n f\"[LLMClient.fetch_models] Fetched {len(model_ids)} models from {self.base_url}\",\n extra={\"src\": \"LLMClient.fetch_models\"},\n )\n return model_ids\n except Exception as e:\n logger.warning(\n f\"[LLMClient.fetch_models] Failed to fetch models: {e}\",\n )\n raise\n # endregion LLMClient.fetch_models\n\n # region LLMClient.analyze_dashboard [TYPE Function]\n # @PURPOSE: Sends dashboard data (screenshot + logs) to LLM for health analysis.\n # @PRE: screenshot_path exists, logs is a list of strings.\n # @POST: Returns a structured analysis dictionary (status, summary, issues).\n # @SIDE_EFFECT: Reads screenshot file and calls external LLM API.\n async def analyze_dashboard(\n self,\n screenshot_path: str,\n logs: list[str],\n prompt_template: str = DEFAULT_LLM_PROMPTS[\"dashboard_validation_prompt\"],\n ) -> dict[str, Any]:\n with belief_scope(\"analyze_dashboard\"):\n # Optimize image to reduce token count (US1 / T023)\n # Gemini/Gemma models have limits on input tokens, and large images contribute significantly.\n try:\n with Image.open(screenshot_path) as img:\n # Convert to RGB if necessary\n if img.mode in (\"RGBA\", \"P\"):\n img = img.convert(\"RGB\")\n\n # Resize if too large (max 1024px width while maintaining aspect ratio)\n # We reduce width further to 1024px to stay within token limits for long dashboards\n max_width = 1024\n if img.width > max_width or img.height > 2048:\n # Calculate scaling factor to fit within 1024x2048\n scale = min(max_width / img.width, 2048 / img.height)\n if scale < 1.0:\n new_width = int(img.width * scale)\n new_height = int(img.height * scale)\n img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)\n logger.info(f\"[analyze_dashboard] Resized image from {img.width}x{img.height} to {new_width}x{new_height}\")\n\n # Compress and convert to base64\n buffer = io.BytesIO()\n # Lower quality to 60% to further reduce payload size\n img.save(buffer, format=\"JPEG\", quality=60, optimize=True)\n base_64_image = base64.b64encode(buffer.getvalue()).decode('utf-8')\n logger.info(f\"[analyze_dashboard] Optimized image size: {len(buffer.getvalue()) / 1024:.2f} KB\")\n except Exception as img_e:\n logger.warning(f\"[analyze_dashboard] Image optimization failed: {img_e}. Using raw image.\")\n with open(screenshot_path, \"rb\") as image_file:\n base_64_image = base64.b64encode(image_file.read()).decode('utf-8')\n\n log_text = \"\\n\".join(logs)\n prompt = render_prompt(prompt_template, {\"logs\": log_text})\n\n messages = [\n {\n \"role\": \"user\",\n \"content\": [\n {\"type\": \"text\", \"text\": prompt},\n {\n \"type\": \"image_url\",\n \"image_url\": {\n \"url\": f\"data:image/jpeg;base64,{base_64_image}\"\n }\n }\n ]\n }\n ]\n\n try:\n return await self.get_json_completion(messages)\n except Exception as e:\n logger.error(f\"[analyze_dashboard] Failed to get analysis: {e!s}\")\n return {\n \"status\": \"UNKNOWN\",\n \"summary\": f\"Failed to get response from LLM: {e!s}\",\n \"issues\": [{\"severity\": \"UNKNOWN\", \"message\": \"LLM provider returned empty or invalid response\"}]\n }\n # endregion LLMClient.analyze_dashboard\n# #endregion LLMClient\n\n# #endregion LLMAnalysisService\n" + "body": "# #region LLMAnalysisService [C:3] [TYPE Module] [SEMANTICS llm, screenshot, playwright, openai, tenacity]\n# @BRIEF Services for LLM interaction and dashboard screenshots.\n# @LAYER: Domain\n# @RELATION DEPENDS_ON -> playwright\n# @RELATION DEPENDS_ON -> openai\n# @RELATION DEPENDS_ON -> tenacity\n# @INVARIANT: Screenshots must be 1920px width and capture full page height.\n\nimport asyncio\nimport base64\nimport io\nimport json\nimport os\nfrom typing import Any\nfrom urllib.parse import urlsplit\n\nimport httpx\nfrom openai import AsyncOpenAI, RateLimitError\nfrom openai import AuthenticationError as OpenAIAuthenticationError\nfrom PIL import Image\nfrom playwright.async_api import async_playwright\nfrom tenacity import retry, retry_if_exception, stop_after_attempt, wait_exponential\n\nfrom ...core.config_models import Environment\nfrom ...core.logger import belief_scope, logger\nfrom ...services.llm_prompt_templates import DEFAULT_LLM_PROMPTS, render_prompt\nfrom .models import LLMProviderType\n\n\n# #region ScreenshotService [TYPE Class]\n# @BRIEF Handles capturing screenshots of Superset dashboards.\nclass ScreenshotService:\n # region ScreenshotService.__init__ [TYPE Function]\n # @PURPOSE: Initializes the ScreenshotService with environment configuration.\n # @PRE: env is a valid Environment object.\n def __init__(self, env: Environment):\n self.env = env\n # endregion ScreenshotService.__init__\n\n # region ScreenshotService._find_first_visible_locator [TYPE Function]\n # @PURPOSE: Resolve the first visible locator from multiple Playwright locator strategies.\n # @PRE: candidates is a non-empty list of locator-like objects.\n # @POST: Returns a locator ready for interaction or None when nothing matches.\n async def _find_first_visible_locator(self, candidates) -> Any:\n for locator in candidates:\n try:\n match_count = await locator.count()\n for index in range(match_count):\n candidate = locator.nth(index)\n if await candidate.is_visible():\n return candidate\n except Exception:\n continue\n return None\n # endregion ScreenshotService._find_first_visible_locator\n\n # region ScreenshotService._iter_login_roots [TYPE Function]\n # @PURPOSE: Enumerate page and child frames where login controls may be rendered.\n # @PRE: page is a Playwright page-like object.\n # @POST: Returns ordered roots starting with main page followed by frames.\n def _iter_login_roots(self, page) -> list[Any]:\n roots = [page]\n page_frames = getattr(page, \"frames\", [])\n try:\n for frame in page_frames:\n if frame not in roots:\n roots.append(frame)\n except Exception:\n pass\n return roots\n # endregion ScreenshotService._iter_login_roots\n\n # region ScreenshotService._extract_hidden_login_fields [TYPE Function]\n # @PURPOSE: Collect hidden form fields required for direct login POST fallback.\n # @PRE: Login page is loaded.\n # @POST: Returns hidden input name/value mapping aggregated from page and child frames.\n async def _extract_hidden_login_fields(self, page) -> dict[str, str]:\n hidden_fields: dict[str, str] = {}\n for root in self._iter_login_roots(page):\n try:\n locator = root.locator(\"input[type='hidden'][name]\")\n count = await locator.count()\n for index in range(count):\n candidate = locator.nth(index)\n field_name = str(await candidate.get_attribute(\"name\") or \"\").strip()\n if not field_name or field_name in hidden_fields:\n continue\n hidden_fields[field_name] = str(await candidate.input_value()).strip()\n except Exception:\n continue\n return hidden_fields\n # endregion ScreenshotService._extract_hidden_login_fields\n\n # region ScreenshotService._extract_csrf_token [TYPE Function]\n # @PURPOSE: Resolve CSRF token value from main page or embedded login frame.\n # @PRE: Login page is loaded.\n # @POST: Returns first non-empty csrf token or empty string.\n async def _extract_csrf_token(self, page) -> str:\n hidden_fields = await self._extract_hidden_login_fields(page)\n return str(hidden_fields.get(\"csrf_token\") or \"\").strip()\n # endregion ScreenshotService._extract_csrf_token\n\n # region ScreenshotService._response_looks_like_login_page [TYPE Function]\n # @PURPOSE: Detect when fallback login POST returned the login form again instead of an authenticated page.\n # @PRE: response_text is normalized HTML or text from login POST response.\n # @POST: Returns True when login-page markers dominate the response body.\n def _response_looks_like_login_page(self, response_text: str) -> bool:\n normalized = str(response_text or \"\").strip().lower()\n if not normalized:\n return False\n\n markers = [\n \"enter your login and password below\",\n \"username:\",\n \"password:\",\n \"sign in\",\n 'name=\"csrf_token\"',\n ]\n return sum(marker in normalized for marker in markers) >= 3\n # endregion ScreenshotService._response_looks_like_login_page\n\n # region ScreenshotService._redirect_looks_authenticated [TYPE Function]\n # @PURPOSE: Treat non-login redirects after form POST as successful authentication without waiting for redirect target.\n # @PRE: redirect_location may be empty or relative.\n # @POST: Returns True when redirect target does not point back to login flow.\n def _redirect_looks_authenticated(self, redirect_location: str) -> bool:\n normalized = str(redirect_location or \"\").strip().lower()\n if not normalized:\n return True\n return \"/login\" not in normalized\n # endregion ScreenshotService._redirect_looks_authenticated\n\n # region ScreenshotService._submit_login_via_form_post [TYPE Function]\n # @PURPOSE: Fallback login path that submits credentials directly with csrf token.\n # @PRE: login_url is same-origin and csrf token can be read from DOM.\n # @POST: Browser context receives authenticated cookies when login succeeds.\n async def _submit_login_via_form_post(self, page, login_url: str) -> bool:\n hidden_fields = await self._extract_hidden_login_fields(page)\n csrf_token = str(hidden_fields.get(\"csrf_token\") or \"\").strip()\n if not csrf_token:\n logger.warning(\"[DEBUG] Direct form login fallback skipped: csrf_token not found\")\n return False\n\n try:\n request_context = page.context.request\n except Exception as context_error:\n logger.warning(f\"[DEBUG] Direct form login fallback skipped: request context unavailable: {context_error}\")\n return False\n\n parsed_url = urlsplit(login_url)\n origin = f\"{parsed_url.scheme}://{parsed_url.netloc}\" if parsed_url.scheme and parsed_url.netloc else login_url\n payload = dict(hidden_fields)\n payload[\"username\"] = self.env.username\n payload[\"password\"] = self.env.password\n logger.info(\n f\"[DEBUG] Attempting direct form login fallback via browser context request with hidden fields: {sorted(hidden_fields.keys())}\"\n )\n\n response = await request_context.post(\n login_url,\n form=payload,\n headers={\n \"Origin\": origin,\n \"Referer\": login_url,\n },\n timeout=10000,\n fail_on_status_code=False,\n max_redirects=0,\n )\n response_url = str(getattr(response, \"url\", \"\") or \"\")\n response_status = int(getattr(response, \"status\", 0) or 0)\n response_headers = dict(getattr(response, \"headers\", {}) or {})\n redirect_location = str(\n response_headers.get(\"location\")\n or response_headers.get(\"Location\")\n or \"\"\n ).strip()\n redirect_statuses = {301, 302, 303, 307, 308}\n if response_status in redirect_statuses:\n redirect_authenticated = self._redirect_looks_authenticated(redirect_location)\n logger.info(\n f\"[DEBUG] Direct form login fallback redirect response: status={response_status} url={response_url} location={redirect_location!r} authenticated={redirect_authenticated}\"\n )\n return redirect_authenticated\n\n response_text = await response.text()\n text_snippet = \" \".join(response_text.split())[:200]\n looks_like_login_page = self._response_looks_like_login_page(response_text)\n logger.info(\n f\"[DEBUG] Direct form login fallback response: status={response_status} url={response_url} login_markup={looks_like_login_page} snippet={text_snippet!r}\"\n )\n return not looks_like_login_page\n # endregion ScreenshotService._submit_login_via_form_post\n\n # region ScreenshotService._find_login_field_locator [TYPE Function]\n # @PURPOSE: Resolve login form input using semantic label text plus generic visible-input fallbacks.\n # @PRE: field_name is `username` or `password`.\n # @POST: Returns a locator for the corresponding input or None.\n async def _find_login_field_locator(self, page, field_name: str) -> Any:\n normalized = str(field_name or \"\").strip().lower()\n for root in self._iter_login_roots(page):\n if normalized == \"username\":\n input_candidates = [\n root.get_by_label(\"Username\", exact=False),\n root.get_by_label(\"Login\", exact=False),\n root.locator(\"label:text-matches('Username|Login', 'i')\").locator(\"xpath=following::input[1]\"),\n root.locator(\"text=/Username|Login/i\").locator(\"xpath=following::input[1]\"),\n root.locator(\"input[name='username']\"),\n root.locator(\"input#username\"),\n root.locator(\"input[placeholder*='Username']\"),\n root.locator(\"input[type='text']\"),\n root.locator(\"input:not([type='password'])\"),\n ]\n locator = await self._find_first_visible_locator(input_candidates)\n if locator:\n return locator\n\n if normalized == \"password\":\n input_candidates = [\n root.get_by_label(\"Password\", exact=False),\n root.locator(\"label:text-matches('Password', 'i')\").locator(\"xpath=following::input[1]\"),\n root.locator(\"text=/Password/i\").locator(\"xpath=following::input[1]\"),\n root.locator(\"input[name='password']\"),\n root.locator(\"input#password\"),\n root.locator(\"input[placeholder*='Password']\"),\n root.locator(\"input[type='password']\"),\n ]\n locator = await self._find_first_visible_locator(input_candidates)\n if locator:\n return locator\n\n return None\n # endregion ScreenshotService._find_login_field_locator\n\n # region ScreenshotService._find_submit_locator [TYPE Function]\n # @PURPOSE: Resolve login submit button from main page or embedded auth frame.\n # @PRE: page is ready for login interaction.\n # @POST: Returns visible submit locator or None.\n async def _find_submit_locator(self, page) -> Any:\n selectors = [\n lambda root: root.get_by_role(\"button\", name=\"Sign in\", exact=False),\n lambda root: root.get_by_role(\"button\", name=\"Login\", exact=False),\n lambda root: root.locator(\"button[type='submit']\"),\n lambda root: root.locator(\"button#submit\"),\n lambda root: root.locator(\".btn-primary\"),\n lambda root: root.locator(\"input[type='submit']\"),\n ]\n for root in self._iter_login_roots(page):\n locator = await self._find_first_visible_locator([factory(root) for factory in selectors])\n if locator:\n return locator\n return None\n # endregion ScreenshotService._find_submit_locator\n\n # region ScreenshotService._goto_resilient [TYPE Function]\n # @PURPOSE: Navigate without relying on networkidle for pages with long-polling or persistent requests.\n # @PRE: page is a valid Playwright page and url is non-empty.\n # @POST: Returns last navigation response or raises when both primary and fallback waits fail.\n async def _goto_resilient(\n self,\n page,\n url: str,\n primary_wait_until: str = \"domcontentloaded\",\n fallback_wait_until: str = \"load\",\n timeout: int = 60000,\n ):\n try:\n return await page.goto(url, wait_until=primary_wait_until, timeout=timeout)\n except Exception as primary_error:\n logger.warning(\n f\"[ScreenshotService._goto_resilient] Primary navigation wait '{primary_wait_until}' failed for {url}: {primary_error}\"\n )\n return await page.goto(url, wait_until=fallback_wait_until, timeout=timeout)\n # endregion ScreenshotService._goto_resilient\n\n # region ScreenshotService.capture_dashboard [TYPE Function]\n # @PURPOSE: Captures a full-page screenshot of a dashboard using Playwright and CDP.\n # @PRE: dashboard_id is a valid string, output_path is a writable path.\n # @POST: Returns True if screenshot is saved successfully.\n # @SIDE_EFFECT: Launches a browser, performs UI login, switches tabs, and writes a PNG file.\n # @UX_STATE: [Navigating] -> Loading dashboard UI\n # @UX_STATE: [TabSwitching] -> Iterating through dashboard tabs to trigger lazy loading\n # @UX_STATE: [CalculatingHeight] -> Determining dashboard dimensions\n # @UX_STATE: [Capturing] -> Executing CDP screenshot\n async def capture_dashboard(self, dashboard_id: str, output_path: str) -> bool:\n with belief_scope(\"capture_dashboard\", f\"dashboard_id={dashboard_id}\"):\n logger.info(f\"Capturing screenshot for dashboard {dashboard_id}\")\n async with async_playwright() as p:\n browser = await p.chromium.launch(\n headless=True,\n args=[\n \"--disable-blink-features=AutomationControlled\",\n \"--disable-infobars\",\n \"--no-sandbox\"\n ]\n )\n # Set a realistic user agent to avoid 403 Forbidden from OpenResty/WAF\n user_agent = \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36\"\n # Construct base UI URL from environment (strip /api/v1 suffix)\n base_ui_url = self.env.url.rstrip(\"/\")\n if base_ui_url.endswith(\"/api/v1\"):\n base_ui_url = base_ui_url[:-len(\"/api/v1\")]\n\n # Create browser context with realistic headers\n context = await browser.new_context(\n viewport={'width': 1280, 'height': 720},\n user_agent=user_agent,\n extra_http_headers={\n \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7\",\n \"Accept-Language\": \"ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7\",\n \"Upgrade-Insecure-Requests\": \"1\",\n \"Sec-Fetch-Dest\": \"document\",\n \"Sec-Fetch-Mode\": \"navigate\",\n \"Sec-Fetch-Site\": \"none\",\n \"Sec-Fetch-User\": \"?1\"\n }\n )\n logger.info(\"Browser context created successfully\")\n\n page = await context.new_page()\n # Bypass navigator.webdriver detection\n await page.add_init_script(\"delete Object.getPrototypeOf(navigator).webdriver\")\n\n # 1. Navigate to login page and authenticate\n login_url = f\"{base_ui_url.rstrip('/')}/login/\"\n logger.info(f\"[DEBUG] Navigating to login page: {login_url}\")\n\n response = await self._goto_resilient(\n page,\n login_url,\n primary_wait_until=\"domcontentloaded\",\n fallback_wait_until=\"load\",\n timeout=60000,\n )\n if response:\n logger.info(f\"[DEBUG] Login page response status: {response.status}\")\n\n # Wait for login form to be ready\n await page.wait_for_load_state(\"domcontentloaded\")\n\n # More exhaustive list of selectors for various Superset versions/themes\n selectors = {\n \"username\": ['input[name=\"username\"]', 'input#username', 'input[placeholder*=\"Username\"]', 'input[type=\"text\"]'],\n \"password\": ['input[name=\"password\"]', 'input#password', 'input[placeholder*=\"Password\"]', 'input[type=\"password\"]'],\n \"submit\": ['button[type=\"submit\"]', 'button#submit', '.btn-primary', 'input[type=\"submit\"]']\n }\n logger.info(\"[DEBUG] Attempting to find login form elements...\")\n\n try:\n used_direct_form_login = False\n # Find and fill username\n username_locator = await self._find_login_field_locator(page, \"username\")\n\n if not username_locator:\n roots = self._iter_login_roots(page)\n logger.info(f\"[DEBUG] Found {len(roots)} login roots including child frames\")\n for root_index, root in enumerate(roots[:5]):\n all_inputs = await root.locator('input').all()\n logger.info(f\"[DEBUG] Root {root_index}: found {len(all_inputs)} input fields\")\n for i, inp in enumerate(all_inputs[:5]): # Log first 5\n inp_type = await inp.get_attribute('type')\n inp_name = await inp.get_attribute('name')\n inp_id = await inp.get_attribute('id')\n logger.info(f\"[DEBUG] Root {root_index} input {i}: type={inp_type}, name={inp_name}, id={inp_id}\")\n used_direct_form_login = await self._submit_login_via_form_post(page, login_url)\n if not used_direct_form_login:\n raise RuntimeError(\"Could not find username input field on login page\")\n username_locator = None\n\n if username_locator is not None:\n logger.info(\"[DEBUG] Filling username field\")\n await username_locator.fill(self.env.username)\n\n # Find and fill password\n password_locator = await self._find_login_field_locator(page, \"password\") if username_locator is not None else None\n\n if username_locator is not None and not password_locator:\n raise RuntimeError(\"Could not find password input field on login page\")\n\n if password_locator is not None:\n logger.info(\"[DEBUG] Filling password field\")\n await password_locator.fill(self.env.password)\n\n # Click submit\n submit_locator = await self._find_submit_locator(page) if username_locator is not None else None\n\n if username_locator is not None and not submit_locator:\n raise RuntimeError(\"Could not find submit button on login page\")\n\n if submit_locator is not None:\n logger.info(\"[DEBUG] Clicking submit button\")\n await submit_locator.click()\n\n # Wait for navigation after login\n if not used_direct_form_login:\n try:\n await page.wait_for_load_state(\"load\", timeout=30000)\n except Exception as load_wait_error:\n logger.warning(f\"[DEBUG] Login post-submit load wait timed out: {load_wait_error}\")\n\n # Check if login was successful\n if not used_direct_form_login and \"/login\" in page.url:\n # Check for error messages on page\n error_msg = await page.locator(\".alert-danger, .error-message\").text_content() if await page.locator(\".alert-danger, .error-message\").count() > 0 else \"Unknown error\"\n logger.error(f\"[DEBUG] Login failed. Still on login page. Error: {error_msg}\")\n debug_path = output_path.replace(\".png\", \"_debug_failed_login.png\")\n await page.screenshot(path=debug_path)\n raise RuntimeError(f\"Login failed: {error_msg}. Debug screenshot saved to {debug_path}\")\n\n logger.info(f\"[DEBUG] Login successful. Current URL: {page.url}\")\n\n # Check cookies after successful login\n page_cookies = await context.cookies()\n logger.info(f\"[DEBUG] Cookies after login: {len(page_cookies)}\")\n for c in page_cookies:\n logger.info(f\"[DEBUG] Cookie: name={c['name']}, domain={c['domain']}, value={c.get('value', '')[:20]}...\")\n\n except Exception as e:\n page_title = await page.title()\n logger.error(f\"UI Login failed. Page title: {page_title}, URL: {page.url}, Error: {e!s}\")\n debug_path = output_path.replace(\".png\", \"_debug_failed_login.png\")\n await page.screenshot(path=debug_path)\n raise RuntimeError(f\"Login failed: {e!s}. Debug screenshot saved to {debug_path}\")\n\n # 2. Navigate to dashboard\n # @UX_STATE: [Navigating] -> Loading dashboard UI\n dashboard_url = f\"{base_ui_url.rstrip('/')}/superset/dashboard/{dashboard_id}/?standalone=true\"\n\n if base_ui_url.startswith(\"https://\") and dashboard_url.startswith(\"http://\"):\n dashboard_url = dashboard_url.replace(\"http://\", \"https://\")\n\n logger.info(f\"[DEBUG] Navigating to dashboard: {dashboard_url}\")\n\n # Dashboard pages can keep polling/network activity open indefinitely.\n response = await self._goto_resilient(\n page,\n dashboard_url,\n primary_wait_until=\"domcontentloaded\",\n fallback_wait_until=\"load\",\n timeout=60000,\n )\n\n if response:\n logger.info(f\"[DEBUG] Dashboard navigation response status: {response.status}, URL: {response.url}\")\n\n if \"/login\" in page.url:\n debug_path = output_path.replace(\".png\", \"_debug_failed_dashboard_auth.png\")\n await page.screenshot(path=debug_path)\n raise RuntimeError(\n f\"Dashboard navigation redirected to login page after authentication. Debug screenshot saved to {debug_path}\"\n )\n\n try:\n # Wait for the dashboard grid to be present\n await page.wait_for_selector('.dashboard-component, .dashboard-header, [data-test=\"dashboard-grid\"]', timeout=30000)\n logger.info(\"[DEBUG] Dashboard container loaded\")\n\n # Wait for charts to finish loading (Superset uses loading spinners/skeletons)\n # We wait until loading indicators disappear or a timeout occurs\n try:\n # Wait for loading indicators to disappear\n await page.wait_for_selector('.loading, .ant-skeleton, .spinner', state=\"hidden\", timeout=60000)\n logger.info(\"[DEBUG] Loading indicators hidden\")\n except Exception:\n logger.warning(\"[DEBUG] Timeout waiting for loading indicators to hide\")\n\n # Wait for charts to actually render their content (e.g., ECharts, NVD3)\n # We look for common chart containers that should have content\n try:\n await page.wait_for_selector('.chart-container canvas, .slice_container svg, .superset-chart-canvas, .grid-content .chart-container', timeout=60000)\n logger.info(\"[DEBUG] Chart content detected\")\n except Exception:\n logger.warning(\"[DEBUG] Timeout waiting for chart content\")\n\n # Additional check: wait for all chart containers to have non-empty content\n logger.info(\"[DEBUG] Waiting for all charts to have rendered content...\")\n await page.wait_for_function(\"\"\"() => {\n const charts = document.querySelectorAll('.chart-container, .slice_container');\n if (charts.length === 0) return true; // No charts to wait for\n \n // Check if all charts have rendered content (canvas, svg, or non-empty div)\n return Array.from(charts).every(chart => {\n const hasCanvas = chart.querySelector('canvas') !== null;\n const hasSvg = chart.querySelector('svg') !== null;\n const hasContent = chart.innerText.trim().length > 0 || chart.children.length > 0;\n return hasCanvas || hasSvg || hasContent;\n });\n }\"\"\", timeout=60000)\n logger.info(\"[DEBUG] All charts have rendered content\")\n\n # Scroll to bottom and back to top to trigger lazy loading of all charts\n logger.info(\"[DEBUG] Scrolling to trigger lazy loading...\")\n await page.evaluate(\"\"\"async () => {\n const delay = ms => new Promise(resolve => setTimeout(resolve, ms));\n for (let i = 0; i < document.body.scrollHeight; i += 500) {\n window.scrollTo(0, i);\n await delay(100);\n }\n window.scrollTo(0, 0);\n await delay(500);\n }\"\"\")\n\n except Exception as e:\n logger.warning(f\"[DEBUG] Dashboard content wait failed: {e}, proceeding anyway after delay\")\n\n # Final stabilization delay - increased for complex dashboards\n logger.info(\"[DEBUG] Final stabilization delay...\")\n await asyncio.sleep(15)\n\n # Logic to handle tabs and full-page capture\n try:\n # 1. Handle Tabs (Recursive switching)\n # @UX_STATE: [TabSwitching] -> Iterating through dashboard tabs to trigger lazy loading\n processed_tabs = set()\n\n async def switch_tabs(depth=0):\n if depth > 3:\n return # Limit recursion depth\n\n tab_selectors = [\n '.ant-tabs-nav-list .ant-tabs-tab',\n '.dashboard-component-tabs .ant-tabs-tab',\n '[data-test=\"dashboard-component-tabs\"] .ant-tabs-tab'\n ]\n\n found_tabs = []\n for selector in tab_selectors:\n found_tabs = await page.locator(selector).all()\n if found_tabs:\n break\n\n if found_tabs:\n logger.info(f\"[DEBUG][TabSwitching] Found {len(found_tabs)} tabs at depth {depth}\")\n for i, tab in enumerate(found_tabs):\n try:\n tab_text = (await tab.inner_text()).strip()\n tab_id = f\"{depth}_{i}_{tab_text}\"\n\n if tab_id in processed_tabs:\n continue\n\n if await tab.is_visible():\n logger.info(f\"[DEBUG][TabSwitching] Switching to tab: {tab_text}\")\n processed_tabs.add(tab_id)\n\n is_active = \"ant-tabs-tab-active\" in (await tab.get_attribute(\"class\") or \"\")\n if not is_active:\n await tab.click()\n await asyncio.sleep(2) # Wait for content to render\n\n await switch_tabs(depth + 1)\n except Exception as tab_e:\n logger.warning(f\"[DEBUG][TabSwitching] Failed to process tab {i}: {tab_e}\")\n\n try:\n first_tab = found_tabs[0]\n if \"ant-tabs-tab-active\" not in (await first_tab.get_attribute(\"class\") or \"\"):\n await first_tab.click()\n await asyncio.sleep(1)\n except Exception:\n pass\n\n await switch_tabs()\n\n # 2. Calculate full height for screenshot\n # @UX_STATE: [CalculatingHeight] -> Determining dashboard dimensions\n full_height = await page.evaluate(\"\"\"() => {\n const body = document.body;\n const html = document.documentElement;\n const dashboardContent = document.querySelector('.dashboard-content');\n \n return Math.max(\n body.scrollHeight, body.offsetHeight,\n html.clientHeight, html.scrollHeight, html.offsetHeight,\n dashboardContent ? dashboardContent.scrollHeight + 100 : 0\n );\n }\"\"\")\n logger.info(f\"[DEBUG] Calculated full height: {full_height}\")\n\n # DIAGNOSTIC: Count chart elements before resize\n chart_count_before = await page.evaluate(\"\"\"() => {\n return {\n chartContainers: document.querySelectorAll('.chart-container, .slice_container').length,\n canvasElements: document.querySelectorAll('canvas').length,\n svgElements: document.querySelectorAll('.chart-container svg, .slice_container svg').length,\n visibleCharts: document.querySelectorAll('.chart-container:visible, .slice_container:visible').length\n };\n }\"\"\")\n logger.info(f\"[DIAGNOSTIC] Chart elements BEFORE viewport resize: {chart_count_before}\")\n\n # DIAGNOSTIC: Capture pre-resize screenshot for comparison\n pre_resize_path = output_path.replace(\".png\", \"_preresize.png\")\n try:\n await page.screenshot(path=pre_resize_path, full_page=False, timeout=10000)\n import os\n pre_resize_size = os.path.getsize(pre_resize_path) if os.path.exists(pre_resize_path) else 0\n logger.info(f\"[DIAGNOSTIC] Pre-resize screenshot saved: {pre_resize_path} ({pre_resize_size} bytes)\")\n except Exception as pre_e:\n logger.warning(f\"[DIAGNOSTIC] Failed to capture pre-resize screenshot: {pre_e}\")\n\n logger.info(f\"[DIAGNOSTIC] Resizing viewport from current to 1920x{int(full_height)}\")\n await page.set_viewport_size({\"width\": 1920, \"height\": int(full_height)})\n\n # DIAGNOSTIC: Increased wait time and log timing\n logger.info(\"[DIAGNOSTIC] Waiting 10 seconds after viewport resize for re-render...\")\n await asyncio.sleep(10)\n logger.info(\"[DIAGNOSTIC] Wait completed\")\n\n # DIAGNOSTIC: Count chart elements after resize and wait\n chart_count_after = await page.evaluate(\"\"\"() => {\n return {\n chartContainers: document.querySelectorAll('.chart-container, .slice_container').length,\n canvasElements: document.querySelectorAll('canvas').length,\n svgElements: document.querySelectorAll('.chart-container svg, .slice_container svg').length,\n visibleCharts: document.querySelectorAll('.chart-container:visible, .slice_container:visible').length\n };\n }\"\"\")\n logger.info(f\"[DIAGNOSTIC] Chart elements AFTER viewport resize + wait: {chart_count_after}\")\n\n # DIAGNOSTIC: Check if any charts have error states\n chart_errors = await page.evaluate(\"\"\"() => {\n const errors = [];\n document.querySelectorAll('.chart-container, .slice_container').forEach((chart, i) => {\n const errorEl = chart.querySelector('.error, .alert-danger, .ant-alert-error');\n if (errorEl) {\n errors.push({index: i, text: errorEl.innerText.substring(0, 100)});\n }\n });\n return errors;\n }\"\"\")\n if chart_errors:\n logger.warning(f\"[DIAGNOSTIC] Charts with error states detected: {chart_errors}\")\n else:\n logger.info(\"[DIAGNOSTIC] No chart error states detected\")\n\n # 3. Take screenshot using CDP to bypass Playwright's font loading wait\n # @UX_STATE: [Capturing] -> Executing CDP screenshot\n logger.info(\"[DEBUG] Attempting full-page screenshot via CDP...\")\n cdp = await page.context.new_cdp_session(page)\n\n screenshot_data = await cdp.send(\"Page.captureScreenshot\", {\n \"format\": \"png\",\n \"fromSurface\": True,\n \"captureBeyondViewport\": True\n })\n\n image_data = base64.b64decode(screenshot_data[\"data\"])\n\n with open(output_path, 'wb') as f:\n f.write(image_data)\n\n # DIAGNOSTIC: Verify screenshot file\n import os\n final_size = os.path.getsize(output_path) if os.path.exists(output_path) else 0\n logger.info(f\"[DIAGNOSTIC] Final screenshot saved: {output_path}\")\n logger.info(f\"[DIAGNOSTIC] Final screenshot size: {final_size} bytes ({final_size / 1024:.2f} KB)\")\n\n # DIAGNOSTIC: Get image dimensions\n try:\n with Image.open(output_path) as final_img:\n logger.info(f\"[DIAGNOSTIC] Final screenshot dimensions: {final_img.width}x{final_img.height}\")\n except Exception as img_err:\n logger.warning(f\"[DIAGNOSTIC] Could not read final image dimensions: {img_err}\")\n\n logger.info(f\"Full-page screenshot saved to {output_path} (via CDP)\")\n except Exception as e:\n logger.error(f\"[DEBUG] Full-page/Tab capture failed: {e}\")\n try:\n await page.screenshot(path=output_path, full_page=True, timeout=10000)\n except Exception as e2:\n logger.error(f\"[DEBUG] Fallback screenshot also failed: {e2}\")\n await page.screenshot(path=output_path, timeout=5000)\n\n await browser.close()\n return True\n # endregion ScreenshotService.capture_dashboard\n# #endregion ScreenshotService\n\n# #region LLMClient [TYPE Class]\n# @BRIEF Wrapper for LLM provider APIs.\nclass LLMClient:\n # region LLMClient.__init__ [TYPE Function]\n # @PURPOSE: Initializes the LLMClient with provider settings.\n # @PRE: api_key, base_url, and default_model are non-empty strings.\n def __init__(self, provider_type: LLMProviderType, api_key: str, base_url: str, default_model: str):\n self.provider_type = provider_type\n normalized_key = (api_key or \"\").strip()\n if normalized_key.lower().startswith(\"bearer \"):\n normalized_key = normalized_key[7:].strip()\n self.api_key = normalized_key\n self.base_url = base_url\n self.default_model = default_model\n\n # DEBUG: Log initialization parameters (without exposing full API key)\n logger.info(\"[LLMClient.__init__] Initializing LLM client:\")\n logger.info(f\"[LLMClient.__init__] Provider Type: {provider_type}\")\n logger.info(f\"[LLMClient.__init__] Base URL: {base_url}\")\n logger.info(f\"[LLMClient.__init__] Default Model: {default_model}\")\n logger.info(f\"[LLMClient.__init__] API Key (first 8 chars): {self.api_key[:8] if self.api_key and len(self.api_key) > 8 else 'EMPTY_OR_NONE'}...\")\n logger.info(f\"[LLMClient.__init__] API Key Length: {len(self.api_key) if self.api_key else 0}\")\n\n # Some OpenAI-compatible gateways are strict about auth header naming.\n default_headers = {\"Authorization\": f\"Bearer {self.api_key}\"}\n if self.provider_type == LLMProviderType.OPENROUTER:\n default_headers[\"HTTP-Referer\"] = (\n os.getenv(\"OPENROUTER_SITE_URL\", \"\").strip()\n or os.getenv(\"APP_BASE_URL\", \"\").strip()\n or \"http://localhost:8000\"\n )\n default_headers[\"X-Title\"] = os.getenv(\"OPENROUTER_APP_NAME\", \"\").strip() or \"ss-tools\"\n if self.provider_type == LLMProviderType.KILO:\n default_headers[\"Authentication\"] = f\"Bearer {self.api_key}\"\n default_headers[\"X-API-Key\"] = self.api_key\n # LiteLLM proxy uses standard OpenAI-compatible Bearer auth — no special headers needed.\n # It routes to upstream providers transparently, and the default Authorization header\n # is sufficient. No additional headers like HTTP-Referer or X-API-Key are required.\n\n http_client = httpx.AsyncClient(headers=default_headers, timeout=120.0)\n self.client = AsyncOpenAI(\n api_key=self.api_key,\n base_url=base_url,\n default_headers=default_headers,\n http_client=http_client,\n )\n # endregion LLMClient.__init__\n\n # region LLMClient._supports_json_response_format [TYPE Function]\n # @PURPOSE: Detect whether provider/model is likely compatible with response_format=json_object.\n # @PRE: Client initialized with base_url and default_model.\n # @POST: Returns False for known-incompatible combinations to avoid avoidable 400 errors.\n def _supports_json_response_format(self) -> bool:\n base = (self.base_url or \"\").lower()\n model = (self.default_model or \"\").lower()\n\n # OpenRouter routes to many upstream providers; some models reject json_object mode.\n if \"openrouter.ai\" in base:\n incompatible_tokens = (\n \"stepfun/\",\n \"step-\",\n \":free\",\n )\n if any(token in model for token in incompatible_tokens):\n return False\n return True\n # endregion LLMClient._supports_json_response_format\n\n # region LLMClient.get_json_completion [TYPE Function]\n # @PURPOSE: Helper to handle LLM calls with JSON mode and fallback parsing.\n # @PRE: messages is a list of valid message dictionaries.\n # @POST: Returns a parsed JSON dictionary.\n # @SIDE_EFFECT: Calls external LLM API.\n def _should_retry(exception: Exception) -> bool:\n \"\"\"Custom retry predicate that excludes authentication errors.\"\"\"\n # Don't retry on authentication errors\n if isinstance(exception, OpenAIAuthenticationError):\n return False\n # Retry on rate limit errors and other exceptions\n return isinstance(exception, (RateLimitError, Exception))\n\n @retry(\n stop=stop_after_attempt(5),\n wait=wait_exponential(multiplier=2, min=5, max=60),\n retry=retry_if_exception(_should_retry),\n reraise=True\n )\n async def get_json_completion(self, messages: list[dict[str, Any]]) -> dict[str, Any]:\n with belief_scope(\"get_json_completion\"):\n response = None\n try:\n use_json_mode = self._supports_json_response_format()\n try:\n logger.info(\n f\"[get_json_completion] Attempting LLM call for model: {self.default_model} \"\n f\"(json_mode={'on' if use_json_mode else 'off'})\"\n )\n logger.info(f\"[get_json_completion] Base URL being used: {self.base_url}\")\n logger.info(f\"[get_json_completion] Number of messages: {len(messages)}\")\n logger.info(f\"[get_json_completion] API Key present: {bool(self.api_key and len(self.api_key) > 0)}\")\n\n if use_json_mode:\n response = await self.client.chat.completions.create(\n model=self.default_model,\n messages=messages,\n response_format={\"type\": \"json_object\"}\n )\n else:\n response = await self.client.chat.completions.create(\n model=self.default_model,\n messages=messages\n )\n except Exception as e:\n if use_json_mode and (\n \"JSON mode is not enabled\" in str(e)\n or \"json_object is not supported\" in str(e).lower()\n or \"response_format\" in str(e).lower()\n or \"400\" in str(e)\n ):\n logger.warning(f\"[get_json_completion] JSON mode failed or not supported: {e!s}. Falling back to plain text response.\")\n response = await self.client.chat.completions.create(\n model=self.default_model,\n messages=messages\n )\n else:\n raise e\n\n logger.debug(f\"[get_json_completion] LLM Response: {response}\")\n except OpenAIAuthenticationError as e:\n logger.error(f\"[get_json_completion] Authentication error: {e!s}\")\n # Do not retry on auth errors - re-raise to stop retry\n raise\n except RateLimitError as e:\n logger.warning(f\"[get_json_completion] Rate limit hit: {e!s}\")\n\n # Extract retry_delay from error metadata if available\n retry_delay = 5.0 # Default fallback\n try:\n # Based on logs, the raw response is in e.body or e.response.json()\n # The logs show 'metadata': {'raw': '...'} which suggests a proxy or specific client wrapper\n # Let's try to find the 'retryDelay' in the error message or response\n import re\n\n # Try to find \"retryDelay\": \"XXs\" in the string representation of the error\n error_str = str(e)\n match = re.search(r'\"retryDelay\":\\s*\"(\\d+)s\"', error_str)\n if match:\n retry_delay = float(match.group(1))\n else:\n # Try to parse from response if it's a standard OpenAI-like error with body\n if hasattr(e, 'body') and isinstance(e.body, dict):\n # Some providers put it in details\n details = e.body.get('error', {}).get('details', [])\n for detail in details:\n if detail.get('@type') == 'type.googleapis.com/google.rpc.RetryInfo':\n delay_str = detail.get('retryDelay', '5s')\n retry_delay = float(delay_str.rstrip('s'))\n break\n except Exception as parse_e:\n logger.debug(f\"[get_json_completion] Failed to parse retry delay: {parse_e}\")\n\n # Add a small safety margin (0.5s) as requested\n wait_time = retry_delay + 0.5\n logger.info(f\"[get_json_completion] Waiting for {wait_time}s before retry...\")\n await asyncio.sleep(wait_time)\n raise\n except Exception as e:\n logger.error(f\"[get_json_completion] LLM call failed: {e!s}\")\n raise\n\n if not response or not hasattr(response, 'choices') or not response.choices:\n raise RuntimeError(f\"Invalid LLM response: {response}\")\n\n content = response.choices[0].message.content\n logger.debug(f\"[get_json_completion] Raw content to parse: {content}\")\n\n try:\n return json.loads(content)\n except json.JSONDecodeError:\n logger.warning(\"[get_json_completion] Failed to parse JSON directly, attempting to extract from code blocks\")\n if \"```json\" in content:\n json_str = content.split(\"```json\")[1].split(\"```\")[0].strip()\n return json.loads(json_str)\n elif \"```\" in content:\n json_str = content.split(\"```\")[1].split(\"```\")[0].strip()\n return json.loads(json_str)\n else:\n raise\n # endregion LLMClient.get_json_completion\n\n # region LLMClient.test_runtime_connection [TYPE Function]\n # @PURPOSE: Validate provider credentials using the same chat completions transport as runtime analysis.\n # @PRE: Client is initialized with provider credentials and default_model.\n # @POST: Returns lightweight JSON payload when runtime auth/model path is valid.\n # @SIDE_EFFECT: Calls external LLM API.\n async def test_runtime_connection(self) -> dict[str, Any]:\n with belief_scope(\"test_runtime_connection\"):\n messages = [\n {\n \"role\": \"user\",\n \"content\": 'Return exactly this JSON object and nothing else: {\"ok\": true}',\n }\n ]\n return await self.get_json_completion(messages)\n # endregion LLMClient.test_runtime_connection\n\n # region LLMClient.fetch_models [TYPE Function]\n # @PURPOSE: Fetch available models from the provider's API.\n # @PRE: Client is initialized with provider credentials.\n # @POST: Returns a list of model ID strings.\n # @SIDE_EFFECT: Calls external LLM API /v1/models endpoint.\n async def fetch_models(self) -> list[str]:\n with belief_scope(\"LLMClient.fetch_models\"):\n try:\n response = await self.client.models.list()\n model_ids = [m.id for m in response.data]\n model_ids.sort()\n logger.reason(\n f\"[LLMClient.fetch_models] Fetched {len(model_ids)} models from {self.base_url}\",\n extra={\"src\": \"LLMClient.fetch_models\"},\n )\n return model_ids\n except Exception as e:\n logger.warning(\n f\"[LLMClient.fetch_models] Failed to fetch models: {e}\",\n )\n raise\n # endregion LLMClient.fetch_models\n\n # region LLMClient.analyze_dashboard [TYPE Function]\n # @PURPOSE: Sends dashboard data (screenshot + logs) to LLM for health analysis.\n # @PRE: screenshot_path exists, logs is a list of strings.\n # @POST: Returns a structured analysis dictionary (status, summary, issues).\n # @SIDE_EFFECT: Reads screenshot file and calls external LLM API.\n async def analyze_dashboard(\n self,\n screenshot_path: str,\n logs: list[str],\n prompt_template: str = DEFAULT_LLM_PROMPTS[\"dashboard_validation_prompt\"],\n ) -> dict[str, Any]:\n with belief_scope(\"analyze_dashboard\"):\n # Optimize image to reduce token count (US1 / T023)\n # Gemini/Gemma models have limits on input tokens, and large images contribute significantly.\n try:\n with Image.open(screenshot_path) as img:\n # Convert to RGB if necessary\n if img.mode in (\"RGBA\", \"P\"):\n img = img.convert(\"RGB\")\n\n # Resize if too large (max 1024px width while maintaining aspect ratio)\n # We reduce width further to 1024px to stay within token limits for long dashboards\n max_width = 1024\n if img.width > max_width or img.height > 2048:\n # Calculate scaling factor to fit within 1024x2048\n scale = min(max_width / img.width, 2048 / img.height)\n if scale < 1.0:\n new_width = int(img.width * scale)\n new_height = int(img.height * scale)\n img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)\n logger.info(f\"[analyze_dashboard] Resized image from {img.width}x{img.height} to {new_width}x{new_height}\")\n\n # Compress and convert to base64\n buffer = io.BytesIO()\n # Lower quality to 60% to further reduce payload size\n img.save(buffer, format=\"JPEG\", quality=60, optimize=True)\n base_64_image = base64.b64encode(buffer.getvalue()).decode('utf-8')\n logger.info(f\"[analyze_dashboard] Optimized image size: {len(buffer.getvalue()) / 1024:.2f} KB\")\n except Exception as img_e:\n logger.warning(f\"[analyze_dashboard] Image optimization failed: {img_e}. Using raw image.\")\n with open(screenshot_path, \"rb\") as image_file:\n base_64_image = base64.b64encode(image_file.read()).decode('utf-8')\n\n log_text = \"\\n\".join(logs)\n prompt = render_prompt(prompt_template, {\"logs\": log_text})\n\n messages = [\n {\n \"role\": \"user\",\n \"content\": [\n {\"type\": \"text\", \"text\": prompt},\n {\n \"type\": \"image_url\",\n \"image_url\": {\n \"url\": f\"data:image/jpeg;base64,{base_64_image}\"\n }\n }\n ]\n }\n ]\n\n try:\n return await self.get_json_completion(messages)\n except Exception as e:\n logger.error(f\"[analyze_dashboard] Failed to get analysis: {e!s}\")\n return {\n \"status\": \"UNKNOWN\",\n \"summary\": f\"Failed to get response from LLM: {e!s}\",\n \"issues\": [{\"severity\": \"UNKNOWN\", \"message\": \"LLM provider returned empty or invalid response\"}]\n }\n # endregion LLMClient.analyze_dashboard\n# #endregion LLMClient\n\n# #endregion LLMAnalysisService\n" }, { "contract_id": "ScreenshotService", @@ -48609,7 +48297,7 @@ "contract_type": "Class", "file_path": "backend/src/plugins/llm_analysis/service.py", "start_line": 679, - "end_line": 976, + "end_line": 979, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -48619,7 +48307,7 @@ "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region LLMClient [TYPE Class]\n# @BRIEF Wrapper for LLM provider APIs.\nclass LLMClient:\n # region LLMClient.__init__ [TYPE Function]\n # @PURPOSE: Initializes the LLMClient with provider settings.\n # @PRE: api_key, base_url, and default_model are non-empty strings.\n def __init__(self, provider_type: LLMProviderType, api_key: str, base_url: str, default_model: str):\n self.provider_type = provider_type\n normalized_key = (api_key or \"\").strip()\n if normalized_key.lower().startswith(\"bearer \"):\n normalized_key = normalized_key[7:].strip()\n self.api_key = normalized_key\n self.base_url = base_url\n self.default_model = default_model\n\n # DEBUG: Log initialization parameters (without exposing full API key)\n logger.info(\"[LLMClient.__init__] Initializing LLM client:\")\n logger.info(f\"[LLMClient.__init__] Provider Type: {provider_type}\")\n logger.info(f\"[LLMClient.__init__] Base URL: {base_url}\")\n logger.info(f\"[LLMClient.__init__] Default Model: {default_model}\")\n logger.info(f\"[LLMClient.__init__] API Key (first 8 chars): {self.api_key[:8] if self.api_key and len(self.api_key) > 8 else 'EMPTY_OR_NONE'}...\")\n logger.info(f\"[LLMClient.__init__] API Key Length: {len(self.api_key) if self.api_key else 0}\")\n\n # Some OpenAI-compatible gateways are strict about auth header naming.\n default_headers = {\"Authorization\": f\"Bearer {self.api_key}\"}\n if self.provider_type == LLMProviderType.OPENROUTER:\n default_headers[\"HTTP-Referer\"] = (\n os.getenv(\"OPENROUTER_SITE_URL\", \"\").strip()\n or os.getenv(\"APP_BASE_URL\", \"\").strip()\n or \"http://localhost:8000\"\n )\n default_headers[\"X-Title\"] = os.getenv(\"OPENROUTER_APP_NAME\", \"\").strip() or \"ss-tools\"\n if self.provider_type == LLMProviderType.KILO:\n default_headers[\"Authentication\"] = f\"Bearer {self.api_key}\"\n default_headers[\"X-API-Key\"] = self.api_key\n\n http_client = httpx.AsyncClient(headers=default_headers, timeout=120.0)\n self.client = AsyncOpenAI(\n api_key=self.api_key,\n base_url=base_url,\n default_headers=default_headers,\n http_client=http_client,\n )\n # endregion LLMClient.__init__\n\n # region LLMClient._supports_json_response_format [TYPE Function]\n # @PURPOSE: Detect whether provider/model is likely compatible with response_format=json_object.\n # @PRE: Client initialized with base_url and default_model.\n # @POST: Returns False for known-incompatible combinations to avoid avoidable 400 errors.\n def _supports_json_response_format(self) -> bool:\n base = (self.base_url or \"\").lower()\n model = (self.default_model or \"\").lower()\n\n # OpenRouter routes to many upstream providers; some models reject json_object mode.\n if \"openrouter.ai\" in base:\n incompatible_tokens = (\n \"stepfun/\",\n \"step-\",\n \":free\",\n )\n if any(token in model for token in incompatible_tokens):\n return False\n return True\n # endregion LLMClient._supports_json_response_format\n\n # region LLMClient.get_json_completion [TYPE Function]\n # @PURPOSE: Helper to handle LLM calls with JSON mode and fallback parsing.\n # @PRE: messages is a list of valid message dictionaries.\n # @POST: Returns a parsed JSON dictionary.\n # @SIDE_EFFECT: Calls external LLM API.\n def _should_retry(exception: Exception) -> bool:\n \"\"\"Custom retry predicate that excludes authentication errors.\"\"\"\n # Don't retry on authentication errors\n if isinstance(exception, OpenAIAuthenticationError):\n return False\n # Retry on rate limit errors and other exceptions\n return isinstance(exception, (RateLimitError, Exception))\n\n @retry(\n stop=stop_after_attempt(5),\n wait=wait_exponential(multiplier=2, min=5, max=60),\n retry=retry_if_exception(_should_retry),\n reraise=True\n )\n async def get_json_completion(self, messages: list[dict[str, Any]]) -> dict[str, Any]:\n with belief_scope(\"get_json_completion\"):\n response = None\n try:\n use_json_mode = self._supports_json_response_format()\n try:\n logger.info(\n f\"[get_json_completion] Attempting LLM call for model: {self.default_model} \"\n f\"(json_mode={'on' if use_json_mode else 'off'})\"\n )\n logger.info(f\"[get_json_completion] Base URL being used: {self.base_url}\")\n logger.info(f\"[get_json_completion] Number of messages: {len(messages)}\")\n logger.info(f\"[get_json_completion] API Key present: {bool(self.api_key and len(self.api_key) > 0)}\")\n\n if use_json_mode:\n response = await self.client.chat.completions.create(\n model=self.default_model,\n messages=messages,\n response_format={\"type\": \"json_object\"}\n )\n else:\n response = await self.client.chat.completions.create(\n model=self.default_model,\n messages=messages\n )\n except Exception as e:\n if use_json_mode and (\n \"JSON mode is not enabled\" in str(e)\n or \"json_object is not supported\" in str(e).lower()\n or \"response_format\" in str(e).lower()\n or \"400\" in str(e)\n ):\n logger.warning(f\"[get_json_completion] JSON mode failed or not supported: {e!s}. Falling back to plain text response.\")\n response = await self.client.chat.completions.create(\n model=self.default_model,\n messages=messages\n )\n else:\n raise e\n\n logger.debug(f\"[get_json_completion] LLM Response: {response}\")\n except OpenAIAuthenticationError as e:\n logger.error(f\"[get_json_completion] Authentication error: {e!s}\")\n # Do not retry on auth errors - re-raise to stop retry\n raise\n except RateLimitError as e:\n logger.warning(f\"[get_json_completion] Rate limit hit: {e!s}\")\n\n # Extract retry_delay from error metadata if available\n retry_delay = 5.0 # Default fallback\n try:\n # Based on logs, the raw response is in e.body or e.response.json()\n # The logs show 'metadata': {'raw': '...'} which suggests a proxy or specific client wrapper\n # Let's try to find the 'retryDelay' in the error message or response\n import re\n\n # Try to find \"retryDelay\": \"XXs\" in the string representation of the error\n error_str = str(e)\n match = re.search(r'\"retryDelay\":\\s*\"(\\d+)s\"', error_str)\n if match:\n retry_delay = float(match.group(1))\n else:\n # Try to parse from response if it's a standard OpenAI-like error with body\n if hasattr(e, 'body') and isinstance(e.body, dict):\n # Some providers put it in details\n details = e.body.get('error', {}).get('details', [])\n for detail in details:\n if detail.get('@type') == 'type.googleapis.com/google.rpc.RetryInfo':\n delay_str = detail.get('retryDelay', '5s')\n retry_delay = float(delay_str.rstrip('s'))\n break\n except Exception as parse_e:\n logger.debug(f\"[get_json_completion] Failed to parse retry delay: {parse_e}\")\n\n # Add a small safety margin (0.5s) as requested\n wait_time = retry_delay + 0.5\n logger.info(f\"[get_json_completion] Waiting for {wait_time}s before retry...\")\n await asyncio.sleep(wait_time)\n raise\n except Exception as e:\n logger.error(f\"[get_json_completion] LLM call failed: {e!s}\")\n raise\n\n if not response or not hasattr(response, 'choices') or not response.choices:\n raise RuntimeError(f\"Invalid LLM response: {response}\")\n\n content = response.choices[0].message.content\n logger.debug(f\"[get_json_completion] Raw content to parse: {content}\")\n\n try:\n return json.loads(content)\n except json.JSONDecodeError:\n logger.warning(\"[get_json_completion] Failed to parse JSON directly, attempting to extract from code blocks\")\n if \"```json\" in content:\n json_str = content.split(\"```json\")[1].split(\"```\")[0].strip()\n return json.loads(json_str)\n elif \"```\" in content:\n json_str = content.split(\"```\")[1].split(\"```\")[0].strip()\n return json.loads(json_str)\n else:\n raise\n # endregion LLMClient.get_json_completion\n\n # region LLMClient.test_runtime_connection [TYPE Function]\n # @PURPOSE: Validate provider credentials using the same chat completions transport as runtime analysis.\n # @PRE: Client is initialized with provider credentials and default_model.\n # @POST: Returns lightweight JSON payload when runtime auth/model path is valid.\n # @SIDE_EFFECT: Calls external LLM API.\n async def test_runtime_connection(self) -> dict[str, Any]:\n with belief_scope(\"test_runtime_connection\"):\n messages = [\n {\n \"role\": \"user\",\n \"content\": 'Return exactly this JSON object and nothing else: {\"ok\": true}',\n }\n ]\n return await self.get_json_completion(messages)\n # endregion LLMClient.test_runtime_connection\n\n # region LLMClient.fetch_models [TYPE Function]\n # @PURPOSE: Fetch available models from the provider's API.\n # @PRE: Client is initialized with provider credentials.\n # @POST: Returns a list of model ID strings.\n # @SIDE_EFFECT: Calls external LLM API /v1/models endpoint.\n async def fetch_models(self) -> list[str]:\n with belief_scope(\"LLMClient.fetch_models\"):\n try:\n response = await self.client.models.list()\n model_ids = [m.id for m in response.data]\n model_ids.sort()\n logger.reason(\n f\"[LLMClient.fetch_models] Fetched {len(model_ids)} models from {self.base_url}\",\n extra={\"src\": \"LLMClient.fetch_models\"},\n )\n return model_ids\n except Exception as e:\n logger.warning(\n f\"[LLMClient.fetch_models] Failed to fetch models: {e}\",\n )\n raise\n # endregion LLMClient.fetch_models\n\n # region LLMClient.analyze_dashboard [TYPE Function]\n # @PURPOSE: Sends dashboard data (screenshot + logs) to LLM for health analysis.\n # @PRE: screenshot_path exists, logs is a list of strings.\n # @POST: Returns a structured analysis dictionary (status, summary, issues).\n # @SIDE_EFFECT: Reads screenshot file and calls external LLM API.\n async def analyze_dashboard(\n self,\n screenshot_path: str,\n logs: list[str],\n prompt_template: str = DEFAULT_LLM_PROMPTS[\"dashboard_validation_prompt\"],\n ) -> dict[str, Any]:\n with belief_scope(\"analyze_dashboard\"):\n # Optimize image to reduce token count (US1 / T023)\n # Gemini/Gemma models have limits on input tokens, and large images contribute significantly.\n try:\n with Image.open(screenshot_path) as img:\n # Convert to RGB if necessary\n if img.mode in (\"RGBA\", \"P\"):\n img = img.convert(\"RGB\")\n\n # Resize if too large (max 1024px width while maintaining aspect ratio)\n # We reduce width further to 1024px to stay within token limits for long dashboards\n max_width = 1024\n if img.width > max_width or img.height > 2048:\n # Calculate scaling factor to fit within 1024x2048\n scale = min(max_width / img.width, 2048 / img.height)\n if scale < 1.0:\n new_width = int(img.width * scale)\n new_height = int(img.height * scale)\n img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)\n logger.info(f\"[analyze_dashboard] Resized image from {img.width}x{img.height} to {new_width}x{new_height}\")\n\n # Compress and convert to base64\n buffer = io.BytesIO()\n # Lower quality to 60% to further reduce payload size\n img.save(buffer, format=\"JPEG\", quality=60, optimize=True)\n base_64_image = base64.b64encode(buffer.getvalue()).decode('utf-8')\n logger.info(f\"[analyze_dashboard] Optimized image size: {len(buffer.getvalue()) / 1024:.2f} KB\")\n except Exception as img_e:\n logger.warning(f\"[analyze_dashboard] Image optimization failed: {img_e}. Using raw image.\")\n with open(screenshot_path, \"rb\") as image_file:\n base_64_image = base64.b64encode(image_file.read()).decode('utf-8')\n\n log_text = \"\\n\".join(logs)\n prompt = render_prompt(prompt_template, {\"logs\": log_text})\n\n messages = [\n {\n \"role\": \"user\",\n \"content\": [\n {\"type\": \"text\", \"text\": prompt},\n {\n \"type\": \"image_url\",\n \"image_url\": {\n \"url\": f\"data:image/jpeg;base64,{base_64_image}\"\n }\n }\n ]\n }\n ]\n\n try:\n return await self.get_json_completion(messages)\n except Exception as e:\n logger.error(f\"[analyze_dashboard] Failed to get analysis: {e!s}\")\n return {\n \"status\": \"UNKNOWN\",\n \"summary\": f\"Failed to get response from LLM: {e!s}\",\n \"issues\": [{\"severity\": \"UNKNOWN\", \"message\": \"LLM provider returned empty or invalid response\"}]\n }\n # endregion LLMClient.analyze_dashboard\n# #endregion LLMClient\n" + "body": "# #region LLMClient [TYPE Class]\n# @BRIEF Wrapper for LLM provider APIs.\nclass LLMClient:\n # region LLMClient.__init__ [TYPE Function]\n # @PURPOSE: Initializes the LLMClient with provider settings.\n # @PRE: api_key, base_url, and default_model are non-empty strings.\n def __init__(self, provider_type: LLMProviderType, api_key: str, base_url: str, default_model: str):\n self.provider_type = provider_type\n normalized_key = (api_key or \"\").strip()\n if normalized_key.lower().startswith(\"bearer \"):\n normalized_key = normalized_key[7:].strip()\n self.api_key = normalized_key\n self.base_url = base_url\n self.default_model = default_model\n\n # DEBUG: Log initialization parameters (without exposing full API key)\n logger.info(\"[LLMClient.__init__] Initializing LLM client:\")\n logger.info(f\"[LLMClient.__init__] Provider Type: {provider_type}\")\n logger.info(f\"[LLMClient.__init__] Base URL: {base_url}\")\n logger.info(f\"[LLMClient.__init__] Default Model: {default_model}\")\n logger.info(f\"[LLMClient.__init__] API Key (first 8 chars): {self.api_key[:8] if self.api_key and len(self.api_key) > 8 else 'EMPTY_OR_NONE'}...\")\n logger.info(f\"[LLMClient.__init__] API Key Length: {len(self.api_key) if self.api_key else 0}\")\n\n # Some OpenAI-compatible gateways are strict about auth header naming.\n default_headers = {\"Authorization\": f\"Bearer {self.api_key}\"}\n if self.provider_type == LLMProviderType.OPENROUTER:\n default_headers[\"HTTP-Referer\"] = (\n os.getenv(\"OPENROUTER_SITE_URL\", \"\").strip()\n or os.getenv(\"APP_BASE_URL\", \"\").strip()\n or \"http://localhost:8000\"\n )\n default_headers[\"X-Title\"] = os.getenv(\"OPENROUTER_APP_NAME\", \"\").strip() or \"ss-tools\"\n if self.provider_type == LLMProviderType.KILO:\n default_headers[\"Authentication\"] = f\"Bearer {self.api_key}\"\n default_headers[\"X-API-Key\"] = self.api_key\n # LiteLLM proxy uses standard OpenAI-compatible Bearer auth — no special headers needed.\n # It routes to upstream providers transparently, and the default Authorization header\n # is sufficient. No additional headers like HTTP-Referer or X-API-Key are required.\n\n http_client = httpx.AsyncClient(headers=default_headers, timeout=120.0)\n self.client = AsyncOpenAI(\n api_key=self.api_key,\n base_url=base_url,\n default_headers=default_headers,\n http_client=http_client,\n )\n # endregion LLMClient.__init__\n\n # region LLMClient._supports_json_response_format [TYPE Function]\n # @PURPOSE: Detect whether provider/model is likely compatible with response_format=json_object.\n # @PRE: Client initialized with base_url and default_model.\n # @POST: Returns False for known-incompatible combinations to avoid avoidable 400 errors.\n def _supports_json_response_format(self) -> bool:\n base = (self.base_url or \"\").lower()\n model = (self.default_model or \"\").lower()\n\n # OpenRouter routes to many upstream providers; some models reject json_object mode.\n if \"openrouter.ai\" in base:\n incompatible_tokens = (\n \"stepfun/\",\n \"step-\",\n \":free\",\n )\n if any(token in model for token in incompatible_tokens):\n return False\n return True\n # endregion LLMClient._supports_json_response_format\n\n # region LLMClient.get_json_completion [TYPE Function]\n # @PURPOSE: Helper to handle LLM calls with JSON mode and fallback parsing.\n # @PRE: messages is a list of valid message dictionaries.\n # @POST: Returns a parsed JSON dictionary.\n # @SIDE_EFFECT: Calls external LLM API.\n def _should_retry(exception: Exception) -> bool:\n \"\"\"Custom retry predicate that excludes authentication errors.\"\"\"\n # Don't retry on authentication errors\n if isinstance(exception, OpenAIAuthenticationError):\n return False\n # Retry on rate limit errors and other exceptions\n return isinstance(exception, (RateLimitError, Exception))\n\n @retry(\n stop=stop_after_attempt(5),\n wait=wait_exponential(multiplier=2, min=5, max=60),\n retry=retry_if_exception(_should_retry),\n reraise=True\n )\n async def get_json_completion(self, messages: list[dict[str, Any]]) -> dict[str, Any]:\n with belief_scope(\"get_json_completion\"):\n response = None\n try:\n use_json_mode = self._supports_json_response_format()\n try:\n logger.info(\n f\"[get_json_completion] Attempting LLM call for model: {self.default_model} \"\n f\"(json_mode={'on' if use_json_mode else 'off'})\"\n )\n logger.info(f\"[get_json_completion] Base URL being used: {self.base_url}\")\n logger.info(f\"[get_json_completion] Number of messages: {len(messages)}\")\n logger.info(f\"[get_json_completion] API Key present: {bool(self.api_key and len(self.api_key) > 0)}\")\n\n if use_json_mode:\n response = await self.client.chat.completions.create(\n model=self.default_model,\n messages=messages,\n response_format={\"type\": \"json_object\"}\n )\n else:\n response = await self.client.chat.completions.create(\n model=self.default_model,\n messages=messages\n )\n except Exception as e:\n if use_json_mode and (\n \"JSON mode is not enabled\" in str(e)\n or \"json_object is not supported\" in str(e).lower()\n or \"response_format\" in str(e).lower()\n or \"400\" in str(e)\n ):\n logger.warning(f\"[get_json_completion] JSON mode failed or not supported: {e!s}. Falling back to plain text response.\")\n response = await self.client.chat.completions.create(\n model=self.default_model,\n messages=messages\n )\n else:\n raise e\n\n logger.debug(f\"[get_json_completion] LLM Response: {response}\")\n except OpenAIAuthenticationError as e:\n logger.error(f\"[get_json_completion] Authentication error: {e!s}\")\n # Do not retry on auth errors - re-raise to stop retry\n raise\n except RateLimitError as e:\n logger.warning(f\"[get_json_completion] Rate limit hit: {e!s}\")\n\n # Extract retry_delay from error metadata if available\n retry_delay = 5.0 # Default fallback\n try:\n # Based on logs, the raw response is in e.body or e.response.json()\n # The logs show 'metadata': {'raw': '...'} which suggests a proxy or specific client wrapper\n # Let's try to find the 'retryDelay' in the error message or response\n import re\n\n # Try to find \"retryDelay\": \"XXs\" in the string representation of the error\n error_str = str(e)\n match = re.search(r'\"retryDelay\":\\s*\"(\\d+)s\"', error_str)\n if match:\n retry_delay = float(match.group(1))\n else:\n # Try to parse from response if it's a standard OpenAI-like error with body\n if hasattr(e, 'body') and isinstance(e.body, dict):\n # Some providers put it in details\n details = e.body.get('error', {}).get('details', [])\n for detail in details:\n if detail.get('@type') == 'type.googleapis.com/google.rpc.RetryInfo':\n delay_str = detail.get('retryDelay', '5s')\n retry_delay = float(delay_str.rstrip('s'))\n break\n except Exception as parse_e:\n logger.debug(f\"[get_json_completion] Failed to parse retry delay: {parse_e}\")\n\n # Add a small safety margin (0.5s) as requested\n wait_time = retry_delay + 0.5\n logger.info(f\"[get_json_completion] Waiting for {wait_time}s before retry...\")\n await asyncio.sleep(wait_time)\n raise\n except Exception as e:\n logger.error(f\"[get_json_completion] LLM call failed: {e!s}\")\n raise\n\n if not response or not hasattr(response, 'choices') or not response.choices:\n raise RuntimeError(f\"Invalid LLM response: {response}\")\n\n content = response.choices[0].message.content\n logger.debug(f\"[get_json_completion] Raw content to parse: {content}\")\n\n try:\n return json.loads(content)\n except json.JSONDecodeError:\n logger.warning(\"[get_json_completion] Failed to parse JSON directly, attempting to extract from code blocks\")\n if \"```json\" in content:\n json_str = content.split(\"```json\")[1].split(\"```\")[0].strip()\n return json.loads(json_str)\n elif \"```\" in content:\n json_str = content.split(\"```\")[1].split(\"```\")[0].strip()\n return json.loads(json_str)\n else:\n raise\n # endregion LLMClient.get_json_completion\n\n # region LLMClient.test_runtime_connection [TYPE Function]\n # @PURPOSE: Validate provider credentials using the same chat completions transport as runtime analysis.\n # @PRE: Client is initialized with provider credentials and default_model.\n # @POST: Returns lightweight JSON payload when runtime auth/model path is valid.\n # @SIDE_EFFECT: Calls external LLM API.\n async def test_runtime_connection(self) -> dict[str, Any]:\n with belief_scope(\"test_runtime_connection\"):\n messages = [\n {\n \"role\": \"user\",\n \"content\": 'Return exactly this JSON object and nothing else: {\"ok\": true}',\n }\n ]\n return await self.get_json_completion(messages)\n # endregion LLMClient.test_runtime_connection\n\n # region LLMClient.fetch_models [TYPE Function]\n # @PURPOSE: Fetch available models from the provider's API.\n # @PRE: Client is initialized with provider credentials.\n # @POST: Returns a list of model ID strings.\n # @SIDE_EFFECT: Calls external LLM API /v1/models endpoint.\n async def fetch_models(self) -> list[str]:\n with belief_scope(\"LLMClient.fetch_models\"):\n try:\n response = await self.client.models.list()\n model_ids = [m.id for m in response.data]\n model_ids.sort()\n logger.reason(\n f\"[LLMClient.fetch_models] Fetched {len(model_ids)} models from {self.base_url}\",\n extra={\"src\": \"LLMClient.fetch_models\"},\n )\n return model_ids\n except Exception as e:\n logger.warning(\n f\"[LLMClient.fetch_models] Failed to fetch models: {e}\",\n )\n raise\n # endregion LLMClient.fetch_models\n\n # region LLMClient.analyze_dashboard [TYPE Function]\n # @PURPOSE: Sends dashboard data (screenshot + logs) to LLM for health analysis.\n # @PRE: screenshot_path exists, logs is a list of strings.\n # @POST: Returns a structured analysis dictionary (status, summary, issues).\n # @SIDE_EFFECT: Reads screenshot file and calls external LLM API.\n async def analyze_dashboard(\n self,\n screenshot_path: str,\n logs: list[str],\n prompt_template: str = DEFAULT_LLM_PROMPTS[\"dashboard_validation_prompt\"],\n ) -> dict[str, Any]:\n with belief_scope(\"analyze_dashboard\"):\n # Optimize image to reduce token count (US1 / T023)\n # Gemini/Gemma models have limits on input tokens, and large images contribute significantly.\n try:\n with Image.open(screenshot_path) as img:\n # Convert to RGB if necessary\n if img.mode in (\"RGBA\", \"P\"):\n img = img.convert(\"RGB\")\n\n # Resize if too large (max 1024px width while maintaining aspect ratio)\n # We reduce width further to 1024px to stay within token limits for long dashboards\n max_width = 1024\n if img.width > max_width or img.height > 2048:\n # Calculate scaling factor to fit within 1024x2048\n scale = min(max_width / img.width, 2048 / img.height)\n if scale < 1.0:\n new_width = int(img.width * scale)\n new_height = int(img.height * scale)\n img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)\n logger.info(f\"[analyze_dashboard] Resized image from {img.width}x{img.height} to {new_width}x{new_height}\")\n\n # Compress and convert to base64\n buffer = io.BytesIO()\n # Lower quality to 60% to further reduce payload size\n img.save(buffer, format=\"JPEG\", quality=60, optimize=True)\n base_64_image = base64.b64encode(buffer.getvalue()).decode('utf-8')\n logger.info(f\"[analyze_dashboard] Optimized image size: {len(buffer.getvalue()) / 1024:.2f} KB\")\n except Exception as img_e:\n logger.warning(f\"[analyze_dashboard] Image optimization failed: {img_e}. Using raw image.\")\n with open(screenshot_path, \"rb\") as image_file:\n base_64_image = base64.b64encode(image_file.read()).decode('utf-8')\n\n log_text = \"\\n\".join(logs)\n prompt = render_prompt(prompt_template, {\"logs\": log_text})\n\n messages = [\n {\n \"role\": \"user\",\n \"content\": [\n {\"type\": \"text\", \"text\": prompt},\n {\n \"type\": \"image_url\",\n \"image_url\": {\n \"url\": f\"data:image/jpeg;base64,{base_64_image}\"\n }\n }\n ]\n }\n ]\n\n try:\n return await self.get_json_completion(messages)\n except Exception as e:\n logger.error(f\"[analyze_dashboard] Failed to get analysis: {e!s}\")\n return {\n \"status\": \"UNKNOWN\",\n \"summary\": f\"Failed to get response from LLM: {e!s}\",\n \"issues\": [{\"severity\": \"UNKNOWN\", \"message\": \"LLM provider returned empty or invalid response\"}]\n }\n # endregion LLMClient.analyze_dashboard\n# #endregion LLMClient\n" }, { "contract_id": "MapperPluginModule", @@ -49010,52 +48698,22 @@ "contract_type": "Package", "file_path": "backend/src/plugins/translate/__init__.py", "start_line": 1, - "end_line": 3, + "end_line": 2, "tier": "TIER_1", "complexity": 1, - "metadata": { - "PURPOSE": "Translation plugin package for LLM-based cross-Superset SQL/dashboard translation." - }, + "metadata": {}, "relations": [], - "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "PURPOSE", - "message": "@PURPOSE is not allowed for contract type 'Package'", - "detail": { - "actual_type": "Package", - "allowed_types": [ - "Module", - "Function", - "Class", - "Component", - "Block", - "ADR", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PURPOSE", - "message": "@PURPOSE is forbidden for contract type 'Package' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Package" - } - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslatePluginPackage [TYPE Package] [SEMANTICS translate, plugin, package, sql, dashboard]\n# @BRIEF Translation plugin package for LLM-based cross-Superset SQL/dashboard translation.\n# #endregion TranslatePluginPackage\n" + "body": "# #region TranslatePluginPackage [TYPE Package] [SEMANTICS translate, plugin, package, sql, dashboard]\n# #endregion TranslatePluginPackage\n" }, { "contract_id": "TestClickHouseTimestampNormalization", "contract_type": "Class", "file_path": "backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py", - "start_line": 76, - "end_line": 136, + "start_line": 81, + "end_line": 141, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -49071,8 +48729,8 @@ "contract_id": "TestClickHouseInsertSqlGeneration", "contract_type": "Class", "file_path": "backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py", - "start_line": 139, - "end_line": 248, + "start_line": 144, + "end_line": 253, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -49088,8 +48746,8 @@ "contract_id": "TestClickHouseJoinVerification", "contract_type": "Class", "file_path": "backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py", - "start_line": 251, - "end_line": 319, + "start_line": 256, + "end_line": 324, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -49105,8 +48763,8 @@ "contract_id": "TestOrchestratorInsertFlow", "contract_type": "Class", "file_path": "backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py", - "start_line": 322, - "end_line": 410, + "start_line": 327, + "end_line": 416, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -49116,14 +48774,14 @@ "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TestOrchestratorInsertFlow [TYPE Class]\n# @BRIEF Verify the orchestrator's _generate_and_insert_sql produces correct SQL for ClickHouse.\nclass TestOrchestratorInsertFlow:\n \"\"\"Verify TranslationOrchestrator._generate_and_insert_sql with mocked DB.\"\"\"\n\n # region test_generate_and_insert_sql_with_timestamps [TYPE Function]\n # @BRIEF Orchestrator builds correct rows_for_sql from source_data with timestamps.\n def test_generate_and_insert_sql_with_timestamps(self) -> None:\n \"\"\"Verify the orchestrator correctly passes source_data through to SQLGenerator.\"\"\"\n from src.plugins.translate.orchestrator import TranslationOrchestrator\n\n # Mock DB session\n db = MagicMock()\n config_manager = MagicMock()\n\n # Create mock records with timestamp source_data\n rec1 = _make_mock_record(\n target_sql=\"Translated comment 1\",\n report_date=\"1726358400000.0\",\n document_number=\"DOC-001\",\n )\n rec2 = _make_mock_record(\n target_sql=\"Translated comment 2\",\n report_date=\"1726444800000.0\",\n document_number=\"DOC-002\",\n )\n\n # Mock the DB query to return our records\n mock_query = MagicMock()\n mock_query.filter.return_value.all.return_value = [rec1, rec2]\n db.query.return_value = mock_query\n\n # Create mock job\n job = _make_mock_job()\n\n # Create mock run\n run = MagicMock()\n run.id = \"run-test-001\"\n run.job_id = job.id\n\n # Create orchestrator\n orch = TranslationOrchestrator(db, config_manager, \"test-user\")\n\n # Mock the event_log and SupersetSqlLabExecutor\n with patch.object(orch, \"event_log\") as mock_event_log, patch(\n \"src.plugins.translate.orchestrator.SupersetSqlLabExecutor\"\n ) as MockExecutor:\n mock_executor = MagicMock()\n MockExecutor.return_value = mock_executor\n mock_executor.resolve_database_id.return_value = None\n mock_executor.get_database_backend.return_value = None\n mock_executor.execute_and_poll.return_value = {\n \"status\": \"success\",\n \"query_id\": \"q-123\",\n \"rows_affected\": 2,\n }\n\n # Call _generate_and_insert_sql\n result = orch._generate_and_insert_sql(job, run)\n\n # Verify executor was called\n mock_executor.execute_and_poll.assert_called_once()\n\n # Get the SQL that was submitted\n call_args = mock_executor.execute_and_poll.call_args\n submitted_sql = call_args.kwargs.get(\"sql\") or call_args[1].get(\"sql\")\n\n # Verify the SQL contains normalized dates\n assert \"'2024-09-15'\" in submitted_sql, f\"Expected '2024-09-15' in SQL:\\n{submitted_sql}\"\n assert \"'2024-09-16'\" in submitted_sql, f\"Expected '2024-09-16' in SQL:\\n{submitted_sql}\"\n\n # Verify document numbers are preserved\n assert \"'DOC-001'\" in submitted_sql\n assert \"'DOC-002'\" in submitted_sql\n\n # Verify translated text is present\n assert \"'Translated comment 1'\" in submitted_sql\n assert \"'Translated comment 2'\" in submitted_sql\n\n # Verify ClickHouse-specific quoting (backticks)\n assert \"`report_date`\" in submitted_sql\n assert \"`document_number`\" in submitted_sql\n assert \"`comment_text_en`\" in submitted_sql\n\n # Verify result\n assert result[\"status\"] == \"success\"\n\n # endregion test_generate_and_insert_sql_with_timestamps\n# #endregion TestOrchestratorInsertFlow\n" + "body": "# #region TestOrchestratorInsertFlow [TYPE Class]\n# @BRIEF Verify the orchestrator's _generate_and_insert_sql produces correct SQL for ClickHouse.\nclass TestOrchestratorInsertFlow:\n \"\"\"Verify TranslationOrchestrator._generate_and_insert_sql with mocked DB.\"\"\"\n\n # region test_generate_and_insert_sql_with_timestamps [TYPE Function]\n # @BRIEF Orchestrator builds correct rows_for_sql from source_data with timestamps.\n def test_generate_and_insert_sql_with_timestamps(self) -> None:\n \"\"\"Verify the orchestrator correctly passes source_data through to SQLGenerator.\"\"\"\n from src.plugins.translate.orchestrator import TranslationOrchestrator\n\n # Mock DB session\n db = MagicMock()\n config_manager = MagicMock()\n\n # Create mock records with timestamp source_data\n rec1 = _make_mock_record(\n target_sql=\"Translated comment 1\",\n report_date=\"1726358400000.0\",\n document_number=\"DOC-001\",\n )\n rec2 = _make_mock_record(\n target_sql=\"Translated comment 2\",\n report_date=\"1726444800000.0\",\n document_number=\"DOC-002\",\n )\n\n # Mock the DB query to return our records\n # Note: orchestrator uses .options(joinedload()) before .filter()\n mock_query = MagicMock()\n mock_query.options.return_value.filter.return_value.all.return_value = [rec1, rec2]\n db.query.return_value = mock_query\n\n # Create mock job\n job = _make_mock_job()\n\n # Create mock run\n run = MagicMock()\n run.id = \"run-test-001\"\n run.job_id = job.id\n\n # Create orchestrator\n orch = TranslationOrchestrator(db, config_manager, \"test-user\")\n\n # Mock the event_log and SupersetSqlLabExecutor\n with patch.object(orch, \"event_log\") as mock_event_log, patch(\n \"src.plugins.translate.orchestrator.SupersetSqlLabExecutor\"\n ) as MockExecutor:\n mock_executor = MagicMock()\n MockExecutor.return_value = mock_executor\n mock_executor.resolve_database_id.return_value = None\n mock_executor.get_database_backend.return_value = None\n mock_executor.execute_and_poll.return_value = {\n \"status\": \"success\",\n \"query_id\": \"q-123\",\n \"rows_affected\": 2,\n }\n\n # Call _generate_and_insert_sql\n result = orch._generate_and_insert_sql(job, run)\n\n # Verify executor was called\n mock_executor.execute_and_poll.assert_called_once()\n\n # Get the SQL that was submitted\n call_args = mock_executor.execute_and_poll.call_args\n submitted_sql = call_args.kwargs.get(\"sql\") or call_args[1].get(\"sql\")\n\n # Verify the SQL contains normalized dates\n assert \"'2024-09-15'\" in submitted_sql, f\"Expected '2024-09-15' in SQL:\\n{submitted_sql}\"\n assert \"'2024-09-16'\" in submitted_sql, f\"Expected '2024-09-16' in SQL:\\n{submitted_sql}\"\n\n # Verify document numbers are preserved\n assert \"'DOC-001'\" in submitted_sql\n assert \"'DOC-002'\" in submitted_sql\n\n # Verify translated text is present\n assert \"'Translated comment 1'\" in submitted_sql\n assert \"'Translated comment 2'\" in submitted_sql\n\n # Verify ClickHouse-specific quoting (backticks)\n assert \"`report_date`\" in submitted_sql\n assert \"`document_number`\" in submitted_sql\n assert \"`comment_text_en`\" in submitted_sql\n\n # Verify result\n assert result[\"status\"] == \"success\"\n\n # endregion test_generate_and_insert_sql_with_timestamps\n# #endregion TestOrchestratorInsertFlow\n" }, { "contract_id": "TestClickHouseEndToEnd", "contract_type": "Class", "file_path": "backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py", - "start_line": 413, - "end_line": 539, + "start_line": 419, + "end_line": 545, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -49135,39 +48793,6 @@ "tier_source": "AutoCalculated", "body": "# #region TestClickHouseEndToEnd [TYPE Class]\n# @BRIEF End-to-end test: generate SQL, verify structure, simulate execution.\nclass TestClickHouseEndToEnd:\n \"\"\"End-to-end verification of ClickHouse INSERT flow.\"\"\"\n\n # region test_full_insert_sql_valid_for_clickhouse [TYPE Function]\n # @BRIEF Generated SQL is valid ClickHouse INSERT with proper date formatting.\n def test_full_insert_sql_valid_for_clickhouse(self) -> None:\n \"\"\"Simulate the full flow: records -> SQL generation -> verification.\"\"\"\n # Simulate what the orchestrator does\n records = [\n _make_mock_record(\n target_sql=\"Comment about supply chain\",\n report_date=\"1726358400000.0\",\n document_number=\"INV-2024-001\",\n ),\n _make_mock_record(\n target_sql=\"Payment terms description\",\n report_date=\"1726444800000.0\",\n document_number=\"INV-2024-002\",\n ),\n _make_mock_record(\n target_sql=\"Delivery schedule notes\",\n report_date=\"1726531200000.0\",\n document_number=\"INV-2024-003\",\n ),\n ]\n\n # Build rows_for_sql (same logic as orchestrator._generate_and_insert_sql)\n job = _make_mock_job()\n columns = []\n if job.translation_column:\n columns.append(job.translation_column)\n if job.target_key_cols:\n for k in job.target_key_cols:\n if k not in columns:\n columns.append(k)\n\n rows_for_sql = []\n for rec in records:\n row_data = {}\n if job.translation_column:\n row_data[job.translation_column] = rec.target_sql or \"\"\n if job.target_key_cols:\n source_data = rec.source_data or {}\n for k in job.target_key_cols:\n row_data[k] = source_data.get(k, \"\")\n rows_for_sql.append(row_data)\n\n # Generate SQL\n sql, count = SQLGenerator.generate(\n dialect=job.database_dialect or job.target_dialect or \"clickhouse\",\n target_schema=job.target_schema,\n target_table=job.target_table,\n columns=columns,\n rows=rows_for_sql,\n key_columns=job.target_key_cols,\n upsert_strategy=job.upsert_strategy or \"INSERT\",\n )\n\n # Verify SQL structure\n assert count == 3\n assert sql.startswith(\"INSERT INTO\")\n assert \"dm_view\" in sql\n assert \"financial_comments_translated\" in sql\n\n # Verify all dates are normalized\n assert \"'2024-09-15'\" in sql # 1726358400000\n assert \"'2024-09-16'\" in sql # 1726444800000\n assert \"'2024-09-17'\" in sql # 1726531200000\n\n # Verify NO raw timestamps leaked through\n assert \"1726358400000\" not in sql\n assert \"1726444800000\" not in sql\n assert \"1726531200000\" not in sql\n\n # Verify document numbers\n assert \"'INV-2024-001'\" in sql\n assert \"'INV-2024-002'\" in sql\n assert \"'INV-2024-003'\" in sql\n\n # Verify translated texts\n assert \"'Comment about supply chain'\" in sql\n assert \"'Payment terms description'\" in sql\n assert \"'Delivery schedule notes'\" in sql\n\n # Print SQL for manual verification\n print(f\"\\n{'='*60}\")\n print(\"Generated ClickHouse INSERT SQL:\")\n print(f\"{'='*60}\")\n print(sql)\n print(f\"{'='*60}\")\n\n # region test_verification_join_query [TYPE Function]\n # @BRIEF The JOIN verification query that can be run against ClickHouse.\n def test_verification_join_query(self) -> None:\n \"\"\"Generate the verification JOIN query for manual execution.\"\"\"\n join_sql = \"\"\"\nSELECT\n f_a.report_date,\n f_a.document_number,\n comment_text AS comment_text_ru,\n counterparty,\n supply_country,\n f_c.comment_text_en\nFROM dm_view.financial_arrears f_a\nLEFT JOIN dm_view.financial_comments_translated f_c\n ON f_a.report_date::date = f_c.report_date::date\n AND f_a.document_number = f_c.document_number\nWHERE f_c.comment_text_en IS NOT NULL\nLIMIT 10\n\"\"\"\n print(f\"\\n{'='*60}\")\n print(\"Verification JOIN query (run in ClickHouse):\")\n print(f\"{'='*60}\")\n print(join_sql)\n print(f\"{'='*60}\")\n\n # Verify structure\n assert \"f_a.report_date::date = f_c.report_date::date\" in join_sql\n assert \"f_a.document_number = f_c.document_number\" in join_sql\n assert \"dm_view.financial_arrears\" in join_sql\n assert \"dm_view.financial_comments_translated\" in join_sql\n\n # endregion test_full_insert_sql_valid_for_clickhouse\n # endregion test_verification_join_query\n# #endregion TestClickHouseEndToEnd\n" }, - { - "contract_id": "estimate_token_budget", - "contract_type": "Module", - "file_path": "backend/src/plugins/translate/_token_budget.py", - "start_line": 1, - "end_line": 201, - "tier": "TIER_2", - "complexity": 3, - "metadata": { - "COMPLEXITY": 3, - "LAYER": "Domain", - "PURPOSE": "Calculate safe batch_size and max_tokens for LLM translation calls based on actual content length and model context window limits.", - "RATIONALE": "Prevents LLM truncation (finish_reason=length) by sizing batches within context limits." - }, - "relations": [ - { - "source_id": "estimate_token_budget", - "relation_type": "DEPENDS_ON", - "target_id": "TranslationPreview:Module", - "target_ref": "[TranslationPreview:Module]" - }, - { - "source_id": "estimate_token_budget", - "relation_type": "DEPENDS_ON", - "target_id": "TranslationExecutor:Module", - "target_ref": "[TranslationExecutor:Module]" - } - ], - "schema_warnings": [], - "anchor_syntax": "region", - "tier_source": "AutoCalculated", - "body": "# #region estimate_token_budget [C:3] [TYPE Module] [SEMANTICS translate, token, budget, estimation, llm]\n# @BRIEF Calculate safe batch_size and max_tokens for LLM translation calls based on actual content length and model context window limits.\n# @LAYER: Domain\n# @RELATION DEPENDS_ON -> [TranslationPreview:Module]\n# @RELATION DEPENDS_ON -> [TranslationExecutor:Module]\n# @RATIONALE: Prevents LLM truncation (finish_reason=length) by sizing batches within context limits.\n# DeepSeek v4 Flash supports up to 64K context window; output is limited by max_tokens.\n# @REJECTED: External tokenizer library — would introduce heavy dependency for estimation only.\n# Fixed batch_size of 50 — causes truncation on long-content rows.\n\n# #region DEFAULT_CONTEXT_WINDOW [TYPE Constant]\n# @BRIEF Default context window for DeepSeek v4 Flash: up to 64K tokens.\nDEFAULT_CONTEXT_WINDOW = 64000\n# #endregion DEFAULT_CONTEXT_WINDOW\n\n# #region DEFAULT_MAX_OUTPUT_TOKENS [TYPE Constant]\n# @BRIEF Default max_tokens setting for LLM output (8192 tokens).\nDEFAULT_MAX_OUTPUT_TOKENS = 8192\n# #endregion DEFAULT_MAX_OUTPUT_TOKENS\n\n# #region REASONING_OVERHEAD [TYPE Constant]\n# @BRIEF CoT reasoning overhead tokens for DeepSeek models (~2000 tokens for chain-of-thought).\nREASONING_OVERHEAD = 2000\n# #endregion REASONING_OVERHEAD\n\n# #region OUTPUT_PER_ROW_PER_LANG [TYPE Constant]\n# @BRIEF Estimated output tokens per row per language in JSON response format.\nOUTPUT_PER_ROW_PER_LANG = 60\n# #endregion OUTPUT_PER_ROW_PER_LANG\n\n# #region PROMPT_BASE_TOKENS [TYPE Constant]\n# @BRIEF Base tokens for system prompt + instructions + JSON format specification.\nPROMPT_BASE_TOKENS = 300\n# #endregion PROMPT_BASE_TOKENS\n\n# #region DICT_TOKENS_PER_ENTRY [TYPE Constant]\n# @BRIEF Estimated tokens per dictionary entry in the glossary section.\nDICT_TOKENS_PER_ENTRY = 20\n# #endregion DICT_TOKENS_PER_ENTRY\n\n# #region DICT_TOKENS_MAX [TYPE Constant]\n# @BRIEF Cap for dictionary tokens in estimation to avoid overestimating.\nDICT_TOKENS_MAX = 5000\n# #endregion DICT_TOKENS_MAX\n\n# #region CHARS_PER_TOKEN_MIXED [TYPE Constant]\n# @BRIEF Characters per token for mixed Russian/English text (empirical ~2.2 for mixed, ~2 for Russian, ~4 for English).\nCHARS_PER_TOKEN_MIXED = 2.2\n# #endregion CHARS_PER_TOKEN_MIXED\n\n# #region MIN_MAX_TOKENS [TYPE Constant]\n# @BRIEF Minimum max_tokens to allow (4096 ensures reasonable output even for small batches).\nMIN_MAX_TOKENS = 4096\n# #endregion MIN_MAX_TOKENS\n\n# #region MAX_OUTPUT_HEADROOM [TYPE Constant]\n# @BRIEF Extra headroom added to max_output_needed beyond the estimate (1000 tokens buffer).\nMAX_OUTPUT_HEADROOM = 1000\n# #endregion MAX_OUTPUT_HEADROOM\n\n\n# region _count_rows_that_fit [TYPE Function]\n# @BRIEF Count how many rows fit within the available input budget.\n# @PRE: input_per_row is non-empty; available_budget > 0.\n# @POST: Returns (safe_count, total_input_tokens).\ndef _count_rows_that_fit(\n input_per_row: list[int],\n available_budget: int,\n) -> tuple[int, int]:\n \"\"\"Count consecutive rows that fit within available_budget.\n\n Returns:\n (safe_count, total_input_tokens): Number of rows and their total tokens.\n \"\"\"\n running_total = 0\n safe_size = 0\n for tokens in input_per_row:\n if running_total + tokens + REASONING_OVERHEAD < available_budget:\n running_total += tokens\n safe_size += 1\n else:\n break\n safe_size = max(safe_size, 1)\n return safe_size, running_total\n# endregion _count_rows_that_fit\n\n\n# region estimate_token_budget [C:3] [TYPE Function]\n# @BRIEF Estimate token budget for a batch of source rows and return safe batch parameters.\n# @PRE: source_rows is a list of dicts (can be empty). target_languages is a non-empty list.\n# @POST: Returns dict with batch_size_adjusted, estimated_input_tokens, estimated_output_tokens, max_output_needed, warning.\n# @RATIONALE: Uses character-count heuristics (chars/2.2 for mixed text) since exact tokenization\n# depends on the LLM model. Estimates are intentionally conservative to prevent truncation.\n# @REJECTED: Using tiktoken or similar tokenizer — would introduce a heavy dependency and still\n# not match DeepSeek's tokenizer exactly.\ndef estimate_token_budget(\n source_rows: list[dict],\n target_languages: list[str],\n source_column: str = \"source_text\",\n context_columns: list[str] | None = None,\n dictionary_entries: list | None = None,\n batch_size: int | None = None,\n context_window: int = DEFAULT_CONTEXT_WINDOW,\n max_output_tokens: int = DEFAULT_MAX_OUTPUT_TOKENS,\n) -> dict:\n \"\"\"Estimate token budget and return safe batch parameters.\n\n Args:\n source_rows: List of row dicts with source text.\n target_languages: List of target language codes.\n source_column: Key for the source text in each row dict.\n context_columns: Optional list of keys for context columns.\n dictionary_entries: Optional list of dictionary entries for glossary.\n batch_size: Desired batch size. If None, auto-calculate max safe size.\n context_window: Model context window (default 64000 for DeepSeek v4 Flash).\n max_output_tokens: Hard max output tokens limit (default 8192).\n\n Returns:\n dict with:\n batch_size_adjusted: Safe batch size (may be less than requested).\n estimated_input_tokens: Total estimated input tokens for the batch.\n estimated_output_tokens: Total estimated output tokens.\n max_output_needed: Recommended max_tokens for this batch.\n warning: str | None if batch was reduced.\n \"\"\"\n if not target_languages:\n target_languages = [\"en\"]\n\n num_languages = len(target_languages)\n\n # 1. Estimate tokens per row\n input_per_row = []\n limit = batch_size if batch_size else len(source_rows)\n for i, row in enumerate(source_rows):\n if i >= limit:\n break\n text = str(row.get(source_column, \"\") or \"\")\n # Use ~2.2 chars per token for mixed Russian/English text\n estimated_tokens = max(1, int(len(text) / CHARS_PER_TOKEN_MIXED))\n # Add context columns\n if context_columns:\n for col in context_columns:\n val = str(row.get(col, \"\") or \"\")\n estimated_tokens += max(1, int(len(val) / CHARS_PER_TOKEN_MIXED))\n input_per_row.append(estimated_tokens)\n\n # 2. Calculate dictionary tokens\n dict_tokens = 0\n if dictionary_entries:\n dict_tokens = min(\n len(dictionary_entries) * DICT_TOKENS_PER_ENTRY,\n DICT_TOKENS_MAX,\n )\n\n prompt_tokens = PROMPT_BASE_TOKENS + dict_tokens\n available_input_budget = context_window - max_output_tokens\n\n # 3. Calculate safe batch size using shared helper\n safe_size, input_total = _count_rows_that_fit(input_per_row, available_input_budget)\n estimated_input = prompt_tokens + input_total\n\n # If batch_size was specified and we reduced it, recalculate\n if batch_size and safe_size < batch_size:\n # Ensure at minimum one row even for huge content\n safe_size = max(safe_size, 1)\n _, truncated_total = _count_rows_that_fit(\n input_per_row[:batch_size], available_input_budget,\n )\n estimated_input = prompt_tokens + truncated_total\n\n # 4. Estimate output tokens\n estimated_output = (\n safe_size * num_languages * OUTPUT_PER_ROW_PER_LANG + REASONING_OVERHEAD\n )\n\n # 5. Calculate recommended max_tokens\n max_output_needed = min(\n estimated_output + MAX_OUTPUT_HEADROOM,\n context_window - estimated_input,\n )\n max_output_needed = max(max_output_needed, MIN_MAX_TOKENS)\n max_output_needed = min(max_output_needed, max_output_tokens)\n\n # 6. Generate warning if batch was reduced\n warning = None\n if batch_size and safe_size < batch_size:\n total_estimated = estimated_input + max_output_needed\n warning = (\n f\"Reduced batch size from {batch_size} to {safe_size} \"\n f\"(estimated {total_estimated} tokens vs {context_window} window)\"\n )\n\n return {\n \"batch_size_adjusted\": safe_size,\n \"estimated_input_tokens\": estimated_input,\n \"estimated_output_tokens\": estimated_output,\n \"max_output_needed\": max_output_needed,\n \"warning\": warning,\n }\n# endregion estimate_token_budget\n# #endregion estimate_token_budget\n" - }, { "contract_id": "DEFAULT_CONTEXT_WINDOW", "contract_type": "Constant", @@ -49176,42 +48801,12 @@ "end_line": 14, "tier": "TIER_1", "complexity": 1, - "metadata": { - "PURPOSE": "Default context window for DeepSeek v4 Flash: up to 64K tokens." - }, + "metadata": {}, "relations": [], - "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "PURPOSE", - "message": "@PURPOSE is not allowed for contract type 'Constant'", - "detail": { - "actual_type": "Constant", - "allowed_types": [ - "Module", - "Function", - "Class", - "Component", - "Block", - "ADR", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PURPOSE", - "message": "@PURPOSE is forbidden for contract type 'Constant' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Constant" - } - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region DEFAULT_CONTEXT_WINDOW [TYPE Constant]\n# @BRIEF Default context window for DeepSeek v4 Flash: up to 64K tokens.\nDEFAULT_CONTEXT_WINDOW = 64000\n# #endregion DEFAULT_CONTEXT_WINDOW\n" + "body": "# #region DEFAULT_CONTEXT_WINDOW [TYPE Constant]\n\nDEFAULT_CONTEXT_WINDOW = 64000\n# #endregion DEFAULT_CONTEXT_WINDOW\n" }, { "contract_id": "DEFAULT_MAX_OUTPUT_TOKENS", @@ -49221,42 +48816,12 @@ "end_line": 19, "tier": "TIER_1", "complexity": 1, - "metadata": { - "PURPOSE": "Default max_tokens setting for LLM output (8192 tokens)." - }, + "metadata": {}, "relations": [], - "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "PURPOSE", - "message": "@PURPOSE is not allowed for contract type 'Constant'", - "detail": { - "actual_type": "Constant", - "allowed_types": [ - "Module", - "Function", - "Class", - "Component", - "Block", - "ADR", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PURPOSE", - "message": "@PURPOSE is forbidden for contract type 'Constant' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Constant" - } - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region DEFAULT_MAX_OUTPUT_TOKENS [TYPE Constant]\n# @BRIEF Default max_tokens setting for LLM output (8192 tokens).\nDEFAULT_MAX_OUTPUT_TOKENS = 8192\n# #endregion DEFAULT_MAX_OUTPUT_TOKENS\n" + "body": "# #region DEFAULT_MAX_OUTPUT_TOKENS [TYPE Constant]\n\nDEFAULT_MAX_OUTPUT_TOKENS = 16384\n# #endregion DEFAULT_MAX_OUTPUT_TOKENS\n" }, { "contract_id": "REASONING_OVERHEAD", @@ -49266,357 +48831,147 @@ "end_line": 24, "tier": "TIER_1", "complexity": 1, - "metadata": { - "PURPOSE": "CoT reasoning overhead tokens for DeepSeek models (~2000 tokens for chain-of-thought)." - }, + "metadata": {}, "relations": [], - "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "PURPOSE", - "message": "@PURPOSE is not allowed for contract type 'Constant'", - "detail": { - "actual_type": "Constant", - "allowed_types": [ - "Module", - "Function", - "Class", - "Component", - "Block", - "ADR", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PURPOSE", - "message": "@PURPOSE is forbidden for contract type 'Constant' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Constant" - } - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region REASONING_OVERHEAD [TYPE Constant]\n# @BRIEF CoT reasoning overhead tokens for DeepSeek models (~2000 tokens for chain-of-thought).\nREASONING_OVERHEAD = 2000\n# #endregion REASONING_OVERHEAD\n" + "body": "# #region REASONING_OVERHEAD [TYPE Constant]\n\nREASONING_OVERHEAD = 2000\n# #endregion REASONING_OVERHEAD\n" + }, + { + "contract_id": "PROVIDER_DEFAULTS", + "contract_type": "Constant", + "file_path": "backend/src/plugins/translate/_token_budget.py", + "start_line": 26, + "end_line": 40, + "tier": "TIER_1", + "complexity": 1, + "metadata": {}, + "relations": [], + "schema_warnings": [], + "anchor_syntax": "region", + "tier_source": "AutoCalculated", + "body": "# #region PROVIDER_DEFAULTS [TYPE Constant]\n\n# Maps model name (or \"default\" fallback) to capacity limits.\n# @RATIONALE Different providers have drastically different context windows and\n# output limits. Using a single default for all causes either wasted\n# capacity (underestimation) or truncation (overestimation).\nPROVIDER_DEFAULTS: dict[str, dict[str, int]] = {\n \"gpt-4o-mini\": {\"context_window\": 128000, \"max_output_tokens\": 16384},\n \"gpt-4o\": {\"context_window\": 128000, \"max_output_tokens\": 16384},\n \"o1-mini\": {\"context_window\": 128000, \"max_output_tokens\": 65536},\n \"claude-3-5-sonnet\": {\"context_window\": 200000, \"max_output_tokens\": 8192},\n \"deepseek-v4-flash\": {\"context_window\": 64000, \"max_output_tokens\": 8192},\n \"default\": {\"context_window\": 64000, \"max_output_tokens\": 16384},\n}\n# #endregion PROVIDER_DEFAULTS\n" }, { "contract_id": "OUTPUT_PER_ROW_PER_LANG", "contract_type": "Constant", "file_path": "backend/src/plugins/translate/_token_budget.py", - "start_line": 26, - "end_line": 29, + "start_line": 42, + "end_line": 46, "tier": "TIER_1", "complexity": 1, - "metadata": { - "PURPOSE": "Estimated output tokens per row per language in JSON response format." - }, + "metadata": {}, "relations": [], - "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "PURPOSE", - "message": "@PURPOSE is not allowed for contract type 'Constant'", - "detail": { - "actual_type": "Constant", - "allowed_types": [ - "Module", - "Function", - "Class", - "Component", - "Block", - "ADR", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PURPOSE", - "message": "@PURPOSE is forbidden for contract type 'Constant' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Constant" - } - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region OUTPUT_PER_ROW_PER_LANG [TYPE Constant]\n# @BRIEF Estimated output tokens per row per language in JSON response format.\nOUTPUT_PER_ROW_PER_LANG = 60\n# #endregion OUTPUT_PER_ROW_PER_LANG\n" + "body": "# #region OUTPUT_PER_ROW_PER_LANG [TYPE Constant]\n\n# Increased from 60 to 120 because SQL/dashboard text and JSON structure need more.\nOUTPUT_PER_ROW_PER_LANG = 120\n# #endregion OUTPUT_PER_ROW_PER_LANG\n" + }, + { + "contract_id": "JSON_OVERHEAD_PER_ROW", + "contract_type": "Constant", + "file_path": "backend/src/plugins/translate/_token_budget.py", + "start_line": 48, + "end_line": 51, + "tier": "TIER_1", + "complexity": 1, + "metadata": {}, + "relations": [], + "schema_warnings": [], + "anchor_syntax": "region", + "tier_source": "AutoCalculated", + "body": "# #region JSON_OVERHEAD_PER_ROW [TYPE Constant]\n\nJSON_OVERHEAD_PER_ROW = 50\n# #endregion JSON_OVERHEAD_PER_ROW\n" }, { "contract_id": "PROMPT_BASE_TOKENS", "contract_type": "Constant", "file_path": "backend/src/plugins/translate/_token_budget.py", - "start_line": 31, - "end_line": 34, + "start_line": 53, + "end_line": 57, "tier": "TIER_1", "complexity": 1, - "metadata": { - "PURPOSE": "Base tokens for system prompt + instructions + JSON format specification." - }, + "metadata": {}, "relations": [], - "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "PURPOSE", - "message": "@PURPOSE is not allowed for contract type 'Constant'", - "detail": { - "actual_type": "Constant", - "allowed_types": [ - "Module", - "Function", - "Class", - "Component", - "Block", - "ADR", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PURPOSE", - "message": "@PURPOSE is forbidden for contract type 'Constant' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Constant" - } - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region PROMPT_BASE_TOKENS [TYPE Constant]\n# @BRIEF Base tokens for system prompt + instructions + JSON format specification.\nPROMPT_BASE_TOKENS = 300\n# #endregion PROMPT_BASE_TOKENS\n" + "body": "# #region PROMPT_BASE_TOKENS [TYPE Constant]\n\n# Increased from 300 to 600 to account for longer template, system msg, and dict preamble.\nPROMPT_BASE_TOKENS = 600\n# #endregion PROMPT_BASE_TOKENS\n" }, { "contract_id": "DICT_TOKENS_PER_ENTRY", "contract_type": "Constant", "file_path": "backend/src/plugins/translate/_token_budget.py", - "start_line": 36, - "end_line": 39, + "start_line": 59, + "end_line": 62, "tier": "TIER_1", "complexity": 1, - "metadata": { - "PURPOSE": "Estimated tokens per dictionary entry in the glossary section." - }, + "metadata": {}, "relations": [], - "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "PURPOSE", - "message": "@PURPOSE is not allowed for contract type 'Constant'", - "detail": { - "actual_type": "Constant", - "allowed_types": [ - "Module", - "Function", - "Class", - "Component", - "Block", - "ADR", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PURPOSE", - "message": "@PURPOSE is forbidden for contract type 'Constant' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Constant" - } - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region DICT_TOKENS_PER_ENTRY [TYPE Constant]\n# @BRIEF Estimated tokens per dictionary entry in the glossary section.\nDICT_TOKENS_PER_ENTRY = 20\n# #endregion DICT_TOKENS_PER_ENTRY\n" + "body": "# #region DICT_TOKENS_PER_ENTRY [TYPE Constant]\n\nDICT_TOKENS_PER_ENTRY = 20\n# #endregion DICT_TOKENS_PER_ENTRY\n" }, { "contract_id": "DICT_TOKENS_MAX", "contract_type": "Constant", "file_path": "backend/src/plugins/translate/_token_budget.py", - "start_line": 41, - "end_line": 44, + "start_line": 64, + "end_line": 67, "tier": "TIER_1", "complexity": 1, - "metadata": { - "PURPOSE": "Cap for dictionary tokens in estimation to avoid overestimating." - }, + "metadata": {}, "relations": [], - "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "PURPOSE", - "message": "@PURPOSE is not allowed for contract type 'Constant'", - "detail": { - "actual_type": "Constant", - "allowed_types": [ - "Module", - "Function", - "Class", - "Component", - "Block", - "ADR", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PURPOSE", - "message": "@PURPOSE is forbidden for contract type 'Constant' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Constant" - } - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region DICT_TOKENS_MAX [TYPE Constant]\n# @BRIEF Cap for dictionary tokens in estimation to avoid overestimating.\nDICT_TOKENS_MAX = 5000\n# #endregion DICT_TOKENS_MAX\n" + "body": "# #region DICT_TOKENS_MAX [TYPE Constant]\n\nDICT_TOKENS_MAX = 5000\n# #endregion DICT_TOKENS_MAX\n" }, { "contract_id": "CHARS_PER_TOKEN_MIXED", "contract_type": "Constant", "file_path": "backend/src/plugins/translate/_token_budget.py", - "start_line": 46, - "end_line": 49, + "start_line": 69, + "end_line": 72, "tier": "TIER_1", "complexity": 1, - "metadata": { - "PURPOSE": "Characters per token for mixed Russian/English text (empirical ~2.2 for mixed, ~2 for Russian, ~4 for English)." - }, + "metadata": {}, "relations": [], - "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "PURPOSE", - "message": "@PURPOSE is not allowed for contract type 'Constant'", - "detail": { - "actual_type": "Constant", - "allowed_types": [ - "Module", - "Function", - "Class", - "Component", - "Block", - "ADR", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PURPOSE", - "message": "@PURPOSE is forbidden for contract type 'Constant' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Constant" - } - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region CHARS_PER_TOKEN_MIXED [TYPE Constant]\n# @BRIEF Characters per token for mixed Russian/English text (empirical ~2.2 for mixed, ~2 for Russian, ~4 for English).\nCHARS_PER_TOKEN_MIXED = 2.2\n# #endregion CHARS_PER_TOKEN_MIXED\n" + "body": "# #region CHARS_PER_TOKEN_MIXED [TYPE Constant]\n\nCHARS_PER_TOKEN_MIXED = 2.2\n# #endregion CHARS_PER_TOKEN_MIXED\n" }, { "contract_id": "MIN_MAX_TOKENS", "contract_type": "Constant", "file_path": "backend/src/plugins/translate/_token_budget.py", - "start_line": 51, - "end_line": 54, + "start_line": 74, + "end_line": 77, "tier": "TIER_1", "complexity": 1, - "metadata": { - "PURPOSE": "Minimum max_tokens to allow (4096 ensures reasonable output even for small batches)." - }, + "metadata": {}, "relations": [], - "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "PURPOSE", - "message": "@PURPOSE is not allowed for contract type 'Constant'", - "detail": { - "actual_type": "Constant", - "allowed_types": [ - "Module", - "Function", - "Class", - "Component", - "Block", - "ADR", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PURPOSE", - "message": "@PURPOSE is forbidden for contract type 'Constant' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Constant" - } - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region MIN_MAX_TOKENS [TYPE Constant]\n# @BRIEF Minimum max_tokens to allow (4096 ensures reasonable output even for small batches).\nMIN_MAX_TOKENS = 4096\n# #endregion MIN_MAX_TOKENS\n" + "body": "# #region MIN_MAX_TOKENS [TYPE Constant]\n\nMIN_MAX_TOKENS = 4096\n# #endregion MIN_MAX_TOKENS\n" }, { "contract_id": "MAX_OUTPUT_HEADROOM", "contract_type": "Constant", "file_path": "backend/src/plugins/translate/_token_budget.py", - "start_line": 56, - "end_line": 59, + "start_line": 79, + "end_line": 83, "tier": "TIER_1", "complexity": 1, - "metadata": { - "PURPOSE": "Extra headroom added to max_output_needed beyond the estimate (1000 tokens buffer)." - }, + "metadata": {}, "relations": [], - "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "PURPOSE", - "message": "@PURPOSE is not allowed for contract type 'Constant'", - "detail": { - "actual_type": "Constant", - "allowed_types": [ - "Module", - "Function", - "Class", - "Component", - "Block", - "ADR", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PURPOSE", - "message": "@PURPOSE is forbidden for contract type 'Constant' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Constant" - } - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region MAX_OUTPUT_HEADROOM [TYPE Constant]\n# @BRIEF Extra headroom added to max_output_needed beyond the estimate (1000 tokens buffer).\nMAX_OUTPUT_HEADROOM = 1000\n# #endregion MAX_OUTPUT_HEADROOM\n" + "body": "# #region MAX_OUTPUT_HEADROOM [TYPE Constant]\n\n# Increased from 1000 to 3000 because SQL/dashboard text output varies significantly.\nMAX_OUTPUT_HEADROOM = 3000\n# #endregion MAX_OUTPUT_HEADROOM\n" }, { "contract_id": "DictionaryUtils", @@ -49672,104 +49027,12 @@ "tier_source": "AutoCalculated", "body": "# #region _detect_delimiter [TYPE Function]\n# @BRIEF Detect the delimiter used in a CSV/TSV header line.\ndef _detect_delimiter(header_line: str) -> str:\n \"\"\"Detect delimiter by counting tabs vs commas in the first line.\"\"\"\n if not header_line:\n return \",\"\n tab_count = header_line.count(\"\\t\")\n comma_count = header_line.count(\",\")\n return \"\\t\" if tab_count > comma_count else \",\"\n# #endregion _detect_delimiter\n" }, - { - "contract_id": "DictionaryManagerModule", - "contract_type": "Module", - "file_path": "backend/src/plugins/translate/dictionary.py", - "start_line": 1, - "end_line": 1002, - "tier": "TIER_2", - "complexity": 4, - "metadata": { - "COMPLEXITY": 4, - "LAYER": "Domain", - "PURPOSE": "Business logic for terminology dictionary management, entry CRUD, CSV/TSV import with conflict detection, and per-batch filtering.", - "RATIONALE": "C4 complexity because dictionary CRUD is stateful with referential integrity enforcement on deletion and unique constraint on normalized source term.", - "REJECTED": "\"Keep both\" as conflict option — UniqueConstraint(dictionary_id, source_term_normalized) prohibits variants; only overwrite/keep existing." - }, - "relations": [ - { - "source_id": "DictionaryManagerModule", - "relation_type": "DEPENDS_ON", - "target_id": "TerminologyDictionary:Class", - "target_ref": "[TerminologyDictionary:Class]" - }, - { - "source_id": "DictionaryManagerModule", - "relation_type": "DEPENDS_ON", - "target_id": "DictionaryEntry:Class", - "target_ref": "[DictionaryEntry:Class]" - }, - { - "source_id": "DictionaryManagerModule", - "relation_type": "DEPENDS_ON", - "target_id": "TranslationJobDictionary:Class", - "target_ref": "[TranslationJobDictionary:Class]" - }, - { - "source_id": "DictionaryManagerModule", - "relation_type": "DEPENDS_ON", - "target_id": "TranslationJob:Class", - "target_ref": "[TranslationJob:Class]" - } - ], - "schema_warnings": [ - { - "code": "missing_required_tag", - "tag": "POST", - "message": "@POST is required for contract type 'Module' at C4", - "detail": { - "actual_complexity": 4, - "contract_type": "Module" - } - }, - { - "code": "missing_required_tag", - "tag": "PRE", - "message": "@PRE is required for contract type 'Module' at C4", - "detail": { - "actual_complexity": 4, - "contract_type": "Module" - } - }, - { - "code": "missing_required_tag", - "tag": "SIDE_EFFECT", - "message": "@SIDE_EFFECT is required for contract type 'Module' at C4", - "detail": { - "actual_complexity": 4, - "contract_type": "Module" - } - } - ], - "anchor_syntax": "region", - "tier_source": "AutoCalculated", - "body": "# #region DictionaryManagerModule [C:4] [TYPE Module] [SEMANTICS sqlalchemy, translate, dictionary, batch, term]\n# @BRIEF Business logic for terminology dictionary management, entry CRUD, CSV/TSV import with conflict detection, and per-batch filtering.\n# @LAYER: Domain\n# @RELATION DEPENDS_ON -> [TerminologyDictionary:Class]\n# @RELATION DEPENDS_ON -> [DictionaryEntry:Class]\n# @RELATION DEPENDS_ON -> [TranslationJobDictionary:Class]\n# @RELATION DEPENDS_ON -> [TranslationJob:Class]\n# @RATIONALE: C4 complexity because dictionary CRUD is stateful with referential integrity enforcement on deletion and unique constraint on normalized source term.\n# @REJECTED: Pure C3 CRUD without state guards would allow orphaned job-dictionary links.\n# @REJECTED: \"Keep both\" as conflict option — UniqueConstraint(dictionary_id, source_term_normalized) prohibits variants; only overwrite/keep existing.\n\nimport csv\nimport io\nimport re\nfrom typing import Any\n\nfrom sqlalchemy import func, or_\nfrom sqlalchemy.orm import Session\n\nfrom ...core.logger import belief_scope, logger\nfrom ...models.translate import (\n DictionaryEntry,\n TerminologyDictionary,\n TranslationJob,\n TranslationJobDictionary,\n)\nfrom ._utils import _detect_delimiter, _normalize_term\nfrom .prompt_builder import ContextAwarePromptBuilder\n\n\n# #region _validate_bcp47 [C:2] [TYPE Function] [SEMANTICS validation, bcp47, language]\n# @BRIEF Validate that a language tag is a non-empty BCP-47 string.\ndef _validate_bcp47(tag: str, field_name: str) -> None:\n \"\"\"Validate that tag is a non-empty BCP-47 string (basic check).\"\"\"\n if not tag or not tag.strip():\n raise ValueError(f\"{field_name} must be a non-empty BCP-47 language tag\")\n tag = tag.strip()\n # Basic BCP-47 validation: must match lang[-script][-region][-variant]* pattern\n import re as _re\n if not _re.match(r'^[a-zA-Z]{2,8}(-[a-zA-Z0-9]{1,8})*$', tag):\n raise ValueError(\n f\"{field_name} is not a valid BCP-47 tag: '{tag}'. \"\n \"Expected format like 'en', 'ru', 'zh-CN', 'pt-BR'.\"\n )\n# #endregion _validate_bcp47\n\n\n# #region DictionaryManager [C:4] [TYPE Class]\n# @BRIEF Manages terminology dictionaries and their entries with referential integrity.\n# @PRE: Database session is open and valid.\n# @POST: Dictionary and entry mutations are persisted with conflict detection.\n# @SIDE_EFFECT: Creates, updates, deletes TerminologyDictionary and DictionaryEntry rows; enforces deletion guards.\nclass DictionaryManager:\n # region DictionaryManager.create_dictionary [TYPE Function]\n # @PURPOSE: Create a new terminology dictionary (language independent at dictionary level; language pairs are per-entry).\n # @PRE: name is provided.\n # @POST: New TerminologyDictionary row is created and returned.\n @staticmethod\n def create_dictionary(\n db: Session, name: str,\n source_dialect: str = \"\",\n target_dialect: str = \"\",\n created_by: str | None = None, description: str | None = None,\n is_active: bool = True,\n ) -> TerminologyDictionary:\n with belief_scope(\"DictionaryManager.create_dictionary\"):\n logger.reason(\"Creating dictionary\", {\"name\": name, \"source\": source_dialect, \"target\": target_dialect})\n dictionary = TerminologyDictionary(\n name=name,\n description=description,\n source_dialect=source_dialect or \"\",\n target_dialect=target_dialect or \"\",\n is_active=is_active,\n created_by=created_by,\n )\n db.add(dictionary)\n db.commit()\n db.refresh(dictionary)\n logger.reflect(\"Dictionary created\", {\"id\": dictionary.id})\n return dictionary\n # endregion DictionaryManager.create_dictionary\n\n # region DictionaryManager.update_dictionary [TYPE Function]\n # @PURPOSE: Update an existing terminology dictionary.\n # @PRE: dict_id exists in terminology_dictionaries table.\n # @POST: Dictionary metadata is updated and returned.\n @staticmethod\n def update_dictionary(\n db: Session, dict_id: str, name: str | None = None,\n description: str | None = None, source_dialect: str | None = None,\n target_dialect: str | None = None, is_active: bool | None = None,\n ) -> TerminologyDictionary:\n with belief_scope(\"DictionaryManager.update_dictionary\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n logger.reason(\"Updating dictionary\", {\"id\": dict_id})\n if name is not None:\n dictionary.name = name\n if description is not None:\n dictionary.description = description\n if source_dialect is not None:\n dictionary.source_dialect = source_dialect\n if target_dialect is not None:\n dictionary.target_dialect = target_dialect\n if is_active is not None:\n dictionary.is_active = is_active\n db.commit()\n db.refresh(dictionary)\n logger.reflect(\"Dictionary updated\", {\"id\": dictionary.id})\n return dictionary\n # endregion DictionaryManager.update_dictionary\n\n # region DictionaryManager.delete_dictionary [TYPE Function]\n # @PURPOSE: Delete a dictionary, blocked if attached to active/scheduled jobs.\n # @PRE: dict_id exists.\n # @POST: Dictionary and its entries are deleted, unless attached to ACTIVE/READY/RUNNING/SCHEDULED jobs.\n # @SIDE_EFFECT: Deletes TerminologyDictionary row and all DictionaryEntry rows.\n @staticmethod\n def delete_dictionary(db: Session, dict_id: str) -> None:\n with belief_scope(\"DictionaryManager.delete_dictionary\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n\n # Check for attached active/scheduled jobs\n blocked_statuses = [\"ACTIVE\", \"READY\", \"RUNNING\", \"SCHEDULED\"]\n attached_jobs = (\n db.query(TranslationJobDictionary)\n .filter(\n TranslationJobDictionary.dictionary_id == dict_id,\n TranslationJobDictionary.job_id.in_(\n db.query(TranslationJob.id).filter(\n TranslationJob.status.in_(blocked_statuses)\n )\n ),\n )\n .count()\n )\n\n if attached_jobs > 0:\n logger.explore(\"Delete blocked: dictionary attached to active jobs\", {\"dict_id\": dict_id, \"jobs\": attached_jobs})\n raise ValueError(\n f\"Cannot delete dictionary attached to {attached_jobs} active/scheduled job(s). \"\n \"Remove dictionary associations from jobs first.\"\n )\n\n logger.reason(\"Deleting dictionary\", {\"id\": dict_id})\n # Delete entries and job-dictionary links first\n db.query(DictionaryEntry).filter(DictionaryEntry.dictionary_id == dict_id).delete()\n db.query(TranslationJobDictionary).filter(TranslationJobDictionary.dictionary_id == dict_id).delete()\n db.delete(dictionary)\n db.commit()\n logger.reflect(\"Dictionary deleted\", {\"id\": dict_id})\n # endregion DictionaryManager.delete_dictionary\n\n # region DictionaryManager.get_dictionary [TYPE Function]\n # @PURPOSE: Get a single dictionary by ID with entry count.\n # @PRE: dict_id exists.\n # @POST: Returns dict with dictionary + entry_count or raises ValueError.\n @staticmethod\n def get_dictionary(db: Session, dict_id: str) -> TerminologyDictionary:\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n return dictionary\n # endregion DictionaryManager.get_dictionary\n\n # region DictionaryManager.list_dictionaries [TYPE Function]\n # @PURPOSE: List dictionaries with pagination and entry counts.\n # @PRE: page >= 1, page_size between 1 and 100.\n # @POST: Returns (list of dicts, total_count).\n @staticmethod\n def list_dictionaries(\n db: Session, page: int = 1, page_size: int = 20,\n ) -> tuple[list[TerminologyDictionary], int]:\n total = db.query(func.count(TerminologyDictionary.id)).scalar() or 0\n dictionaries = (\n db.query(TerminologyDictionary)\n .order_by(TerminologyDictionary.created_at.desc())\n .offset((page - 1) * page_size)\n .limit(page_size)\n .all()\n )\n return dictionaries, total\n # endregion DictionaryManager.list_dictionaries\n\n # region DictionaryManager.add_entry [TYPE Function]\n # @PURPOSE: Add an entry to a dictionary with language-pair-aware uniqueness validation.\n # @PRE: dict_id exists. source_term, target_term are non-empty. source_language, target_language are valid BCP-47.\n # @POST: New DictionaryEntry row is created or raises on duplicate.\n @staticmethod\n def add_entry(\n db: Session, dict_id: str, source_term: str, target_term: str,\n context_notes: str | None = None,\n source_language: str = \"und\",\n target_language: str = \"und\",\n ) -> DictionaryEntry:\n with belief_scope(\"DictionaryManager.add_entry\"):\n _validate_bcp47(source_language, \"source_language\")\n _validate_bcp47(target_language, \"target_language\")\n\n normalized = _normalize_term(source_term)\n # Uniqueness is now (dictionary_id, source_term_normalized, source_language, target_language)\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == source_language,\n DictionaryEntry.target_language == target_language,\n )\n .first()\n )\n if existing:\n raise ValueError(\n f\"Duplicate entry: '{source_term}' (lang: {source_language}→{target_language}) \"\n f\"already exists in this dictionary (id={existing.id}). \"\n \"Use overwrite or keep_existing conflict mode.\"\n )\n\n logger.reason(\"Adding dictionary entry\", {\"dict_id\": dict_id, \"term\": source_term, \"src_lang\": source_language, \"tgt_lang\": target_language})\n entry = DictionaryEntry(\n dictionary_id=dict_id,\n source_term=source_term.strip(),\n source_term_normalized=normalized,\n target_term=target_term.strip(),\n context_notes=context_notes.strip() if context_notes else None,\n source_language=source_language.strip(),\n target_language=target_language.strip(),\n )\n db.add(entry)\n db.commit()\n db.refresh(entry)\n logger.reflect(\"Entry added\", {\"entry_id\": entry.id, \"src_lang\": source_language, \"tgt_lang\": target_language})\n return entry\n # endregion DictionaryManager.add_entry\n\n # region DictionaryManager.edit_entry [TYPE Function]\n # @PURPOSE: Edit an existing dictionary entry with language-pair-aware duplicate check.\n # @PRE: entry_id exists.\n # @POST: Entry fields are updated.\n @staticmethod\n def edit_entry(\n db: Session, entry_id: str, source_term: str | None = None,\n target_term: str | None = None, context_notes: str | None = None,\n source_language: str | None = None,\n target_language: str | None = None,\n ) -> DictionaryEntry:\n with belief_scope(\"DictionaryManager.edit_entry\"):\n entry = db.query(DictionaryEntry).filter(DictionaryEntry.id == entry_id).first()\n if not entry:\n raise ValueError(f\"Entry not found: {entry_id}\")\n\n logger.reason(\"Editing dictionary entry\", {\"entry_id\": entry_id})\n\n if source_language is not None:\n _validate_bcp47(source_language, \"source_language\")\n entry.source_language = source_language.strip()\n if target_language is not None:\n _validate_bcp47(target_language, \"target_language\")\n entry.target_language = target_language.strip()\n\n if source_term is not None:\n normalized = _normalize_term(source_term)\n # Check uniqueness within the same dictionary + language pair\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == entry.dictionary_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == entry.source_language,\n DictionaryEntry.target_language == entry.target_language,\n DictionaryEntry.id != entry_id,\n )\n .first()\n )\n if existing:\n raise ValueError(\n f\"Duplicate entry: '{source_term}' already exists in this dictionary \"\n f\"(id={existing.id}).\"\n )\n entry.source_term = source_term.strip()\n entry.source_term_normalized = normalized\n if target_term is not None:\n entry.target_term = target_term.strip()\n if context_notes is not None:\n entry.context_notes = context_notes.strip() if context_notes else None\n db.commit()\n db.refresh(entry)\n logger.reflect(\"Entry updated\", {\"entry_id\": entry.id})\n return entry\n # endregion DictionaryManager.edit_entry\n\n # region DictionaryManager.delete_entry [TYPE Function]\n # @PURPOSE: Delete a single dictionary entry.\n # @PRE: entry_id exists.\n # @POST: Entry is deleted.\n @staticmethod\n def delete_entry(db: Session, entry_id: str) -> None:\n with belief_scope(\"DictionaryManager.delete_entry\"):\n entry = db.query(DictionaryEntry).filter(DictionaryEntry.id == entry_id).first()\n if not entry:\n raise ValueError(f\"Entry not found: {entry_id}\")\n logger.reason(\"Deleting dictionary entry\", {\"entry_id\": entry_id})\n db.delete(entry)\n db.commit()\n logger.reflect(\"Entry deleted\", {\"entry_id\": entry_id})\n # endregion DictionaryManager.delete_entry\n\n # region DictionaryManager.clear_entries [TYPE Function]\n # @PURPOSE: Delete all entries for a dictionary.\n # @PRE: dict_id exists.\n # @POST: All entries for the dictionary are deleted.\n @staticmethod\n def clear_entries(db: Session, dict_id: str) -> int:\n with belief_scope(\"DictionaryManager.clear_entries\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n logger.reason(\"Clearing all entries\", {\"dict_id\": dict_id})\n deleted = db.query(DictionaryEntry).filter(DictionaryEntry.dictionary_id == dict_id).delete()\n db.commit()\n logger.reflect(\"Entries cleared\", {\"dict_id\": dict_id, \"count\": deleted})\n return deleted\n # endregion DictionaryManager.clear_entries\n\n # region DictionaryManager.list_entries [TYPE Function]\n # @PURPOSE: List entries for a dictionary with pagination.\n # @PRE: dict_id exists.\n # @POST: Returns (list of entries, total_count).\n @staticmethod\n def list_entries(\n db: Session, dict_id: str, page: int = 1, page_size: int = 50,\n ) -> tuple[list[DictionaryEntry], int]:\n total = (\n db.query(func.count(DictionaryEntry.id))\n .filter(DictionaryEntry.dictionary_id == dict_id)\n .scalar()\n or 0\n )\n entries = (\n db.query(DictionaryEntry)\n .filter(DictionaryEntry.dictionary_id == dict_id)\n .order_by(DictionaryEntry.source_term.asc())\n .offset((page - 1) * page_size)\n .limit(page_size)\n .all()\n )\n return entries, total\n # endregion DictionaryManager.list_entries\n\n # region DictionaryManager.import_entries [TYPE Function]\n # @PURPOSE: Import entries from CSV/TSV content with duplicate detection and conflict resolution.\n # @PRE: content is valid CSV or TSV. dict_id exists.\n # @POST: Entries are created/updated/skipped per conflict mode. Returns result summary.\n # @SIDE_EFFECT: Batch-inserts or updates DictionaryEntry rows.\n @staticmethod\n def import_entries(\n db: Session, dict_id: str, content: str,\n delimiter: str | None = None,\n on_conflict: str = \"overwrite\",\n preview_only: bool = False,\n default_source_language: str | None = None,\n default_target_language: str | None = None,\n ) -> dict[str, Any]:\n with belief_scope(\"DictionaryManager.import_entries\"):\n # Validate dictionary\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n\n # Detect delimiter if not specified\n if not delimiter:\n delimiter = _detect_delimiter(content)\n logger.reason(\"Detected delimiter\", {\"delimiter\": repr(delimiter)})\n\n if delimiter not in (\",\", \"\\t\"):\n raise ValueError(f\"Unsupported delimiter: {delimiter!r}. Use ',' or '\\\\t'.\")\n\n # Parse content\n reader = csv.DictReader(io.StringIO(content), delimiter=delimiter)\n required_fields = {\"source_term\", \"target_term\"}\n if not reader.fieldnames or not required_fields.issubset(reader.fieldnames):\n raise ValueError(\n f\"CSV/TSV must have at least 'source_term' and 'target_term' columns. \"\n f\"Got: {reader.fieldnames}\"\n )\n\n result: dict[str, Any] = {\n \"total\": 0,\n \"created\": 0,\n \"updated\": 0,\n \"skipped\": 0,\n \"errors\": [],\n \"preview\": [],\n }\n\n rows = list(reader)\n result[\"total\"] = len(rows)\n\n for row_idx, row in enumerate(rows):\n try:\n source_term = row.get(\"source_term\", \"\").strip()\n target_term = row.get(\"target_term\", \"\").strip()\n context_notes = row.get(\"context_notes\", \"\").strip() or None\n source_language = row.get(\"source_language\", \"\").strip() or default_source_language or \"und\"\n target_language = row.get(\"target_language\", \"\").strip() or default_target_language or \"und\"\n\n if not source_term or not target_term:\n result[\"errors\"].append({\n \"line\": row_idx + 2, # +2 for header and 1-indexed\n \"error\": \"Both source_term and target_term are required\",\n \"row\": row,\n })\n continue\n\n normalized = _normalize_term(source_term)\n\n if preview_only:\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == source_language,\n DictionaryEntry.target_language == target_language,\n )\n .first()\n )\n preview_row = {\n \"line\": row_idx + 2,\n \"source_term\": source_term,\n \"target_term\": target_term,\n \"context_notes\": context_notes,\n \"source_language\": source_language,\n \"target_language\": target_language,\n \"is_conflict\": existing is not None,\n \"existing_target_term\": existing.target_term if existing else None,\n }\n result[\"preview\"].append(preview_row)\n continue\n\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == source_language,\n DictionaryEntry.target_language == target_language,\n )\n .first()\n )\n\n if existing:\n if on_conflict == \"overwrite\":\n existing.source_term = source_term\n existing.target_term = target_term\n existing.context_notes = context_notes\n existing.source_language = source_language\n existing.target_language = target_language\n result[\"updated\"] += 1\n elif on_conflict == \"keep_existing\":\n result[\"skipped\"] += 1\n else: # cancel\n result[\"errors\"].append({\n \"line\": row_idx + 2,\n \"error\": f\"Conflict on '{source_term}' and on_conflict='cancel'\",\n \"row\": row,\n })\n continue\n else:\n entry = DictionaryEntry(\n dictionary_id=dict_id,\n source_term=source_term,\n source_term_normalized=normalized,\n target_term=target_term,\n context_notes=context_notes,\n source_language=source_language,\n target_language=target_language,\n )\n db.add(entry)\n result[\"created\"] += 1\n\n except Exception as e:\n result[\"errors\"].append({\n \"line\": row_idx + 2,\n \"error\": str(e),\n \"row\": row,\n })\n\n if not preview_only:\n db.commit()\n\n logger.reflect(\"Import complete\", {\n \"dict_id\": dict_id,\n \"total\": result[\"total\"],\n \"created\": result[\"created\"],\n \"updated\": result[\"updated\"],\n \"skipped\": result[\"skipped\"],\n \"errors\": len(result[\"errors\"]),\n })\n return result\n # endregion DictionaryManager.import_entries\n\n # region DictionaryManager.export_entries [TYPE Function]\n # @PURPOSE: Export all entries as CSV string with language columns.\n # @PRE: dict_id exists.\n # @POST: Returns CSV string with header: source_term, target_term, source_language, target_language, context_notes, context_data, usage_notes.\n @staticmethod\n def export_entries(\n db: Session, dict_id: str, delimiter: str = \",\",\n ) -> str:\n with belief_scope(\"DictionaryManager.export_entries\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n\n entries = (\n db.query(DictionaryEntry)\n .filter(DictionaryEntry.dictionary_id == dict_id)\n .order_by(DictionaryEntry.source_term.asc())\n .all()\n )\n\n output = io.StringIO()\n fieldnames = [\n \"source_term\", \"target_term\",\n \"source_language\", \"target_language\",\n \"context_notes\", \"context_data\", \"usage_notes\",\n ]\n writer = csv.DictWriter(output, fieldnames=fieldnames, delimiter=delimiter)\n writer.writeheader()\n\n for entry in entries:\n writer.writerow({\n \"source_term\": entry.source_term,\n \"target_term\": entry.target_term,\n \"source_language\": entry.source_language,\n \"target_language\": entry.target_language,\n \"context_notes\": entry.context_notes or \"\",\n \"context_data\": entry.context_data,\n \"usage_notes\": entry.usage_notes or \"\",\n })\n\n result = output.getvalue()\n logger.reflect(\"Entries exported\", {\"dict_id\": dict_id, \"count\": len(entries), \"delimiter\": repr(delimiter)})\n return result\n # endregion DictionaryManager.export_entries\n\n # region DictionaryManager.migrate_old_entries [TYPE Function]\n # @PURPOSE: Migrate existing single-language dictionary entries to populate source_language and target_language.\n # @PRE: db session is open.\n # @POST: Entries with \"und\" source_language or target_language are updated with inferred values.\n # @SIDE_EFFECT: Updates DictionaryEntry rows in bulk.\n @staticmethod\n def migrate_old_entries(db: Session) -> dict[str, int]:\n with belief_scope(\"DictionaryManager.migrate_old_entries\"):\n logger.reason(\"Starting migration of old dictionary entries\")\n migrated_source = 0\n migrated_target = 0\n skipped = 0\n\n # Find all entries that may need migration (source_language is \"und\" or target_language is \"und\")\n entries = (\n db.query(DictionaryEntry)\n .filter(\n (DictionaryEntry.source_language == \"und\") |\n (DictionaryEntry.target_language == \"und\")\n )\n .all()\n )\n\n for entry in entries:\n # Try to infer source_language from origin_source_language\n if entry.source_language == \"und\":\n if entry.origin_source_language:\n entry.source_language = entry.origin_source_language\n migrated_source += 1\n\n # Note: target_language inference from dictionary-level column was removed\n # because TerminologyDictionary.target_language was deprecated and dropped.\n\n if entry.source_language == \"und\" and entry.target_language == \"und\":\n skipped += 1\n\n db.commit()\n\n logger.reflect(\"Migration complete\", {\n \"migrated_source\": migrated_source,\n \"migrated_target\": migrated_target,\n \"skipped\": skipped,\n \"total_processed\": len(entries),\n })\n return {\n \"migrated_source\": migrated_source,\n \"migrated_target\": migrated_target,\n \"skipped\": skipped,\n \"total_processed\": len(entries),\n }\n # endregion DictionaryManager.migrate_old_entries\n\n # region DictionaryManager.filter_for_batch [TYPE Function]\n # @PURPOSE: Scan batch texts for case-insensitive, word-boundary-aware matches against all dictionaries attached to a job,\n # optionally filtered by language pair. When row_context is provided, computes context-aware priority flags.\n # @PRE: job_id exists and source_texts is a list of strings.\n # @POST: Returns list of matched entries with match info, sorted by priority across attached dictionaries.\n # When row_context is given, each result includes a 'priority_match' boolean.\n # @SIDE_EFFECT: Queries TranslationJobDictionary, TerminologyDictionary, and DictionaryEntry tables.\n @staticmethod\n def filter_for_batch(\n db: Session, source_texts: list[str], job_id: str,\n source_language: str | None = None,\n target_language: str | None = None,\n row_context: dict | None = None,\n ) -> list[dict[str, Any]]:\n with belief_scope(\"DictionaryManager.filter_for_batch\"):\n # Get dictionaries attached to this job\n job_dict_links = (\n db.query(TranslationJobDictionary)\n .filter(TranslationJobDictionary.job_id == job_id)\n .all()\n )\n if not job_dict_links:\n logger.reason(\"No dictionaries attached to job\", {\"job_id\": job_id})\n return []\n\n dict_ids = [jd.dictionary_id for jd in job_dict_links]\n\n # Get all active dictionaries\n dictionaries = (\n db.query(TerminologyDictionary)\n .filter(\n TerminologyDictionary.id.in_(dict_ids),\n TerminologyDictionary.is_active == True,\n )\n .all()\n )\n if not dictionaries:\n return []\n\n # Build dict_id -> dict_name lookup\n dict_map = {d.id: d.name for d in dictionaries}\n\n # Fetch all entries for these dictionaries, ordered by dictionary (priority order from link order)\n all_entries = (\n db.query(DictionaryEntry)\n .filter(DictionaryEntry.dictionary_id.in_(dict_ids))\n .order_by(DictionaryEntry.source_term.asc())\n .all()\n )\n\n if not all_entries:\n return []\n\n # PERFORMANCE NOTE: O(rows × entries) regex matching per batch.\n # Acceptable for current scale (50-100 rows × <1000 entries).\n # For larger batches (>500 rows or >5000 entries), consider\n # replacing with an Aho-Corasick automaton (e.g., pyahocorasick).\n matched: list[dict[str, Any]] = []\n seen_source_match: set = set()\n\n for text_idx, source_text in enumerate(source_texts):\n if not source_text:\n continue\n\n text_lower = source_text.lower()\n\n for entry in all_entries:\n norm = entry.source_term_normalized\n if not norm:\n continue\n\n # Apply language pair filtering\n if source_language is not None:\n src = source_language.strip().lower()\n entry_src = entry.source_language.strip().lower()\n if entry_src != src and entry_src != \"und\":\n continue\n if target_language is not None:\n tgt = target_language.strip().lower()\n entry_tgt = entry.target_language.strip().lower()\n if entry_tgt != tgt:\n continue\n\n # Word-boundary-aware matching\n # Build pattern: \\bterm\\b (case-insensitive)\n # Escape regex special chars in the search term\n escaped = re.escape(norm)\n pattern = re.compile(r\"\\b\" + escaped + r\"\\b\", re.IGNORECASE)\n\n if pattern.search(text_lower):\n match_key = (text_idx, entry.id)\n if match_key not in seen_source_match:\n seen_source_match.add(match_key)\n\n # Compute context-aware priority if row_context is available\n priority_match = False\n if row_context and entry.has_context and entry.context_data:\n similarity = ContextAwarePromptBuilder.compute_context_similarity(\n entry.context_data, row_context\n )\n priority_match = similarity >= 0.5\n\n matched.append({\n \"text_index\": text_idx,\n \"source_text\": source_text,\n \"entry_id\": entry.id,\n \"source_term\": entry.source_term,\n \"source_term_normalized\": entry.source_term_normalized,\n \"target_term\": entry.target_term,\n \"dictionary_id\": entry.dictionary_id,\n \"dictionary_name\": dict_map.get(entry.dictionary_id, \"\"),\n \"context_notes\": entry.context_notes,\n \"context_data\": entry.context_data,\n \"has_context\": entry.has_context,\n \"context_source\": entry.context_source,\n \"usage_notes\": entry.usage_notes,\n \"source_language\": entry.source_language,\n \"target_language\": entry.target_language,\n \"priority_match\": priority_match,\n })\n\n # Sort by dictionary link priority (order of dict_ids from link order)\n dict_priority = {d_id: idx for idx, d_id in enumerate(dict_ids)}\n matched.sort(key=lambda m: (dict_priority.get(m[\"dictionary_id\"], 999), m[\"text_index\"]))\n\n logger.reflect(\"Batch filter match complete\", {\n \"job_id\": job_id,\n \"source_texts\": len(source_texts),\n \"matches\": len(matched),\n \"dictionaries_used\": len(dictionaries),\n \"source_language\": source_language,\n \"target_language\": target_language,\n })\n return matched\n # endregion DictionaryManager.filter_for_batch\n\n\n # region DictionaryManager.submit_correction [TYPE Function]\n # @PURPOSE: Submit a term correction from a run result. Validates language match, detects conflicts.\n # @PRE: source_term, incorrect_target_term, corrected_target_term are non-empty. dict_id exists.\n # @POST: Entry created or updated; origin tracking populated. Returns action + conflict info.\n # @SIDE_EFFECT: Creates/updates DictionaryEntry row.\n @staticmethod\n def submit_correction(\n db: Session,\n dict_id: str,\n source_term: str,\n incorrect_target_term: str,\n corrected_target_term: str,\n origin_run_id: str | None = None,\n origin_row_key: str | None = None,\n origin_user_id: str | None = None,\n on_conflict: str = \"overwrite\",\n context_data: dict[str, Any] | None = None,\n usage_notes: str | None = None,\n keep_context: bool = True,\n ) -> dict[str, Any]:\n with belief_scope(\"DictionaryManager.submit_correction\"):\n # Validate dictionary exists\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary '{dict_id}' not found\")\n\n # Handle keep_context=False (user explicitly removed context)\n effective_context = context_data\n effective_context_source = \"auto\"\n if not keep_context:\n effective_context = None\n effective_context_source = \"manual\"\n\n normalized = _normalize_term(source_term)\n entry_src_lang = dictionary.source_dialect or \"und\"\n entry_tgt_lang = dictionary.target_dialect or \"und\"\n # Find existing entry: match exact language pair OR old-style \"und\"/\"und\" entries\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n or_(\n # Exact language pair match\n (DictionaryEntry.source_language == entry_src_lang) &\n (DictionaryEntry.target_language == entry_tgt_lang),\n # Old-style entries without language pair\n (DictionaryEntry.source_language == \"und\") &\n (DictionaryEntry.target_language == \"und\"),\n ),\n )\n .first()\n )\n\n result: dict[str, Any] = {\n \"source_term\": source_term,\n \"target_term\": corrected_target_term,\n \"action\": \"created\",\n \"entry_id\": None,\n \"conflict\": None,\n \"message\": None,\n }\n\n if existing:\n # Conflict detected\n if on_conflict == \"keep_existing\":\n result[\"action\"] = \"conflict_detected\"\n result[\"conflict\"] = {\n \"source_term\": source_term,\n \"existing_target_term\": existing.target_term,\n \"submitted_target_term\": corrected_target_term,\n \"action\": \"keep_existing\",\n }\n result[\"message\"] = f\"Existing entry kept: '{existing.target_term}'\"\n return result\n elif on_conflict == \"overwrite\":\n existing.target_term = corrected_target_term.strip()\n if origin_run_id:\n existing.origin_run_id = origin_run_id\n if origin_row_key:\n existing.origin_row_key = origin_row_key\n if origin_user_id:\n existing.origin_user_id = origin_user_id\n if context_data is not None or not keep_context:\n existing.context_data = effective_context\n existing.has_context = bool(effective_context)\n existing.context_source = effective_context_source\n if usage_notes is not None:\n existing.usage_notes = usage_notes\n db.flush()\n result[\"action\"] = \"updated\"\n result[\"entry_id\"] = existing.id\n result[\"message\"] = f\"Entry updated from '{existing.target_term}' to '{corrected_target_term}'\"\n else: # cancel\n result[\"action\"] = \"skipped\"\n result[\"conflict\"] = {\n \"source_term\": source_term,\n \"existing_target_term\": existing.target_term,\n \"submitted_target_term\": corrected_target_term,\n \"action\": \"cancel\",\n }\n result[\"message\"] = \"Correction cancelled by conflict mode\"\n return result\n else:\n # Create new entry — derive language pair from dictionary\n entry = DictionaryEntry(\n dictionary_id=dict_id,\n source_term=source_term.strip(),\n source_term_normalized=normalized,\n target_term=corrected_target_term.strip(),\n source_language=entry_src_lang,\n target_language=entry_tgt_lang,\n context_data=effective_context,\n usage_notes=usage_notes,\n has_context=bool(effective_context),\n context_source=effective_context_source if effective_context else None,\n origin_run_id=origin_run_id,\n origin_row_key=origin_row_key,\n origin_user_id=origin_user_id,\n )\n db.add(entry)\n db.flush()\n result[\"entry_id\"] = entry.id\n result[\"message\"] = f\"Entry created for '{source_term}' -> '{corrected_target_term}'\"\n\n db.commit()\n logger.reflect(\"Correction processed\", result)\n return result\n # endregion DictionaryManager.submit_correction\n\n # region DictionaryManager.submit_bulk_corrections [TYPE Function]\n # @PURPOSE: Submit multiple term corrections atomically — all succeed or all fail.\n # @PRE: corrections list is non-empty. dict_id exists.\n # @POST: All corrections applied or none applied with conflict list.\n # @SIDE_EFFECT: Creates/updates DictionaryEntry rows; commits once.\n @staticmethod\n def submit_bulk_corrections(\n db: Session,\n dict_id: str,\n corrections: list[dict[str, Any]],\n origin_user_id: str | None = None,\n ) -> dict[str, Any]:\n with belief_scope(\"DictionaryManager.submit_bulk_corrections\"):\n # Validate dictionary first\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary '{dict_id}' not found\")\n\n results: list[dict[str, Any]] = []\n conflicts: list[dict[str, Any]] = []\n all_ok = True\n\n for corr in corrections:\n source_term = corr.get(\"source_term\", \"\").strip()\n incorrect_target = corr.get(\"incorrect_target_term\", \"\").strip()\n corrected_target = corr.get(\"corrected_target_term\", \"\").strip()\n\n if not source_term or not corrected_target:\n results.append({\n \"source_term\": source_term,\n \"action\": \"error\",\n \"message\": \"source_term and corrected_target_term are required\",\n })\n all_ok = False\n continue\n\n normalized = _normalize_term(source_term)\n bulk_src_lang = dictionary.source_dialect or \"und\"\n bulk_tgt_lang = dictionary.target_dialect or \"und\"\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n or_(\n (DictionaryEntry.source_language == bulk_src_lang) &\n (DictionaryEntry.target_language == bulk_tgt_lang),\n (DictionaryEntry.source_language == \"und\") &\n (DictionaryEntry.target_language == \"und\"),\n ),\n )\n .first()\n )\n\n if existing:\n on_conflict = corr.get(\"on_conflict\", \"overwrite\")\n if on_conflict == \"keep_existing\":\n conflicts.append({\n \"source_term\": source_term,\n \"existing_target_term\": existing.target_term,\n \"submitted_target_term\": corrected_target,\n \"action\": \"keep_existing\",\n })\n results.append({\n \"source_term\": source_term,\n \"action\": \"conflict_detected\",\n \"message\": f\"Existing entry kept: '{existing.target_term}'\",\n })\n continue\n elif on_conflict == \"overwrite\":\n existing.target_term = corrected_target\n existing.origin_user_id = origin_user_id\n results.append({\n \"source_term\": source_term,\n \"action\": \"updated\",\n \"entry_id\": existing.id,\n \"message\": f\"Updated to '{corrected_target}'\",\n })\n else:\n conflicts.append({\n \"source_term\": source_term,\n \"existing_target_term\": existing.target_term,\n \"submitted_target_term\": corrected_target,\n \"action\": \"cancel\",\n })\n results.append({\n \"source_term\": source_term,\n \"action\": \"skipped\",\n \"message\": \"Cancelled by conflict mode\",\n })\n else:\n entry = DictionaryEntry(\n dictionary_id=dict_id,\n source_term=source_term,\n source_term_normalized=normalized,\n target_term=corrected_target,\n source_language=bulk_src_lang,\n target_language=bulk_tgt_lang,\n origin_run_id=corr.get(\"origin_run_id\"),\n origin_row_key=corr.get(\"origin_row_key\"),\n origin_user_id=origin_user_id,\n )\n db.add(entry)\n results.append({\n \"source_term\": source_term,\n \"action\": \"created\",\n \"message\": f\"Entry created for '{source_term}' -> '{corrected_target}'\",\n })\n\n if conflicts and not all_ok:\n # Rollback — all failed\n db.rollback()\n return {\n \"status\": \"conflicts\",\n \"results\": results,\n \"conflicts\": conflicts,\n \"message\": \"Conflicts detected. Resolve before retrying.\",\n }\n\n db.commit()\n\n return {\n \"status\": \"completed\",\n \"results\": results,\n \"conflicts\": conflicts,\n \"total\": len(corrections),\n \"applied\": sum(1 for r in results if r[\"action\"] in (\"created\", \"updated\")),\n }\n # endregion DictionaryManager.submit_bulk_corrections\n\n\n# #endregion DictionaryManager\n# #endregion DictionaryManagerModule\n" - }, - { - "contract_id": "_validate_bcp47", - "contract_type": "Function", - "file_path": "backend/src/plugins/translate/dictionary.py", - "start_line": 31, - "end_line": 45, - "tier": "TIER_1", - "complexity": 2, - "metadata": { - "COMPLEXITY": 2, - "PURPOSE": "Validate that a language tag is a non-empty BCP-47 string." - }, - "relations": [], - "schema_warnings": [], - "anchor_syntax": "region", - "tier_source": "AutoCalculated", - "body": "# #region _validate_bcp47 [C:2] [TYPE Function] [SEMANTICS validation, bcp47, language]\n# @BRIEF Validate that a language tag is a non-empty BCP-47 string.\ndef _validate_bcp47(tag: str, field_name: str) -> None:\n \"\"\"Validate that tag is a non-empty BCP-47 string (basic check).\"\"\"\n if not tag or not tag.strip():\n raise ValueError(f\"{field_name} must be a non-empty BCP-47 language tag\")\n tag = tag.strip()\n # Basic BCP-47 validation: must match lang[-script][-region][-variant]* pattern\n import re as _re\n if not _re.match(r'^[a-zA-Z]{2,8}(-[a-zA-Z0-9]{1,8})*$', tag):\n raise ValueError(\n f\"{field_name} is not a valid BCP-47 tag: '{tag}'. \"\n \"Expected format like 'en', 'ru', 'zh-CN', 'pt-BR'.\"\n )\n# #endregion _validate_bcp47\n" - }, { "contract_id": "DictionaryManager", "contract_type": "Class", "file_path": "backend/src/plugins/translate/dictionary.py", "start_line": 48, - "end_line": 1001, + "end_line": 1003, "tier": "TIER_2", "complexity": 4, "metadata": { @@ -49779,21 +49042,18 @@ "PURPOSE": "Manages terminology dictionaries and their entries with referential integrity.", "SIDE_EFFECT": "Creates, updates, deletes TerminologyDictionary and DictionaryEntry rows; enforces deletion guards." }, - "relations": [], - "schema_warnings": [ + "relations": [ { - "code": "missing_required_tag", - "tag": "RELATION", - "message": "@RELATION is required for contract type 'Class' at C4", - "detail": { - "actual_complexity": 4, - "contract_type": "Class" - } + "source_id": "DictionaryManager", + "relation_type": "DEPENDS_ON", + "target_id": "TerminologyDictionary:Class], DEPENDS_ON -> [DictionaryEntry:Class], DEPENDS_ON -> [TranslationJobDictionary:Class], DEPENDS_ON -> [TranslationJob:Class", + "target_ref": "[TerminologyDictionary:Class], DEPENDS_ON -> [DictionaryEntry:Class], DEPENDS_ON -> [TranslationJobDictionary:Class], DEPENDS_ON -> [TranslationJob:Class]" } ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region DictionaryManager [C:4] [TYPE Class]\n# @BRIEF Manages terminology dictionaries and their entries with referential integrity.\n# @PRE: Database session is open and valid.\n# @POST: Dictionary and entry mutations are persisted with conflict detection.\n# @SIDE_EFFECT: Creates, updates, deletes TerminologyDictionary and DictionaryEntry rows; enforces deletion guards.\nclass DictionaryManager:\n # region DictionaryManager.create_dictionary [TYPE Function]\n # @PURPOSE: Create a new terminology dictionary (language independent at dictionary level; language pairs are per-entry).\n # @PRE: name is provided.\n # @POST: New TerminologyDictionary row is created and returned.\n @staticmethod\n def create_dictionary(\n db: Session, name: str,\n source_dialect: str = \"\",\n target_dialect: str = \"\",\n created_by: str | None = None, description: str | None = None,\n is_active: bool = True,\n ) -> TerminologyDictionary:\n with belief_scope(\"DictionaryManager.create_dictionary\"):\n logger.reason(\"Creating dictionary\", {\"name\": name, \"source\": source_dialect, \"target\": target_dialect})\n dictionary = TerminologyDictionary(\n name=name,\n description=description,\n source_dialect=source_dialect or \"\",\n target_dialect=target_dialect or \"\",\n is_active=is_active,\n created_by=created_by,\n )\n db.add(dictionary)\n db.commit()\n db.refresh(dictionary)\n logger.reflect(\"Dictionary created\", {\"id\": dictionary.id})\n return dictionary\n # endregion DictionaryManager.create_dictionary\n\n # region DictionaryManager.update_dictionary [TYPE Function]\n # @PURPOSE: Update an existing terminology dictionary.\n # @PRE: dict_id exists in terminology_dictionaries table.\n # @POST: Dictionary metadata is updated and returned.\n @staticmethod\n def update_dictionary(\n db: Session, dict_id: str, name: str | None = None,\n description: str | None = None, source_dialect: str | None = None,\n target_dialect: str | None = None, is_active: bool | None = None,\n ) -> TerminologyDictionary:\n with belief_scope(\"DictionaryManager.update_dictionary\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n logger.reason(\"Updating dictionary\", {\"id\": dict_id})\n if name is not None:\n dictionary.name = name\n if description is not None:\n dictionary.description = description\n if source_dialect is not None:\n dictionary.source_dialect = source_dialect\n if target_dialect is not None:\n dictionary.target_dialect = target_dialect\n if is_active is not None:\n dictionary.is_active = is_active\n db.commit()\n db.refresh(dictionary)\n logger.reflect(\"Dictionary updated\", {\"id\": dictionary.id})\n return dictionary\n # endregion DictionaryManager.update_dictionary\n\n # region DictionaryManager.delete_dictionary [TYPE Function]\n # @PURPOSE: Delete a dictionary, blocked if attached to active/scheduled jobs.\n # @PRE: dict_id exists.\n # @POST: Dictionary and its entries are deleted, unless attached to ACTIVE/READY/RUNNING/SCHEDULED jobs.\n # @SIDE_EFFECT: Deletes TerminologyDictionary row and all DictionaryEntry rows.\n @staticmethod\n def delete_dictionary(db: Session, dict_id: str) -> None:\n with belief_scope(\"DictionaryManager.delete_dictionary\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n\n # Check for attached active/scheduled jobs\n blocked_statuses = [\"ACTIVE\", \"READY\", \"RUNNING\", \"SCHEDULED\"]\n attached_jobs = (\n db.query(TranslationJobDictionary)\n .filter(\n TranslationJobDictionary.dictionary_id == dict_id,\n TranslationJobDictionary.job_id.in_(\n db.query(TranslationJob.id).filter(\n TranslationJob.status.in_(blocked_statuses)\n )\n ),\n )\n .count()\n )\n\n if attached_jobs > 0:\n logger.explore(\"Delete blocked: dictionary attached to active jobs\", {\"dict_id\": dict_id, \"jobs\": attached_jobs})\n raise ValueError(\n f\"Cannot delete dictionary attached to {attached_jobs} active/scheduled job(s). \"\n \"Remove dictionary associations from jobs first.\"\n )\n\n logger.reason(\"Deleting dictionary\", {\"id\": dict_id})\n # Delete entries and job-dictionary links first\n db.query(DictionaryEntry).filter(DictionaryEntry.dictionary_id == dict_id).delete()\n db.query(TranslationJobDictionary).filter(TranslationJobDictionary.dictionary_id == dict_id).delete()\n db.delete(dictionary)\n db.commit()\n logger.reflect(\"Dictionary deleted\", {\"id\": dict_id})\n # endregion DictionaryManager.delete_dictionary\n\n # region DictionaryManager.get_dictionary [TYPE Function]\n # @PURPOSE: Get a single dictionary by ID with entry count.\n # @PRE: dict_id exists.\n # @POST: Returns dict with dictionary + entry_count or raises ValueError.\n @staticmethod\n def get_dictionary(db: Session, dict_id: str) -> TerminologyDictionary:\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n return dictionary\n # endregion DictionaryManager.get_dictionary\n\n # region DictionaryManager.list_dictionaries [TYPE Function]\n # @PURPOSE: List dictionaries with pagination and entry counts.\n # @PRE: page >= 1, page_size between 1 and 100.\n # @POST: Returns (list of dicts, total_count).\n @staticmethod\n def list_dictionaries(\n db: Session, page: int = 1, page_size: int = 20,\n ) -> tuple[list[TerminologyDictionary], int]:\n total = db.query(func.count(TerminologyDictionary.id)).scalar() or 0\n dictionaries = (\n db.query(TerminologyDictionary)\n .order_by(TerminologyDictionary.created_at.desc())\n .offset((page - 1) * page_size)\n .limit(page_size)\n .all()\n )\n return dictionaries, total\n # endregion DictionaryManager.list_dictionaries\n\n # region DictionaryManager.add_entry [TYPE Function]\n # @PURPOSE: Add an entry to a dictionary with language-pair-aware uniqueness validation.\n # @PRE: dict_id exists. source_term, target_term are non-empty. source_language, target_language are valid BCP-47.\n # @POST: New DictionaryEntry row is created or raises on duplicate.\n @staticmethod\n def add_entry(\n db: Session, dict_id: str, source_term: str, target_term: str,\n context_notes: str | None = None,\n source_language: str = \"und\",\n target_language: str = \"und\",\n ) -> DictionaryEntry:\n with belief_scope(\"DictionaryManager.add_entry\"):\n _validate_bcp47(source_language, \"source_language\")\n _validate_bcp47(target_language, \"target_language\")\n\n normalized = _normalize_term(source_term)\n # Uniqueness is now (dictionary_id, source_term_normalized, source_language, target_language)\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == source_language,\n DictionaryEntry.target_language == target_language,\n )\n .first()\n )\n if existing:\n raise ValueError(\n f\"Duplicate entry: '{source_term}' (lang: {source_language}→{target_language}) \"\n f\"already exists in this dictionary (id={existing.id}). \"\n \"Use overwrite or keep_existing conflict mode.\"\n )\n\n logger.reason(\"Adding dictionary entry\", {\"dict_id\": dict_id, \"term\": source_term, \"src_lang\": source_language, \"tgt_lang\": target_language})\n entry = DictionaryEntry(\n dictionary_id=dict_id,\n source_term=source_term.strip(),\n source_term_normalized=normalized,\n target_term=target_term.strip(),\n context_notes=context_notes.strip() if context_notes else None,\n source_language=source_language.strip(),\n target_language=target_language.strip(),\n )\n db.add(entry)\n db.commit()\n db.refresh(entry)\n logger.reflect(\"Entry added\", {\"entry_id\": entry.id, \"src_lang\": source_language, \"tgt_lang\": target_language})\n return entry\n # endregion DictionaryManager.add_entry\n\n # region DictionaryManager.edit_entry [TYPE Function]\n # @PURPOSE: Edit an existing dictionary entry with language-pair-aware duplicate check.\n # @PRE: entry_id exists.\n # @POST: Entry fields are updated.\n @staticmethod\n def edit_entry(\n db: Session, entry_id: str, source_term: str | None = None,\n target_term: str | None = None, context_notes: str | None = None,\n source_language: str | None = None,\n target_language: str | None = None,\n ) -> DictionaryEntry:\n with belief_scope(\"DictionaryManager.edit_entry\"):\n entry = db.query(DictionaryEntry).filter(DictionaryEntry.id == entry_id).first()\n if not entry:\n raise ValueError(f\"Entry not found: {entry_id}\")\n\n logger.reason(\"Editing dictionary entry\", {\"entry_id\": entry_id})\n\n if source_language is not None:\n _validate_bcp47(source_language, \"source_language\")\n entry.source_language = source_language.strip()\n if target_language is not None:\n _validate_bcp47(target_language, \"target_language\")\n entry.target_language = target_language.strip()\n\n if source_term is not None:\n normalized = _normalize_term(source_term)\n # Check uniqueness within the same dictionary + language pair\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == entry.dictionary_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == entry.source_language,\n DictionaryEntry.target_language == entry.target_language,\n DictionaryEntry.id != entry_id,\n )\n .first()\n )\n if existing:\n raise ValueError(\n f\"Duplicate entry: '{source_term}' already exists in this dictionary \"\n f\"(id={existing.id}).\"\n )\n entry.source_term = source_term.strip()\n entry.source_term_normalized = normalized\n if target_term is not None:\n entry.target_term = target_term.strip()\n if context_notes is not None:\n entry.context_notes = context_notes.strip() if context_notes else None\n db.commit()\n db.refresh(entry)\n logger.reflect(\"Entry updated\", {\"entry_id\": entry.id})\n return entry\n # endregion DictionaryManager.edit_entry\n\n # region DictionaryManager.delete_entry [TYPE Function]\n # @PURPOSE: Delete a single dictionary entry.\n # @PRE: entry_id exists.\n # @POST: Entry is deleted.\n @staticmethod\n def delete_entry(db: Session, entry_id: str) -> None:\n with belief_scope(\"DictionaryManager.delete_entry\"):\n entry = db.query(DictionaryEntry).filter(DictionaryEntry.id == entry_id).first()\n if not entry:\n raise ValueError(f\"Entry not found: {entry_id}\")\n logger.reason(\"Deleting dictionary entry\", {\"entry_id\": entry_id})\n db.delete(entry)\n db.commit()\n logger.reflect(\"Entry deleted\", {\"entry_id\": entry_id})\n # endregion DictionaryManager.delete_entry\n\n # region DictionaryManager.clear_entries [TYPE Function]\n # @PURPOSE: Delete all entries for a dictionary.\n # @PRE: dict_id exists.\n # @POST: All entries for the dictionary are deleted.\n @staticmethod\n def clear_entries(db: Session, dict_id: str) -> int:\n with belief_scope(\"DictionaryManager.clear_entries\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n logger.reason(\"Clearing all entries\", {\"dict_id\": dict_id})\n deleted = db.query(DictionaryEntry).filter(DictionaryEntry.dictionary_id == dict_id).delete()\n db.commit()\n logger.reflect(\"Entries cleared\", {\"dict_id\": dict_id, \"count\": deleted})\n return deleted\n # endregion DictionaryManager.clear_entries\n\n # region DictionaryManager.list_entries [TYPE Function]\n # @PURPOSE: List entries for a dictionary with pagination.\n # @PRE: dict_id exists.\n # @POST: Returns (list of entries, total_count).\n @staticmethod\n def list_entries(\n db: Session, dict_id: str, page: int = 1, page_size: int = 50,\n ) -> tuple[list[DictionaryEntry], int]:\n total = (\n db.query(func.count(DictionaryEntry.id))\n .filter(DictionaryEntry.dictionary_id == dict_id)\n .scalar()\n or 0\n )\n entries = (\n db.query(DictionaryEntry)\n .filter(DictionaryEntry.dictionary_id == dict_id)\n .order_by(DictionaryEntry.source_term.asc())\n .offset((page - 1) * page_size)\n .limit(page_size)\n .all()\n )\n return entries, total\n # endregion DictionaryManager.list_entries\n\n # region DictionaryManager.import_entries [TYPE Function]\n # @PURPOSE: Import entries from CSV/TSV content with duplicate detection and conflict resolution.\n # @PRE: content is valid CSV or TSV. dict_id exists.\n # @POST: Entries are created/updated/skipped per conflict mode. Returns result summary.\n # @SIDE_EFFECT: Batch-inserts or updates DictionaryEntry rows.\n @staticmethod\n def import_entries(\n db: Session, dict_id: str, content: str,\n delimiter: str | None = None,\n on_conflict: str = \"overwrite\",\n preview_only: bool = False,\n default_source_language: str | None = None,\n default_target_language: str | None = None,\n ) -> dict[str, Any]:\n with belief_scope(\"DictionaryManager.import_entries\"):\n # Validate dictionary\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n\n # Detect delimiter if not specified\n if not delimiter:\n delimiter = _detect_delimiter(content)\n logger.reason(\"Detected delimiter\", {\"delimiter\": repr(delimiter)})\n\n if delimiter not in (\",\", \"\\t\"):\n raise ValueError(f\"Unsupported delimiter: {delimiter!r}. Use ',' or '\\\\t'.\")\n\n # Parse content\n reader = csv.DictReader(io.StringIO(content), delimiter=delimiter)\n required_fields = {\"source_term\", \"target_term\"}\n if not reader.fieldnames or not required_fields.issubset(reader.fieldnames):\n raise ValueError(\n f\"CSV/TSV must have at least 'source_term' and 'target_term' columns. \"\n f\"Got: {reader.fieldnames}\"\n )\n\n result: dict[str, Any] = {\n \"total\": 0,\n \"created\": 0,\n \"updated\": 0,\n \"skipped\": 0,\n \"errors\": [],\n \"preview\": [],\n }\n\n rows = list(reader)\n result[\"total\"] = len(rows)\n\n for row_idx, row in enumerate(rows):\n try:\n source_term = row.get(\"source_term\", \"\").strip()\n target_term = row.get(\"target_term\", \"\").strip()\n context_notes = row.get(\"context_notes\", \"\").strip() or None\n source_language = row.get(\"source_language\", \"\").strip() or default_source_language or \"und\"\n target_language = row.get(\"target_language\", \"\").strip() or default_target_language or \"und\"\n\n if not source_term or not target_term:\n result[\"errors\"].append({\n \"line\": row_idx + 2, # +2 for header and 1-indexed\n \"error\": \"Both source_term and target_term are required\",\n \"row\": row,\n })\n continue\n\n normalized = _normalize_term(source_term)\n\n if preview_only:\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == source_language,\n DictionaryEntry.target_language == target_language,\n )\n .first()\n )\n preview_row = {\n \"line\": row_idx + 2,\n \"source_term\": source_term,\n \"target_term\": target_term,\n \"context_notes\": context_notes,\n \"source_language\": source_language,\n \"target_language\": target_language,\n \"is_conflict\": existing is not None,\n \"existing_target_term\": existing.target_term if existing else None,\n }\n result[\"preview\"].append(preview_row)\n continue\n\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == source_language,\n DictionaryEntry.target_language == target_language,\n )\n .first()\n )\n\n if existing:\n if on_conflict == \"overwrite\":\n existing.source_term = source_term\n existing.target_term = target_term\n existing.context_notes = context_notes\n existing.source_language = source_language\n existing.target_language = target_language\n result[\"updated\"] += 1\n elif on_conflict == \"keep_existing\":\n result[\"skipped\"] += 1\n else: # cancel\n result[\"errors\"].append({\n \"line\": row_idx + 2,\n \"error\": f\"Conflict on '{source_term}' and on_conflict='cancel'\",\n \"row\": row,\n })\n continue\n else:\n entry = DictionaryEntry(\n dictionary_id=dict_id,\n source_term=source_term,\n source_term_normalized=normalized,\n target_term=target_term,\n context_notes=context_notes,\n source_language=source_language,\n target_language=target_language,\n )\n db.add(entry)\n result[\"created\"] += 1\n\n except Exception as e:\n result[\"errors\"].append({\n \"line\": row_idx + 2,\n \"error\": str(e),\n \"row\": row,\n })\n\n if not preview_only:\n db.commit()\n\n logger.reflect(\"Import complete\", {\n \"dict_id\": dict_id,\n \"total\": result[\"total\"],\n \"created\": result[\"created\"],\n \"updated\": result[\"updated\"],\n \"skipped\": result[\"skipped\"],\n \"errors\": len(result[\"errors\"]),\n })\n return result\n # endregion DictionaryManager.import_entries\n\n # region DictionaryManager.export_entries [TYPE Function]\n # @PURPOSE: Export all entries as CSV string with language columns.\n # @PRE: dict_id exists.\n # @POST: Returns CSV string with header: source_term, target_term, source_language, target_language, context_notes, context_data, usage_notes.\n @staticmethod\n def export_entries(\n db: Session, dict_id: str, delimiter: str = \",\",\n ) -> str:\n with belief_scope(\"DictionaryManager.export_entries\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n\n entries = (\n db.query(DictionaryEntry)\n .filter(DictionaryEntry.dictionary_id == dict_id)\n .order_by(DictionaryEntry.source_term.asc())\n .all()\n )\n\n output = io.StringIO()\n fieldnames = [\n \"source_term\", \"target_term\",\n \"source_language\", \"target_language\",\n \"context_notes\", \"context_data\", \"usage_notes\",\n ]\n writer = csv.DictWriter(output, fieldnames=fieldnames, delimiter=delimiter)\n writer.writeheader()\n\n for entry in entries:\n writer.writerow({\n \"source_term\": entry.source_term,\n \"target_term\": entry.target_term,\n \"source_language\": entry.source_language,\n \"target_language\": entry.target_language,\n \"context_notes\": entry.context_notes or \"\",\n \"context_data\": entry.context_data,\n \"usage_notes\": entry.usage_notes or \"\",\n })\n\n result = output.getvalue()\n logger.reflect(\"Entries exported\", {\"dict_id\": dict_id, \"count\": len(entries), \"delimiter\": repr(delimiter)})\n return result\n # endregion DictionaryManager.export_entries\n\n # region DictionaryManager.migrate_old_entries [TYPE Function]\n # @PURPOSE: Migrate existing single-language dictionary entries to populate source_language and target_language.\n # @PRE: db session is open.\n # @POST: Entries with \"und\" source_language or target_language are updated with inferred values.\n # @SIDE_EFFECT: Updates DictionaryEntry rows in bulk.\n @staticmethod\n def migrate_old_entries(db: Session) -> dict[str, int]:\n with belief_scope(\"DictionaryManager.migrate_old_entries\"):\n logger.reason(\"Starting migration of old dictionary entries\")\n migrated_source = 0\n migrated_target = 0\n skipped = 0\n\n # Find all entries that may need migration (source_language is \"und\" or target_language is \"und\")\n entries = (\n db.query(DictionaryEntry)\n .filter(\n (DictionaryEntry.source_language == \"und\") |\n (DictionaryEntry.target_language == \"und\")\n )\n .all()\n )\n\n for entry in entries:\n # Try to infer source_language from origin_source_language\n if entry.source_language == \"und\":\n if entry.origin_source_language:\n entry.source_language = entry.origin_source_language\n migrated_source += 1\n\n # Note: target_language inference from dictionary-level column was removed\n # because TerminologyDictionary.target_language was deprecated and dropped.\n\n if entry.source_language == \"und\" and entry.target_language == \"und\":\n skipped += 1\n\n db.commit()\n\n logger.reflect(\"Migration complete\", {\n \"migrated_source\": migrated_source,\n \"migrated_target\": migrated_target,\n \"skipped\": skipped,\n \"total_processed\": len(entries),\n })\n return {\n \"migrated_source\": migrated_source,\n \"migrated_target\": migrated_target,\n \"skipped\": skipped,\n \"total_processed\": len(entries),\n }\n # endregion DictionaryManager.migrate_old_entries\n\n # region DictionaryManager.filter_for_batch [TYPE Function]\n # @PURPOSE: Scan batch texts for case-insensitive, word-boundary-aware matches against all dictionaries attached to a job,\n # optionally filtered by language pair. When row_context is provided, computes context-aware priority flags.\n # @PRE: job_id exists and source_texts is a list of strings.\n # @POST: Returns list of matched entries with match info, sorted by priority across attached dictionaries.\n # When row_context is given, each result includes a 'priority_match' boolean.\n # @SIDE_EFFECT: Queries TranslationJobDictionary, TerminologyDictionary, and DictionaryEntry tables.\n @staticmethod\n def filter_for_batch(\n db: Session, source_texts: list[str], job_id: str,\n source_language: str | None = None,\n target_language: str | None = None,\n row_context: dict | None = None,\n ) -> list[dict[str, Any]]:\n with belief_scope(\"DictionaryManager.filter_for_batch\"):\n # Get dictionaries attached to this job\n job_dict_links = (\n db.query(TranslationJobDictionary)\n .filter(TranslationJobDictionary.job_id == job_id)\n .all()\n )\n if not job_dict_links:\n logger.reason(\"No dictionaries attached to job\", {\"job_id\": job_id})\n return []\n\n dict_ids = [jd.dictionary_id for jd in job_dict_links]\n\n # Get all active dictionaries\n dictionaries = (\n db.query(TerminologyDictionary)\n .filter(\n TerminologyDictionary.id.in_(dict_ids),\n TerminologyDictionary.is_active == True,\n )\n .all()\n )\n if not dictionaries:\n return []\n\n # Build dict_id -> dict_name lookup\n dict_map = {d.id: d.name for d in dictionaries}\n\n # Fetch all entries for these dictionaries, ordered by dictionary (priority order from link order)\n all_entries = (\n db.query(DictionaryEntry)\n .filter(DictionaryEntry.dictionary_id.in_(dict_ids))\n .order_by(DictionaryEntry.source_term.asc())\n .all()\n )\n\n if not all_entries:\n return []\n\n # PERFORMANCE NOTE: O(rows × entries) regex matching per batch.\n # Acceptable for current scale (50-100 rows × <1000 entries).\n # For larger batches (>500 rows or >5000 entries), consider\n # replacing with an Aho-Corasick automaton (e.g., pyahocorasick).\n matched: list[dict[str, Any]] = []\n seen_source_match: set = set()\n\n for text_idx, source_text in enumerate(source_texts):\n if not source_text:\n continue\n\n text_lower = source_text.lower()\n\n for entry in all_entries:\n norm = entry.source_term_normalized\n if not norm:\n continue\n\n # Apply language pair filtering\n if source_language is not None:\n src = source_language.strip().lower()\n entry_src = entry.source_language.strip().lower()\n if entry_src != src and entry_src != \"und\":\n continue\n if target_language is not None:\n tgt = target_language.strip().lower()\n entry_tgt = entry.target_language.strip().lower()\n if entry_tgt != tgt:\n continue\n\n # Word-boundary-aware matching\n # Build pattern: \\bterm\\b (case-insensitive)\n # Escape regex special chars in the search term\n escaped = re.escape(norm)\n pattern = re.compile(r\"\\b\" + escaped + r\"\\b\", re.IGNORECASE)\n\n if pattern.search(text_lower):\n match_key = (text_idx, entry.id)\n if match_key not in seen_source_match:\n seen_source_match.add(match_key)\n\n # Compute context-aware priority if row_context is available\n priority_match = False\n if row_context and entry.has_context and entry.context_data:\n similarity = ContextAwarePromptBuilder.compute_context_similarity(\n entry.context_data, row_context\n )\n priority_match = similarity >= 0.5\n\n matched.append({\n \"text_index\": text_idx,\n \"source_text\": source_text,\n \"entry_id\": entry.id,\n \"source_term\": entry.source_term,\n \"source_term_normalized\": entry.source_term_normalized,\n \"target_term\": entry.target_term,\n \"dictionary_id\": entry.dictionary_id,\n \"dictionary_name\": dict_map.get(entry.dictionary_id, \"\"),\n \"context_notes\": entry.context_notes,\n \"context_data\": entry.context_data,\n \"has_context\": entry.has_context,\n \"context_source\": entry.context_source,\n \"usage_notes\": entry.usage_notes,\n \"source_language\": entry.source_language,\n \"target_language\": entry.target_language,\n \"priority_match\": priority_match,\n })\n\n # Sort by dictionary link priority (order of dict_ids from link order)\n dict_priority = {d_id: idx for idx, d_id in enumerate(dict_ids)}\n matched.sort(key=lambda m: (dict_priority.get(m[\"dictionary_id\"], 999), m[\"text_index\"]))\n\n logger.reflect(\"Batch filter match complete\", {\n \"job_id\": job_id,\n \"source_texts\": len(source_texts),\n \"matches\": len(matched),\n \"dictionaries_used\": len(dictionaries),\n \"source_language\": source_language,\n \"target_language\": target_language,\n })\n return matched\n # endregion DictionaryManager.filter_for_batch\n\n\n # region DictionaryManager.submit_correction [TYPE Function]\n # @PURPOSE: Submit a term correction from a run result. Validates language match, detects conflicts.\n # @PRE: source_term, incorrect_target_term, corrected_target_term are non-empty. dict_id exists.\n # @POST: Entry created or updated; origin tracking populated. Returns action + conflict info.\n # @SIDE_EFFECT: Creates/updates DictionaryEntry row.\n @staticmethod\n def submit_correction(\n db: Session,\n dict_id: str,\n source_term: str,\n incorrect_target_term: str,\n corrected_target_term: str,\n origin_run_id: str | None = None,\n origin_row_key: str | None = None,\n origin_user_id: str | None = None,\n on_conflict: str = \"overwrite\",\n context_data: dict[str, Any] | None = None,\n usage_notes: str | None = None,\n keep_context: bool = True,\n ) -> dict[str, Any]:\n with belief_scope(\"DictionaryManager.submit_correction\"):\n # Validate dictionary exists\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary '{dict_id}' not found\")\n\n # Handle keep_context=False (user explicitly removed context)\n effective_context = context_data\n effective_context_source = \"auto\"\n if not keep_context:\n effective_context = None\n effective_context_source = \"manual\"\n\n normalized = _normalize_term(source_term)\n entry_src_lang = dictionary.source_dialect or \"und\"\n entry_tgt_lang = dictionary.target_dialect or \"und\"\n # Find existing entry: match exact language pair OR old-style \"und\"/\"und\" entries\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n or_(\n # Exact language pair match\n (DictionaryEntry.source_language == entry_src_lang) &\n (DictionaryEntry.target_language == entry_tgt_lang),\n # Old-style entries without language pair\n (DictionaryEntry.source_language == \"und\") &\n (DictionaryEntry.target_language == \"und\"),\n ),\n )\n .first()\n )\n\n result: dict[str, Any] = {\n \"source_term\": source_term,\n \"target_term\": corrected_target_term,\n \"action\": \"created\",\n \"entry_id\": None,\n \"conflict\": None,\n \"message\": None,\n }\n\n if existing:\n # Conflict detected\n if on_conflict == \"keep_existing\":\n result[\"action\"] = \"conflict_detected\"\n result[\"conflict\"] = {\n \"source_term\": source_term,\n \"existing_target_term\": existing.target_term,\n \"submitted_target_term\": corrected_target_term,\n \"action\": \"keep_existing\",\n }\n result[\"message\"] = f\"Existing entry kept: '{existing.target_term}'\"\n return result\n elif on_conflict == \"overwrite\":\n existing.target_term = corrected_target_term.strip()\n if origin_run_id:\n existing.origin_run_id = origin_run_id\n if origin_row_key:\n existing.origin_row_key = origin_row_key\n if origin_user_id:\n existing.origin_user_id = origin_user_id\n if context_data is not None or not keep_context:\n existing.context_data = effective_context\n existing.has_context = bool(effective_context)\n existing.context_source = effective_context_source\n if usage_notes is not None:\n existing.usage_notes = usage_notes\n db.flush()\n result[\"action\"] = \"updated\"\n result[\"entry_id\"] = existing.id\n result[\"message\"] = f\"Entry updated from '{existing.target_term}' to '{corrected_target_term}'\"\n else: # cancel\n result[\"action\"] = \"skipped\"\n result[\"conflict\"] = {\n \"source_term\": source_term,\n \"existing_target_term\": existing.target_term,\n \"submitted_target_term\": corrected_target_term,\n \"action\": \"cancel\",\n }\n result[\"message\"] = \"Correction cancelled by conflict mode\"\n return result\n else:\n # Create new entry — derive language pair from dictionary\n entry = DictionaryEntry(\n dictionary_id=dict_id,\n source_term=source_term.strip(),\n source_term_normalized=normalized,\n target_term=corrected_target_term.strip(),\n source_language=entry_src_lang,\n target_language=entry_tgt_lang,\n context_data=effective_context,\n usage_notes=usage_notes,\n has_context=bool(effective_context),\n context_source=effective_context_source if effective_context else None,\n origin_run_id=origin_run_id,\n origin_row_key=origin_row_key,\n origin_user_id=origin_user_id,\n )\n db.add(entry)\n db.flush()\n result[\"entry_id\"] = entry.id\n result[\"message\"] = f\"Entry created for '{source_term}' -> '{corrected_target_term}'\"\n\n db.commit()\n logger.reflect(\"Correction processed\", result)\n return result\n # endregion DictionaryManager.submit_correction\n\n # region DictionaryManager.submit_bulk_corrections [TYPE Function]\n # @PURPOSE: Submit multiple term corrections atomically — all succeed or all fail.\n # @PRE: corrections list is non-empty. dict_id exists.\n # @POST: All corrections applied or none applied with conflict list.\n # @SIDE_EFFECT: Creates/updates DictionaryEntry rows; commits once.\n @staticmethod\n def submit_bulk_corrections(\n db: Session,\n dict_id: str,\n corrections: list[dict[str, Any]],\n origin_user_id: str | None = None,\n ) -> dict[str, Any]:\n with belief_scope(\"DictionaryManager.submit_bulk_corrections\"):\n # Validate dictionary first\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary '{dict_id}' not found\")\n\n results: list[dict[str, Any]] = []\n conflicts: list[dict[str, Any]] = []\n all_ok = True\n\n for corr in corrections:\n source_term = corr.get(\"source_term\", \"\").strip()\n incorrect_target = corr.get(\"incorrect_target_term\", \"\").strip()\n corrected_target = corr.get(\"corrected_target_term\", \"\").strip()\n\n if not source_term or not corrected_target:\n results.append({\n \"source_term\": source_term,\n \"action\": \"error\",\n \"message\": \"source_term and corrected_target_term are required\",\n })\n all_ok = False\n continue\n\n normalized = _normalize_term(source_term)\n bulk_src_lang = dictionary.source_dialect or \"und\"\n bulk_tgt_lang = dictionary.target_dialect or \"und\"\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n or_(\n (DictionaryEntry.source_language == bulk_src_lang) &\n (DictionaryEntry.target_language == bulk_tgt_lang),\n (DictionaryEntry.source_language == \"und\") &\n (DictionaryEntry.target_language == \"und\"),\n ),\n )\n .first()\n )\n\n if existing:\n on_conflict = corr.get(\"on_conflict\", \"overwrite\")\n if on_conflict == \"keep_existing\":\n conflicts.append({\n \"source_term\": source_term,\n \"existing_target_term\": existing.target_term,\n \"submitted_target_term\": corrected_target,\n \"action\": \"keep_existing\",\n })\n results.append({\n \"source_term\": source_term,\n \"action\": \"conflict_detected\",\n \"message\": f\"Existing entry kept: '{existing.target_term}'\",\n })\n continue\n elif on_conflict == \"overwrite\":\n existing.target_term = corrected_target\n existing.origin_user_id = origin_user_id\n results.append({\n \"source_term\": source_term,\n \"action\": \"updated\",\n \"entry_id\": existing.id,\n \"message\": f\"Updated to '{corrected_target}'\",\n })\n else:\n conflicts.append({\n \"source_term\": source_term,\n \"existing_target_term\": existing.target_term,\n \"submitted_target_term\": corrected_target,\n \"action\": \"cancel\",\n })\n results.append({\n \"source_term\": source_term,\n \"action\": \"skipped\",\n \"message\": \"Cancelled by conflict mode\",\n })\n else:\n entry = DictionaryEntry(\n dictionary_id=dict_id,\n source_term=source_term,\n source_term_normalized=normalized,\n target_term=corrected_target,\n source_language=bulk_src_lang,\n target_language=bulk_tgt_lang,\n origin_run_id=corr.get(\"origin_run_id\"),\n origin_row_key=corr.get(\"origin_row_key\"),\n origin_user_id=origin_user_id,\n )\n db.add(entry)\n results.append({\n \"source_term\": source_term,\n \"action\": \"created\",\n \"message\": f\"Entry created for '{source_term}' -> '{corrected_target}'\",\n })\n\n if conflicts and not all_ok:\n # Rollback — all failed\n db.rollback()\n return {\n \"status\": \"conflicts\",\n \"results\": results,\n \"conflicts\": conflicts,\n \"message\": \"Conflicts detected. Resolve before retrying.\",\n }\n\n db.commit()\n\n return {\n \"status\": \"completed\",\n \"results\": results,\n \"conflicts\": conflicts,\n \"total\": len(corrections),\n \"applied\": sum(1 for r in results if r[\"action\"] in (\"created\", \"updated\")),\n }\n # endregion DictionaryManager.submit_bulk_corrections\n\n\n# #endregion DictionaryManager\n" + "body": "# #region DictionaryManager [C:4] [TYPE Class]\n# @BRIEF Manages terminology dictionaries and their entries with referential integrity.\n# @PRE Database session is open and valid.\n# @POST Dictionary and entry mutations are persisted with conflict detection.\n# @SIDE_EFFECT Creates, updates, deletes TerminologyDictionary and DictionaryEntry rows; enforces deletion guards.\n# @RELATION DEPENDS_ON -> [TerminologyDictionary:Class], DEPENDS_ON -> [DictionaryEntry:Class], DEPENDS_ON -> [TranslationJobDictionary:Class], DEPENDS_ON -> [TranslationJob:Class]\n\nclass DictionaryManager:\n # region DictionaryManager.create_dictionary [TYPE Function]\n # @PURPOSE Create a new terminology dictionary (language independent at dictionary level; language pairs are per-entry).\n # @PRE name is provided.\n # @POST New TerminologyDictionary row is created and returned.\n @staticmethod\n def create_dictionary(\n db: Session, name: str,\n source_dialect: str = \"\",\n target_dialect: str = \"\",\n created_by: str | None = None, description: str | None = None,\n is_active: bool = True,\n ) -> TerminologyDictionary:\n with belief_scope(\"DictionaryManager.create_dictionary\"):\n logger.reason(\"Creating dictionary\", {\"name\": name, \"source\": source_dialect, \"target\": target_dialect})\n dictionary = TerminologyDictionary(\n name=name,\n description=description,\n source_dialect=source_dialect or \"\",\n target_dialect=target_dialect or \"\",\n is_active=is_active,\n created_by=created_by,\n )\n db.add(dictionary)\n db.commit()\n db.refresh(dictionary)\n logger.reflect(\"Dictionary created\", {\"id\": dictionary.id})\n return dictionary\n # endregion DictionaryManager.create_dictionary\n\n # region DictionaryManager.update_dictionary [TYPE Function]\n # @PURPOSE Update an existing terminology dictionary.\n # @PRE dict_id exists in terminology_dictionaries table.\n # @POST Dictionary metadata is updated and returned.\n @staticmethod\n def update_dictionary(\n db: Session, dict_id: str, name: str | None = None,\n description: str | None = None, source_dialect: str | None = None,\n target_dialect: str | None = None, is_active: bool | None = None,\n ) -> TerminologyDictionary:\n with belief_scope(\"DictionaryManager.update_dictionary\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n logger.reason(\"Updating dictionary\", {\"id\": dict_id})\n if name is not None:\n dictionary.name = name\n if description is not None:\n dictionary.description = description\n if source_dialect is not None:\n dictionary.source_dialect = source_dialect\n if target_dialect is not None:\n dictionary.target_dialect = target_dialect\n if is_active is not None:\n dictionary.is_active = is_active\n db.commit()\n db.refresh(dictionary)\n logger.reflect(\"Dictionary updated\", {\"id\": dictionary.id})\n return dictionary\n # endregion DictionaryManager.update_dictionary\n\n # region DictionaryManager.delete_dictionary [TYPE Function]\n # @PURPOSE Delete a dictionary, blocked if attached to active/scheduled jobs.\n # @PRE dict_id exists.\n # @POST Dictionary and its entries are deleted, unless attached to ACTIVE/READY/RUNNING/SCHEDULED jobs.\n # @SIDE_EFFECT Deletes TerminologyDictionary row and all DictionaryEntry rows.\n @staticmethod\n def delete_dictionary(db: Session, dict_id: str) -> None:\n with belief_scope(\"DictionaryManager.delete_dictionary\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n\n # Check for attached active/scheduled jobs\n blocked_statuses = [\"ACTIVE\", \"READY\", \"RUNNING\", \"SCHEDULED\"]\n attached_jobs = (\n db.query(TranslationJobDictionary)\n .filter(\n TranslationJobDictionary.dictionary_id == dict_id,\n TranslationJobDictionary.job_id.in_(\n db.query(TranslationJob.id).filter(\n TranslationJob.status.in_(blocked_statuses)\n )\n ),\n )\n .count()\n )\n\n if attached_jobs > 0:\n logger.explore(\"Delete blocked: dictionary attached to active jobs\", {\"dict_id\": dict_id, \"jobs\": attached_jobs})\n raise ValueError(\n f\"Cannot delete dictionary attached to {attached_jobs} active/scheduled job(s). \"\n \"Remove dictionary associations from jobs first.\"\n )\n\n logger.reason(\"Deleting dictionary\", {\"id\": dict_id})\n # Delete entries and job-dictionary links first\n db.query(DictionaryEntry).filter(DictionaryEntry.dictionary_id == dict_id).delete()\n db.query(TranslationJobDictionary).filter(TranslationJobDictionary.dictionary_id == dict_id).delete()\n db.delete(dictionary)\n db.commit()\n logger.reflect(\"Dictionary deleted\", {\"id\": dict_id})\n # endregion DictionaryManager.delete_dictionary\n\n # region DictionaryManager.get_dictionary [TYPE Function]\n # @PURPOSE Get a single dictionary by ID with entry count.\n # @PRE dict_id exists.\n # @POST Returns dict with dictionary + entry_count or raises ValueError.\n @staticmethod\n def get_dictionary(db: Session, dict_id: str) -> TerminologyDictionary:\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n return dictionary\n # endregion DictionaryManager.get_dictionary\n\n # region DictionaryManager.list_dictionaries [TYPE Function]\n # @PURPOSE List dictionaries with pagination and entry counts.\n # @PRE page >= 1, page_size between 1 and 100.\n # @POST Returns (list of dicts, total_count).\n @staticmethod\n def list_dictionaries(\n db: Session, page: int = 1, page_size: int = 20,\n ) -> tuple[list[TerminologyDictionary], int]:\n total = db.query(func.count(TerminologyDictionary.id)).scalar() or 0\n dictionaries = (\n db.query(TerminologyDictionary)\n .order_by(TerminologyDictionary.created_at.desc())\n .offset((page - 1) * page_size)\n .limit(page_size)\n .all()\n )\n return dictionaries, total\n # endregion DictionaryManager.list_dictionaries\n\n # region DictionaryManager.add_entry [TYPE Function]\n # @PURPOSE Add an entry to a dictionary with language-pair-aware uniqueness validation.\n # @PRE dict_id exists. source_term, target_term are non-empty. source_language, target_language are valid BCP-47.\n # @POST New DictionaryEntry row is created or raises on duplicate.\n @staticmethod\n def add_entry(\n db: Session, dict_id: str, source_term: str, target_term: str,\n context_notes: str | None = None,\n source_language: str = \"und\",\n target_language: str = \"und\",\n ) -> DictionaryEntry:\n with belief_scope(\"DictionaryManager.add_entry\"):\n _validate_bcp47(source_language, \"source_language\")\n _validate_bcp47(target_language, \"target_language\")\n\n normalized = _normalize_term(source_term)\n # Uniqueness is now (dictionary_id, source_term_normalized, source_language, target_language)\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == source_language,\n DictionaryEntry.target_language == target_language,\n )\n .first()\n )\n if existing:\n raise ValueError(\n f\"Duplicate entry: '{source_term}' (lang: {source_language}→{target_language}) \"\n f\"already exists in this dictionary (id={existing.id}). \"\n \"Use overwrite or keep_existing conflict mode.\"\n )\n\n logger.reason(\"Adding dictionary entry\", {\"dict_id\": dict_id, \"term\": source_term, \"src_lang\": source_language, \"tgt_lang\": target_language})\n entry = DictionaryEntry(\n dictionary_id=dict_id,\n source_term=source_term.strip(),\n source_term_normalized=normalized,\n target_term=target_term.strip(),\n context_notes=context_notes.strip() if context_notes else None,\n source_language=source_language.strip(),\n target_language=target_language.strip(),\n )\n db.add(entry)\n db.commit()\n db.refresh(entry)\n logger.reflect(\"Entry added\", {\"entry_id\": entry.id, \"src_lang\": source_language, \"tgt_lang\": target_language})\n return entry\n # endregion DictionaryManager.add_entry\n\n # region DictionaryManager.edit_entry [TYPE Function]\n # @PURPOSE Edit an existing dictionary entry with language-pair-aware duplicate check.\n # @PRE entry_id exists.\n # @POST Entry fields are updated.\n @staticmethod\n def edit_entry(\n db: Session, entry_id: str, source_term: str | None = None,\n target_term: str | None = None, context_notes: str | None = None,\n source_language: str | None = None,\n target_language: str | None = None,\n ) -> DictionaryEntry:\n with belief_scope(\"DictionaryManager.edit_entry\"):\n entry = db.query(DictionaryEntry).filter(DictionaryEntry.id == entry_id).first()\n if not entry:\n raise ValueError(f\"Entry not found: {entry_id}\")\n\n logger.reason(\"Editing dictionary entry\", {\"entry_id\": entry_id})\n\n if source_language is not None:\n _validate_bcp47(source_language, \"source_language\")\n entry.source_language = source_language.strip()\n if target_language is not None:\n _validate_bcp47(target_language, \"target_language\")\n entry.target_language = target_language.strip()\n\n if source_term is not None:\n normalized = _normalize_term(source_term)\n # Check uniqueness within the same dictionary + language pair\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == entry.dictionary_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == entry.source_language,\n DictionaryEntry.target_language == entry.target_language,\n DictionaryEntry.id != entry_id,\n )\n .first()\n )\n if existing:\n raise ValueError(\n f\"Duplicate entry: '{source_term}' already exists in this dictionary \"\n f\"(id={existing.id}).\"\n )\n entry.source_term = source_term.strip()\n entry.source_term_normalized = normalized\n if target_term is not None:\n entry.target_term = target_term.strip()\n if context_notes is not None:\n entry.context_notes = context_notes.strip() if context_notes else None\n db.commit()\n db.refresh(entry)\n logger.reflect(\"Entry updated\", {\"entry_id\": entry.id})\n return entry\n # endregion DictionaryManager.edit_entry\n\n # region DictionaryManager.delete_entry [TYPE Function]\n # @PURPOSE Delete a single dictionary entry.\n # @PRE entry_id exists.\n # @POST Entry is deleted.\n @staticmethod\n def delete_entry(db: Session, entry_id: str) -> None:\n with belief_scope(\"DictionaryManager.delete_entry\"):\n entry = db.query(DictionaryEntry).filter(DictionaryEntry.id == entry_id).first()\n if not entry:\n raise ValueError(f\"Entry not found: {entry_id}\")\n logger.reason(\"Deleting dictionary entry\", {\"entry_id\": entry_id})\n db.delete(entry)\n db.commit()\n logger.reflect(\"Entry deleted\", {\"entry_id\": entry_id})\n # endregion DictionaryManager.delete_entry\n\n # region DictionaryManager.clear_entries [TYPE Function]\n # @PURPOSE Delete all entries for a dictionary.\n # @PRE dict_id exists.\n # @POST All entries for the dictionary are deleted.\n @staticmethod\n def clear_entries(db: Session, dict_id: str) -> int:\n with belief_scope(\"DictionaryManager.clear_entries\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n logger.reason(\"Clearing all entries\", {\"dict_id\": dict_id})\n deleted = db.query(DictionaryEntry).filter(DictionaryEntry.dictionary_id == dict_id).delete()\n db.commit()\n logger.reflect(\"Entries cleared\", {\"dict_id\": dict_id, \"count\": deleted})\n return deleted\n # endregion DictionaryManager.clear_entries\n\n # region DictionaryManager.list_entries [TYPE Function]\n # @PURPOSE List entries for a dictionary with pagination.\n # @PRE dict_id exists.\n # @POST Returns (list of entries, total_count).\n @staticmethod\n def list_entries(\n db: Session, dict_id: str, page: int = 1, page_size: int = 50,\n ) -> tuple[list[DictionaryEntry], int]:\n total = (\n db.query(func.count(DictionaryEntry.id))\n .filter(DictionaryEntry.dictionary_id == dict_id)\n .scalar()\n or 0\n )\n entries = (\n db.query(DictionaryEntry)\n .filter(DictionaryEntry.dictionary_id == dict_id)\n .order_by(DictionaryEntry.source_term.asc())\n .offset((page - 1) * page_size)\n .limit(page_size)\n .all()\n )\n return entries, total\n # endregion DictionaryManager.list_entries\n\n # region DictionaryManager.import_entries [TYPE Function]\n # @PURPOSE Import entries from CSV/TSV content with duplicate detection and conflict resolution.\n # @PRE content is valid CSV or TSV. dict_id exists.\n # @POST Entries are created/updated/skipped per conflict mode. Returns result summary.\n # @SIDE_EFFECT Batch-inserts or updates DictionaryEntry rows.\n @staticmethod\n def import_entries(\n db: Session, dict_id: str, content: str,\n delimiter: str | None = None,\n on_conflict: str = \"overwrite\",\n preview_only: bool = False,\n default_source_language: str | None = None,\n default_target_language: str | None = None,\n ) -> dict[str, Any]:\n with belief_scope(\"DictionaryManager.import_entries\"):\n # Validate dictionary\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n\n # Detect delimiter if not specified\n if not delimiter:\n delimiter = _detect_delimiter(content)\n logger.reason(\"Detected delimiter\", {\"delimiter\": repr(delimiter)})\n\n if delimiter not in (\",\", \"\\t\"):\n raise ValueError(f\"Unsupported delimiter: {delimiter!r}. Use ',' or '\\\\t'.\")\n\n # Parse content\n reader = csv.DictReader(io.StringIO(content), delimiter=delimiter)\n required_fields = {\"source_term\", \"target_term\"}\n if not reader.fieldnames or not required_fields.issubset(reader.fieldnames):\n raise ValueError(\n f\"CSV/TSV must have at least 'source_term' and 'target_term' columns. \"\n f\"Got: {reader.fieldnames}\"\n )\n\n result: dict[str, Any] = {\n \"total\": 0,\n \"created\": 0,\n \"updated\": 0,\n \"skipped\": 0,\n \"errors\": [],\n \"preview\": [],\n }\n\n rows = list(reader)\n result[\"total\"] = len(rows)\n\n for row_idx, row in enumerate(rows):\n try:\n source_term = row.get(\"source_term\", \"\").strip()\n target_term = row.get(\"target_term\", \"\").strip()\n context_notes = row.get(\"context_notes\", \"\").strip() or None\n source_language = row.get(\"source_language\", \"\").strip() or default_source_language or \"und\"\n target_language = row.get(\"target_language\", \"\").strip() or default_target_language or \"und\"\n\n if not source_term or not target_term:\n result[\"errors\"].append({\n \"line\": row_idx + 2, # +2 for header and 1-indexed\n \"error\": \"Both source_term and target_term are required\",\n \"row\": row,\n })\n continue\n\n normalized = _normalize_term(source_term)\n\n if preview_only:\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == source_language,\n DictionaryEntry.target_language == target_language,\n )\n .first()\n )\n preview_row = {\n \"line\": row_idx + 2,\n \"source_term\": source_term,\n \"target_term\": target_term,\n \"context_notes\": context_notes,\n \"source_language\": source_language,\n \"target_language\": target_language,\n \"is_conflict\": existing is not None,\n \"existing_target_term\": existing.target_term if existing else None,\n }\n result[\"preview\"].append(preview_row)\n continue\n\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == source_language,\n DictionaryEntry.target_language == target_language,\n )\n .first()\n )\n\n if existing:\n if on_conflict == \"overwrite\":\n existing.source_term = source_term\n existing.target_term = target_term\n existing.context_notes = context_notes\n existing.source_language = source_language\n existing.target_language = target_language\n result[\"updated\"] += 1\n elif on_conflict == \"keep_existing\":\n result[\"skipped\"] += 1\n else: # cancel\n result[\"errors\"].append({\n \"line\": row_idx + 2,\n \"error\": f\"Conflict on '{source_term}' and on_conflict='cancel'\",\n \"row\": row,\n })\n continue\n else:\n entry = DictionaryEntry(\n dictionary_id=dict_id,\n source_term=source_term,\n source_term_normalized=normalized,\n target_term=target_term,\n context_notes=context_notes,\n source_language=source_language,\n target_language=target_language,\n )\n db.add(entry)\n result[\"created\"] += 1\n\n except Exception as e:\n result[\"errors\"].append({\n \"line\": row_idx + 2,\n \"error\": str(e),\n \"row\": row,\n })\n\n if not preview_only:\n db.commit()\n\n logger.reflect(\"Import complete\", {\n \"dict_id\": dict_id,\n \"total\": result[\"total\"],\n \"created\": result[\"created\"],\n \"updated\": result[\"updated\"],\n \"skipped\": result[\"skipped\"],\n \"errors\": len(result[\"errors\"]),\n })\n return result\n # endregion DictionaryManager.import_entries\n\n # region DictionaryManager.export_entries [TYPE Function]\n # @PURPOSE Export all entries as CSV string with language columns.\n # @PRE dict_id exists.\n # @POST Returns CSV string with header: source_term, target_term, source_language, target_language, context_notes, context_data, usage_notes.\n @staticmethod\n def export_entries(\n db: Session, dict_id: str, delimiter: str = \",\",\n ) -> str:\n with belief_scope(\"DictionaryManager.export_entries\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n\n entries = (\n db.query(DictionaryEntry)\n .filter(DictionaryEntry.dictionary_id == dict_id)\n .order_by(DictionaryEntry.source_term.asc())\n .all()\n )\n\n output = io.StringIO()\n fieldnames = [\n \"source_term\", \"target_term\",\n \"source_language\", \"target_language\",\n \"context_notes\", \"context_data\", \"usage_notes\",\n ]\n writer = csv.DictWriter(output, fieldnames=fieldnames, delimiter=delimiter)\n writer.writeheader()\n\n for entry in entries:\n writer.writerow({\n \"source_term\": entry.source_term,\n \"target_term\": entry.target_term,\n \"source_language\": entry.source_language,\n \"target_language\": entry.target_language,\n \"context_notes\": entry.context_notes or \"\",\n \"context_data\": entry.context_data,\n \"usage_notes\": entry.usage_notes or \"\",\n })\n\n result = output.getvalue()\n logger.reflect(\"Entries exported\", {\"dict_id\": dict_id, \"count\": len(entries), \"delimiter\": repr(delimiter)})\n return result\n # endregion DictionaryManager.export_entries\n\n # region DictionaryManager.migrate_old_entries [TYPE Function]\n # @PURPOSE Migrate existing single-language dictionary entries to populate source_language and target_language.\n # @PRE db session is open.\n # @POST Entries with \"und\" source_language or target_language are updated with inferred values.\n # @SIDE_EFFECT Updates DictionaryEntry rows in bulk.\n @staticmethod\n def migrate_old_entries(db: Session) -> dict[str, int]:\n with belief_scope(\"DictionaryManager.migrate_old_entries\"):\n logger.reason(\"Starting migration of old dictionary entries\")\n migrated_source = 0\n migrated_target = 0\n skipped = 0\n\n # Find all entries that may need migration (source_language is \"und\" or target_language is \"und\")\n entries = (\n db.query(DictionaryEntry)\n .filter(\n (DictionaryEntry.source_language == \"und\") |\n (DictionaryEntry.target_language == \"und\")\n )\n .all()\n )\n\n for entry in entries:\n # Try to infer source_language from origin_source_language\n if entry.source_language == \"und\":\n if entry.origin_source_language:\n entry.source_language = entry.origin_source_language\n migrated_source += 1\n\n # Note: target_language inference from dictionary-level column was removed\n # because TerminologyDictionary.target_language was deprecated and dropped.\n\n if entry.source_language == \"und\" and entry.target_language == \"und\":\n skipped += 1\n\n db.commit()\n\n logger.reflect(\"Migration complete\", {\n \"migrated_source\": migrated_source,\n \"migrated_target\": migrated_target,\n \"skipped\": skipped,\n \"total_processed\": len(entries),\n })\n return {\n \"migrated_source\": migrated_source,\n \"migrated_target\": migrated_target,\n \"skipped\": skipped,\n \"total_processed\": len(entries),\n }\n # endregion DictionaryManager.migrate_old_entries\n\n # region DictionaryManager.filter_for_batch [TYPE Function]\n # @PURPOSE Scan batch texts for case-insensitive, word-boundary-aware matches against all dictionaries attached to a job,\n # optionally filtered by language pair. When row_context is provided, computes context-aware priority flags.\n # @PRE job_id exists and source_texts is a list of strings.\n # @POST Returns list of matched entries with match info, sorted by priority across attached dictionaries.\n # When row_context is given, each result includes a 'priority_match' boolean.\n # @SIDE_EFFECT Queries TranslationJobDictionary, TerminologyDictionary, and DictionaryEntry tables.\n @staticmethod\n def filter_for_batch(\n db: Session, source_texts: list[str], job_id: str,\n source_language: str | None = None,\n target_language: str | None = None,\n row_context: dict | None = None,\n ) -> list[dict[str, Any]]:\n with belief_scope(\"DictionaryManager.filter_for_batch\"):\n # Get dictionaries attached to this job\n job_dict_links = (\n db.query(TranslationJobDictionary)\n .filter(TranslationJobDictionary.job_id == job_id)\n .all()\n )\n if not job_dict_links:\n logger.reason(\"No dictionaries attached to job\", {\"job_id\": job_id})\n return []\n\n dict_ids = [jd.dictionary_id for jd in job_dict_links]\n\n # Get all active dictionaries\n dictionaries = (\n db.query(TerminologyDictionary)\n .filter(\n TerminologyDictionary.id.in_(dict_ids),\n TerminologyDictionary.is_active == True,\n )\n .all()\n )\n if not dictionaries:\n return []\n\n # Build dict_id -> dict_name lookup\n dict_map = {d.id: d.name for d in dictionaries}\n\n # Fetch all entries for these dictionaries, ordered by dictionary (priority order from link order)\n all_entries = (\n db.query(DictionaryEntry)\n .filter(DictionaryEntry.dictionary_id.in_(dict_ids))\n .order_by(DictionaryEntry.source_term.asc())\n .all()\n )\n\n if not all_entries:\n return []\n\n # PERFORMANCE NOTE: O(rows × entries) regex matching per batch.\n # Acceptable for current scale (50-100 rows × <1000 entries).\n # For larger batches (>500 rows or >5000 entries), consider\n # replacing with an Aho-Corasick automaton (e.g., pyahocorasick).\n matched: list[dict[str, Any]] = []\n seen_source_match: set = set()\n\n for text_idx, source_text in enumerate(source_texts):\n if not source_text:\n continue\n\n text_lower = source_text.lower()\n\n for entry in all_entries:\n norm = entry.source_term_normalized\n if not norm:\n continue\n\n # Apply language pair filtering\n if source_language is not None:\n src = source_language.strip().lower()\n entry_src = entry.source_language.strip().lower()\n if entry_src != src and entry_src != \"und\":\n continue\n if target_language is not None:\n tgt = target_language.strip().lower()\n entry_tgt = entry.target_language.strip().lower()\n if entry_tgt != tgt:\n continue\n\n # Word-boundary-aware matching\n # Build pattern: \\bterm\\b (case-insensitive)\n # Escape regex special chars in the search term\n escaped = re.escape(norm)\n pattern = re.compile(r\"\\b\" + escaped + r\"\\b\", re.IGNORECASE)\n\n if pattern.search(text_lower):\n match_key = (text_idx, entry.id)\n if match_key not in seen_source_match:\n seen_source_match.add(match_key)\n\n # Compute context-aware priority if row_context is available\n priority_match = False\n if row_context and entry.has_context and entry.context_data:\n similarity = ContextAwarePromptBuilder.compute_context_similarity(\n entry.context_data, row_context\n )\n priority_match = similarity >= 0.5\n\n matched.append({\n \"text_index\": text_idx,\n \"source_text\": source_text,\n \"entry_id\": entry.id,\n \"source_term\": entry.source_term,\n \"source_term_normalized\": entry.source_term_normalized,\n \"target_term\": entry.target_term,\n \"dictionary_id\": entry.dictionary_id,\n \"dictionary_name\": dict_map.get(entry.dictionary_id, \"\"),\n \"context_notes\": entry.context_notes,\n \"context_data\": entry.context_data,\n \"has_context\": entry.has_context,\n \"context_source\": entry.context_source,\n \"usage_notes\": entry.usage_notes,\n \"source_language\": entry.source_language,\n \"target_language\": entry.target_language,\n \"priority_match\": priority_match,\n })\n\n # Sort by dictionary link priority (order of dict_ids from link order)\n dict_priority = {d_id: idx for idx, d_id in enumerate(dict_ids)}\n matched.sort(key=lambda m: (dict_priority.get(m[\"dictionary_id\"], 999), m[\"text_index\"]))\n\n logger.reflect(\"Batch filter match complete\", {\n \"job_id\": job_id,\n \"source_texts\": len(source_texts),\n \"matches\": len(matched),\n \"dictionaries_used\": len(dictionaries),\n \"source_language\": source_language,\n \"target_language\": target_language,\n })\n return matched\n # endregion DictionaryManager.filter_for_batch\n\n\n # region DictionaryManager.submit_correction [TYPE Function]\n # @PURPOSE Submit a term correction from a run result. Validates language match, detects conflicts.\n # @PRE source_term, incorrect_target_term, corrected_target_term are non-empty. dict_id exists.\n # @POST Entry created or updated; origin tracking populated. Returns action + conflict info.\n # @SIDE_EFFECT Creates/updates DictionaryEntry row.\n @staticmethod\n def submit_correction(\n db: Session,\n dict_id: str,\n source_term: str,\n incorrect_target_term: str,\n corrected_target_term: str,\n origin_run_id: str | None = None,\n origin_row_key: str | None = None,\n origin_user_id: str | None = None,\n on_conflict: str = \"overwrite\",\n context_data: dict[str, Any] | None = None,\n usage_notes: str | None = None,\n keep_context: bool = True,\n ) -> dict[str, Any]:\n with belief_scope(\"DictionaryManager.submit_correction\"):\n # Validate dictionary exists\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary '{dict_id}' not found\")\n\n # Handle keep_context=False (user explicitly removed context)\n effective_context = context_data\n effective_context_source = \"auto\"\n if not keep_context:\n effective_context = None\n effective_context_source = \"manual\"\n\n normalized = _normalize_term(source_term)\n entry_src_lang = dictionary.source_dialect or \"und\"\n entry_tgt_lang = dictionary.target_dialect or \"und\"\n # Find existing entry: match exact language pair OR old-style \"und\"/\"und\" entries\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n or_(\n # Exact language pair match\n (DictionaryEntry.source_language == entry_src_lang) &\n (DictionaryEntry.target_language == entry_tgt_lang),\n # Old-style entries without language pair\n (DictionaryEntry.source_language == \"und\") &\n (DictionaryEntry.target_language == \"und\"),\n ),\n )\n .first()\n )\n\n result: dict[str, Any] = {\n \"source_term\": source_term,\n \"target_term\": corrected_target_term,\n \"action\": \"created\",\n \"entry_id\": None,\n \"conflict\": None,\n \"message\": None,\n }\n\n if existing:\n # Conflict detected\n if on_conflict == \"keep_existing\":\n result[\"action\"] = \"conflict_detected\"\n result[\"conflict\"] = {\n \"source_term\": source_term,\n \"existing_target_term\": existing.target_term,\n \"submitted_target_term\": corrected_target_term,\n \"action\": \"keep_existing\",\n }\n result[\"message\"] = f\"Existing entry kept: '{existing.target_term}'\"\n return result\n elif on_conflict == \"overwrite\":\n existing.target_term = corrected_target_term.strip()\n if origin_run_id:\n existing.origin_run_id = origin_run_id\n if origin_row_key:\n existing.origin_row_key = origin_row_key\n if origin_user_id:\n existing.origin_user_id = origin_user_id\n if context_data is not None or not keep_context:\n existing.context_data = effective_context\n existing.has_context = bool(effective_context)\n existing.context_source = effective_context_source\n if usage_notes is not None:\n existing.usage_notes = usage_notes\n db.flush()\n result[\"action\"] = \"updated\"\n result[\"entry_id\"] = existing.id\n result[\"message\"] = f\"Entry updated from '{existing.target_term}' to '{corrected_target_term}'\"\n else: # cancel\n result[\"action\"] = \"skipped\"\n result[\"conflict\"] = {\n \"source_term\": source_term,\n \"existing_target_term\": existing.target_term,\n \"submitted_target_term\": corrected_target_term,\n \"action\": \"cancel\",\n }\n result[\"message\"] = \"Correction cancelled by conflict mode\"\n return result\n else:\n # Create new entry — derive language pair from dictionary\n entry = DictionaryEntry(\n dictionary_id=dict_id,\n source_term=source_term.strip(),\n source_term_normalized=normalized,\n target_term=corrected_target_term.strip(),\n source_language=entry_src_lang,\n target_language=entry_tgt_lang,\n context_data=effective_context,\n usage_notes=usage_notes,\n has_context=bool(effective_context),\n context_source=effective_context_source if effective_context else None,\n origin_run_id=origin_run_id,\n origin_row_key=origin_row_key,\n origin_user_id=origin_user_id,\n )\n db.add(entry)\n db.flush()\n result[\"entry_id\"] = entry.id\n result[\"message\"] = f\"Entry created for '{source_term}' -> '{corrected_target_term}'\"\n\n db.commit()\n logger.reflect(\"Correction processed\", result)\n return result\n # endregion DictionaryManager.submit_correction\n\n # region DictionaryManager.submit_bulk_corrections [TYPE Function]\n # @PURPOSE Submit multiple term corrections atomically — all succeed or all fail.\n # @PRE corrections list is non-empty. dict_id exists.\n # @POST All corrections applied or none applied with conflict list.\n # @SIDE_EFFECT Creates/updates DictionaryEntry rows; commits once.\n @staticmethod\n def submit_bulk_corrections(\n db: Session,\n dict_id: str,\n corrections: list[dict[str, Any]],\n origin_user_id: str | None = None,\n ) -> dict[str, Any]:\n with belief_scope(\"DictionaryManager.submit_bulk_corrections\"):\n # Validate dictionary first\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary '{dict_id}' not found\")\n\n results: list[dict[str, Any]] = []\n conflicts: list[dict[str, Any]] = []\n all_ok = True\n\n for corr in corrections:\n source_term = corr.get(\"source_term\", \"\").strip()\n incorrect_target = corr.get(\"incorrect_target_term\", \"\").strip()\n corrected_target = corr.get(\"corrected_target_term\", \"\").strip()\n\n if not source_term or not corrected_target:\n results.append({\n \"source_term\": source_term,\n \"action\": \"error\",\n \"message\": \"source_term and corrected_target_term are required\",\n })\n all_ok = False\n continue\n\n normalized = _normalize_term(source_term)\n bulk_src_lang = dictionary.source_dialect or \"und\"\n bulk_tgt_lang = dictionary.target_dialect or \"und\"\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n or_(\n (DictionaryEntry.source_language == bulk_src_lang) &\n (DictionaryEntry.target_language == bulk_tgt_lang),\n (DictionaryEntry.source_language == \"und\") &\n (DictionaryEntry.target_language == \"und\"),\n ),\n )\n .first()\n )\n\n if existing:\n on_conflict = corr.get(\"on_conflict\", \"overwrite\")\n if on_conflict == \"keep_existing\":\n conflicts.append({\n \"source_term\": source_term,\n \"existing_target_term\": existing.target_term,\n \"submitted_target_term\": corrected_target,\n \"action\": \"keep_existing\",\n })\n results.append({\n \"source_term\": source_term,\n \"action\": \"conflict_detected\",\n \"message\": f\"Existing entry kept: '{existing.target_term}'\",\n })\n continue\n elif on_conflict == \"overwrite\":\n existing.target_term = corrected_target\n existing.origin_user_id = origin_user_id\n results.append({\n \"source_term\": source_term,\n \"action\": \"updated\",\n \"entry_id\": existing.id,\n \"message\": f\"Updated to '{corrected_target}'\",\n })\n else:\n conflicts.append({\n \"source_term\": source_term,\n \"existing_target_term\": existing.target_term,\n \"submitted_target_term\": corrected_target,\n \"action\": \"cancel\",\n })\n results.append({\n \"source_term\": source_term,\n \"action\": \"skipped\",\n \"message\": \"Cancelled by conflict mode\",\n })\n else:\n entry = DictionaryEntry(\n dictionary_id=dict_id,\n source_term=source_term,\n source_term_normalized=normalized,\n target_term=corrected_target,\n source_language=bulk_src_lang,\n target_language=bulk_tgt_lang,\n origin_run_id=corr.get(\"origin_run_id\"),\n origin_row_key=corr.get(\"origin_row_key\"),\n origin_user_id=origin_user_id,\n )\n db.add(entry)\n results.append({\n \"source_term\": source_term,\n \"action\": \"created\",\n \"message\": f\"Entry created for '{source_term}' -> '{corrected_target}'\",\n })\n\n if conflicts and not all_ok:\n # Rollback — all failed\n db.rollback()\n return {\n \"status\": \"conflicts\",\n \"results\": results,\n \"conflicts\": conflicts,\n \"message\": \"Conflicts detected. Resolve before retrying.\",\n }\n\n db.commit()\n\n return {\n \"status\": \"completed\",\n \"results\": results,\n \"conflicts\": conflicts,\n \"total\": len(corrections),\n \"applied\": sum(1 for r in results if r[\"action\"] in (\"created\", \"updated\")),\n }\n # endregion DictionaryManager.submit_bulk_corrections\n\n\n# #endregion DictionaryManager\n" }, { "contract_id": "TranslationEventLog", @@ -49839,7 +49099,7 @@ "contract_type": "Module", "file_path": "backend/src/plugins/translate/executor.py", "start_line": 1, - "end_line": 1429, + "end_line": 1974, "tier": "TIER_3", "complexity": 5, "metadata": { @@ -49895,14 +49155,14 @@ "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslationExecutor [C:5] [TYPE Module] [SEMANTICS sqlalchemy, tenacity, translate, insert, llm-retry]\n# @BRIEF Process translation in batches: fetch source rows, call LLM, persist TranslationBatch and TranslationRecord rows.\n# @LAYER: Domain\n# @RELATION DEPENDS_ON -> [TranslationBatch]\n# @RELATION DEPENDS_ON -> [TranslationRecord]\n# @RELATION DEPENDS_ON -> [TranslationRun]\n# @RELATION DEPENDS_ON -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [DictionaryManager]\n# @RELATION DEPENDS_ON -> [TranslationPreview]\n# @PRE: Valid TranslationRun with job configuration. DB session is available.\n# @POST: TranslationBatch and TranslationRecord rows are created. Run status is updated.\n# @SIDE_EFFECT: Calls LLM provider; creates DB rows; updates run statistics.\n# @DATA_CONTRACT Input: TranslationRun + Job -> Output: updated Run with batch/record rows\n# @INVARIANT Batch processing is independent — one batch failure does not affect others.\n# @RATIONALE: Batch processing with retry — independent batches allow partial recovery.\n# @REJECTED: Single monolithic LLM call — would lose all progress on any failure.\n\nimport json\nimport time\nimport uuid\nfrom collections.abc import Callable\nfrom datetime import UTC, datetime\nfrom typing import Any\n\nfrom sqlalchemy.orm import Session, joinedload\n\nfrom ...core.config_manager import ConfigManager\nfrom ...core.logger import belief_scope, logger\nfrom ...models.translate import (\n TranslationBatch,\n TranslationJob,\n TranslationLanguage,\n TranslationPreviewRecord,\n TranslationPreviewSession,\n TranslationRecord,\n TranslationRun,\n TranslationRunLanguageStats,\n)\nfrom ...services.llm_prompt_templates import render_prompt\nfrom ...services.llm_provider import LLMProviderService\nfrom ._token_budget import DEFAULT_CONTEXT_WINDOW, DEFAULT_MAX_OUTPUT_TOKENS, estimate_token_budget\nfrom .dictionary import DictionaryManager\nfrom .preview import DEFAULT_EXECUTION_PROMPT_TEMPLATE\nfrom .prompt_builder import ContextAwarePromptBuilder\nfrom .sql_generator import SQLGenerator\nfrom .superset_executor import SupersetSqlLabExecutor\n\n# #region MAX_RETRIES_PER_BATCH [TYPE Constant]\nMAX_RETRIES_PER_BATCH = 3\n# #endregion MAX_RETRIES_PER_BATCH\n\n# #region MAX_ROWS_PER_RUN [TYPE Constant]\n# Safety cap: without it, a datasource with thousands of rows blocks the single\n# uvicorn worker for minutes/hours. Preview uses sample_size (5-10). Full run\n# should stay within reasonable bounds.\nMAX_ROWS_PER_RUN = 10000\n# #endregion MAX_ROWS_PER_RUN\n\n# #region TranslationExecutor [C:4] [TYPE Class]\n# @BRIEF Process translation batches: fetch source rows, filter dict, call LLM, persist results.\n# @PRE: DB session and config manager available.\n# @POST: Batches and records created with status tracking.\n# @SIDE_EFFECT: LLM API calls; DB writes.\nclass TranslationExecutor:\n\n def __init__(\n self,\n db: Session,\n config_manager: ConfigManager,\n current_user: str | None = None,\n on_batch_progress: Callable[[str, int, int, int, int], None] | None = None,\n ):\n self.db = db\n self.config_manager = config_manager\n self.current_user = current_user\n self.on_batch_progress = on_batch_progress\n self._current_run_id: str | None = None\n self._preview_edits_cache: dict[str, dict[str, str]] | None = None # key_hash -> {lang_code: edited_value}\n\n # region execute_run [TYPE Function]\n # @PURPOSE: Run full translation execution for a TranslationRun.\n # @PRE: run is in PENDING or RUNNING status with valid job config.\n # @POST: Run is populated with batches and records.\n # @SIDE_EFFECT: LLM API calls; DB batch writes.\n def execute_run(\n self,\n run: TranslationRun,\n llm_progress_callback: Callable[[str, int, int, int], None] | None = None,\n language_stats_map: dict[str, TranslationRunLanguageStats] | None = None,\n ) -> TranslationRun:\n with belief_scope(\"TranslationExecutor.execute_run\"):\n job = self.db.query(TranslationJob).filter(TranslationJob.id == run.job_id).first()\n if not job:\n raise ValueError(f\"Job '{run.job_id}' not found for run '{run.id}'\")\n\n logger.reason(\"Starting translation execution\", {\n \"run_id\": run.id,\n \"job_id\": job.id,\n \"batch_size\": job.batch_size,\n })\n\n # Load preview edits for carry-forward\n self._load_preview_edits(job.id)\n\n # Mark run as RUNNING\n run.status = \"RUNNING\"\n run.started_at = datetime.now(UTC)\n self.db.flush()\n\n # Determine whether this is a full translation (all rows) or incremental (new/changed only)\n full_translation = False\n if run.config_snapshot and isinstance(run.config_snapshot, dict):\n full_translation = run.config_snapshot.get(\"full_translation\", False)\n\n # Fetch source rows from the datasource\n source_rows = self._fetch_source_rows(job.id, run.id)\n if not source_rows:\n logger.explore(\"No source rows to translate\", {\"run_id\": run.id})\n run.status = \"COMPLETED\"\n run.completed_at = datetime.now(UTC)\n self.db.flush()\n return run\n\n # Apply new-key-only filtering for scheduled runs OR manual incremental runs\n if run.trigger_type == \"new_key_only\" or (not full_translation and run.trigger_type == \"manual\"):\n source_rows = self._filter_new_keys(job, run.id, source_rows)\n if not source_rows:\n logger.reason(\"run_noop — no new rows to translate\", {\n \"job_id\": job.id, \"run_id\": run.id,\n })\n run.status = \"COMPLETED\"\n run.insert_status = \"skipped\"\n run.total_records = 0\n run.completed_at = datetime.now(UTC)\n self.db.commit()\n return\n\n total_rows = len(source_rows)\n run.total_records = total_rows\n\n # Split into batches\n batch_size = job.batch_size or 50\n batches = [\n source_rows[i:i + batch_size]\n for i in range(0, total_rows, batch_size)\n ]\n\n logger.reason(f\"Processing {len(batches)} batches\", {\n \"run_id\": run.id,\n \"total_rows\": total_rows,\n \"batch_size\": batch_size,\n })\n\n successful_records = 0\n failed_records = 0\n skipped_records = 0\n\n for batch_idx, batch_rows in enumerate(batches):\n batch_result = self._process_batch(\n job=job,\n run_id=run.id,\n batch_index=batch_idx,\n batch_rows=batch_rows,\n )\n successful_records += batch_result[\"successful\"]\n failed_records += batch_result[\"failed\"]\n skipped_records += batch_result[\"skipped\"]\n\n # Update run stats incrementally\n run.successful_records = successful_records\n run.failed_records = failed_records\n run.skipped_records = skipped_records\n\n # Commit after each batch to release row locks and make RUNNING\n # status + batch progress visible to other DB sessions (frontend polling).\n self.db.commit()\n\n # Incremental INSERT into target table after each batch,\n # so data appears incrementally in the target view/table\n # without waiting for the entire run to complete.\n batch_id = batch_result.get(\"batch_id\")\n if batch_id and batch_result[\"successful\"] > 0:\n try:\n self._insert_batch_to_target(job, batch_id, run.id)\n except Exception as e:\n logger.explore(\"Batch INSERT failed (non-fatal, continuing)\", {\n \"batch_id\": batch_id,\n \"error\": str(e),\n })\n\n # Re-fetch run after commit to check for cancellation flag set by\n # cancel_run() fallback (direct SQL UPDATE of error_message).\n self.db.refresh(run)\n if run.error_message == \"CANCEL_REQUESTED\":\n logger.reason(\"Cancellation requested — stopping batch processing\", {\n \"run_id\": run.id,\n \"batch_index\": batch_idx,\n })\n run.status = \"CANCELLED\"\n run.completed_at = datetime.now(UTC)\n run.error_message = None # Clear the orchestration flag\n self.db.commit()\n return run\n\n # Update per-language statistics incrementally after each batch\n # so the frontend shows real-time per-language counts for RUNNING runs.\n if language_stats_map and batch_result[\"successful\"] > 0:\n try:\n self._update_language_stats_incremental(run.id, language_stats_map)\n except Exception as e:\n logger.explore(\"Language stats update failed (non-fatal)\", {\n \"batch_id\": batch_id,\n \"error\": str(e),\n })\n\n if self.on_batch_progress:\n self.on_batch_progress(\n run.id, batch_idx + 1, len(batches),\n successful_records, total_rows,\n )\n\n # Update final run status\n if failed_records == 0 and skipped_records == 0:\n run.status = \"COMPLETED\"\n elif successful_records == 0:\n run.status = \"FAILED\"\n else:\n run.status = \"COMPLETED\" # Partial success\n\n run.completed_at = datetime.now(UTC)\n self.db.flush()\n\n logger.reflect(\"Translation execution complete\", {\n \"run_id\": run.id,\n \"status\": run.status,\n \"total\": total_rows,\n \"successful\": successful_records,\n \"failed\": failed_records,\n \"skipped\": skipped_records,\n })\n\n return run\n # endregion execute_run\n\n # region _fetch_source_rows [TYPE Function]\n # @PURPOSE: Fetch full source dataset from Superset (via datasource) for full translation.\n # @PRE: job_id exists. Job may have source_datasource_id for full fetch.\n # @POST: Returns list of dicts with source data (all rows from the source datasource).\n # @SIDE_EFFECT: Makes HTTP call to Superset chart data API when datasource is configured.\n def _fetch_source_rows(self, job_id: str, run_id: str) -> list[dict[str, Any]]:\n with belief_scope(\"TranslationExecutor._fetch_source_rows\"):\n job = self.db.query(TranslationJob).filter(TranslationJob.id == job_id).first()\n\n # If source_datasource_id is configured, fetch ALL rows from the Superset chart data API\n if job and job.source_datasource_id:\n try:\n logger.reason(\"Fetching full dataset from Superset datasource\", {\n \"run_id\": run_id,\n \"datasource_id\": job.source_datasource_id,\n \"environment_id\": job.environment_id,\n })\n\n # Determine environment\n environments = self.config_manager.get_environments()\n target_env_id = job.environment_id or job.source_dialect or \"\"\n env_config = next(\n (e for e in environments if e.id == target_env_id),\n None,\n )\n if not env_config and environments:\n env_config = environments[0]\n\n if env_config:\n from ...core.superset_client import SupersetClient\n client = SupersetClient(env_config)\n\n # Fetch dataset detail to build proper query context\n dataset_detail = client.get_dataset_detail(int(job.source_datasource_id))\n\n # Build query context (same approach as preview but without row_limit)\n query_context = client.build_dataset_preview_query_context(\n dataset_id=int(job.source_datasource_id),\n dataset_record=dataset_detail,\n template_params={},\n effective_filters=[],\n )\n\n # Use a safety cap instead of removing row_limit entirely.\n # Preview uses sample_size (5-10). Full runs should not fetch unlimited rows\n # because each batch of 20 rows × 4 languages takes ~40s of LLM time.\n queries = query_context.get(\"queries\", [])\n if queries:\n queries[0][\"row_limit\"] = MAX_ROWS_PER_RUN\n queries[0].pop(\"result_type\", None)\n queries[0][\"metrics\"] = []\n query_context[\"result_type\"] = \"samples\"\n form_data = query_context.get(\"form_data\", {})\n form_data.pop(\"query_mode\", None)\n\n response = client.network.request(\n method=\"POST\",\n endpoint=\"/api/v1/chart/data\",\n data=json.dumps(query_context),\n headers={\"Content-Type\": \"application/json\"},\n )\n\n # Extract rows\n rows = self._extract_chart_data_rows(response)\n\n if rows:\n logger.reason(f\"Fetched {len(rows)} rows from Superset datasource\", {\n \"run_id\": run_id,\n })\n # Map rows to source_rows format\n source_rows = []\n for idx, row in enumerate(rows):\n source_data_dict = dict(row) if row else None\n source_text = str(row.get(job.translation_column, \"\")) if job.translation_column else json.dumps(row)\n source_rows.append({\n \"row_index\": str(idx),\n \"source_text\": source_text,\n \"approved_translation\": None,\n \"source_object_name\": f\"Row {idx}\",\n \"source_data\": source_data_dict,\n })\n return source_rows\n else:\n logger.explore(\"Superset datasource returned no rows\", {\n \"run_id\": run_id,\n \"datasource_id\": job.source_datasource_id,\n })\n else:\n logger.explore(\"No environment config found for datasource fetch\", {\n \"env_id\": target_env_id,\n })\n except Exception as e:\n logger.explore(\"Failed to fetch full dataset from Superset, falling back to preview\", {\n \"run_id\": run_id,\n \"error\": str(e),\n })\n # Fall through to preview-based fetch\n\n # Fallback: get the latest APPLIED preview session\n session = (\n self.db.query(TranslationPreviewSession)\n .filter(\n TranslationPreviewSession.job_id == job_id,\n TranslationPreviewSession.status == \"APPLIED\",\n )\n .order_by(TranslationPreviewSession.created_at.desc())\n .first()\n )\n if not session:\n logger.explore(\"No accepted preview session found\", {\"job_id\": job_id})\n return []\n\n # Fetch APPROVED or all records from the session\n records = (\n self.db.query(TranslationPreviewRecord)\n .filter(\n TranslationPreviewRecord.session_id == session.id,\n TranslationPreviewRecord.status.in_([\"APPROVED\", \"PENDING\"]),\n )\n .all()\n )\n\n source_rows = []\n for rec in records:\n source_data_dict = None\n if hasattr(rec, \"source_data\") and rec.source_data:\n source_data_dict = dict(rec.source_data)\n source_rows.append({\n \"row_index\": rec.source_object_id or \"0\",\n \"source_text\": rec.source_sql or \"\",\n \"approved_translation\": rec.target_sql if rec.status == \"APPROVED\" else None,\n \"source_object_name\": rec.source_object_name or \"\",\n \"source_data\": source_data_dict,\n })\n\n logger.reason(f\"Fetched {len(source_rows)} source rows from preview fallback\", {\n \"run_id\": run_id,\n \"session_id\": session.id,\n })\n return source_rows\n # endregion _fetch_source_rows\n\n # region _filter_new_keys [TYPE Function]\n # @PURPOSE: Filter source rows to only include those with keys absent from the last successful run.\n # @PRE: job and run are persisted; source_rows is a list of dicts with source_data containing key columns.\n # @POST: Returns filtered list of source rows with only new keys. Logs skip count.\n # @SIDE_EFFECT: Queries TranslationRecord from previous runs; no writes.\n def _filter_new_keys(self, job, run_id: str, source_rows: list) -> list:\n with belief_scope(\"TranslationExecutor._filter_new_keys\"):\n # Find most recent COMPLETED run with successful insert for this job\n prev_run = (\n self.db.query(TranslationRun)\n .filter(\n TranslationRun.job_id == job.id,\n TranslationRun.status == \"COMPLETED\",\n TranslationRun.insert_status == \"succeeded\",\n TranslationRun.id != run_id,\n )\n .order_by(TranslationRun.created_at.desc())\n .first()\n )\n if not prev_run:\n logger.reason(\"No prior successful run — all keys treated as new\", {\n \"job_id\": job.id,\n })\n return source_rows\n\n # Get successful records from that run\n prev_records = (\n self.db.query(TranslationRecord)\n .filter(\n TranslationRecord.run_id == prev_run.id,\n TranslationRecord.status == \"SUCCESS\",\n )\n .all()\n )\n if not prev_records:\n return source_rows\n\n # Build set of already-translated composite keys\n key_cols = job.target_key_cols or job.source_key_cols or []\n if not key_cols:\n logger.explore(\"No key columns configured — skipping new-key-only filter\",\n {\"job_id\": job.id})\n return source_rows\n existing_keys = set()\n for rec in prev_records:\n sd = rec.source_data or {}\n key_tuple = tuple(str(sd.get(k, \"\")) for k in key_cols)\n existing_keys.add(key_tuple)\n\n # Filter: keep only rows whose keys are NOT in the existing set\n filtered = []\n skipped = 0\n for row in source_rows:\n sd = row.get(\"source_data\", {}) or {}\n key_tuple = tuple(str(sd.get(k, \"\")) for k in key_cols)\n if key_tuple not in existing_keys:\n filtered.append(row)\n else:\n skipped += 1\n\n logger.reason(f\"New-key-only filter: {len(source_rows)} total → {len(filtered)} new, {skipped} skipped\", {\n \"job_id\": job.id,\n \"prev_run_id\": prev_run.id,\n \"key_cols\": key_cols,\n })\n return filtered\n # endregion _filter_new_keys\n\n # region _extract_chart_data_rows [TYPE Function]\n # @PURPOSE: Extract data rows from Superset chart data API response.\n # @POST: Returns list of dicts with column-value pairs.\n @staticmethod\n def _extract_chart_data_rows(response: dict[str, Any]) -> list[dict[str, Any]]:\n result = response.get(\"result\")\n if isinstance(result, list):\n for item in result:\n if isinstance(item, dict):\n data = item.get(\"data\")\n if isinstance(data, list) and data:\n return data\n if isinstance(result, dict):\n data = result.get(\"data\")\n if isinstance(data, list) and data:\n return data\n data = response.get(\"data\")\n if isinstance(data, list) and data:\n return data\n if isinstance(result, list):\n return result\n return []\n # endregion _extract_chart_data_rows\n\n # region _load_preview_edits [TYPE Function]\n # @PURPOSE: Load user edits from accepted preview session for carry-forward.\n # @PRE: job_id exists.\n # @POST: Populates _preview_edits_cache with key_hash -> {lang_code: edited_value}.\n # @SIDE_EFFECT: Queries TranslationPreviewLanguage and TranslationPreviewRecord.\n def _load_preview_edits(self, job_id: str) -> None:\n \"\"\"Load preview edits for carry-forward during execution.\"\"\"\n from ...models.translate import TranslationPreviewLanguage, TranslationPreviewRecord, TranslationPreviewSession\n\n with belief_scope(\"TranslationExecutor._load_preview_edits\"):\n session = (\n self.db.query(TranslationPreviewSession)\n .filter(\n TranslationPreviewSession.job_id == job_id,\n TranslationPreviewSession.status == \"APPLIED\",\n )\n .order_by(TranslationPreviewSession.created_at.desc())\n .first()\n )\n if not session:\n logger.reason(\"No applied preview session found — no edits to carry forward\", {\n \"job_id\": job_id,\n })\n self._preview_edits_cache = {}\n return\n\n records = (\n self.db.query(TranslationPreviewRecord)\n .filter(TranslationPreviewRecord.session_id == session.id)\n .all()\n )\n\n edits: dict[str, dict[str, str]] = {}\n for rec in records:\n if not rec.source_data:\n continue\n # Compute key hash from source_data\n key_hash = self._compute_key_hash(rec.source_data)\n edited_langs: dict[str, str] = {}\n for lang_entry in (rec.languages or []):\n if lang_entry.status in (\"edited\", \"approved\") and lang_entry.user_edit:\n edited_langs[lang_entry.language_code] = lang_entry.final_value or lang_entry.user_edit\n logger.reason(\"Carrying forward preview edit\", {\n \"key_hash\": key_hash,\n \"language_code\": lang_entry.language_code,\n })\n if edited_langs:\n edits[key_hash] = edited_langs\n\n self._preview_edits_cache = edits\n logger.reason(f\"Loaded {len(edits)} preview edits for carry-forward\", {\n \"job_id\": job_id,\n })\n # endregion _load_preview_edits\n\n # region _compute_key_hash [TYPE Function]\n # @PURPOSE: Compute a stable hash from source_data dict for matching preview edits.\n @staticmethod\n def _compute_key_hash(source_data: dict) -> str:\n import hashlib\n stable = json.dumps(source_data, sort_keys=True)\n return hashlib.sha256(stable.encode()).hexdigest()[:16]\n # endregion _compute_key_hash\n\n # region _process_batch [TYPE Function]\n # @PURPOSE: Process a single batch: filter dict, build prompt, call LLM, persist records.\n # @PRE: job and batch_rows are valid.\n # @POST: TranslationBatch and TranslationRecord rows are created.\n # @SIDE_EFFECT: LLM API call.\n def _process_batch(\n self,\n job: TranslationJob,\n run_id: str,\n batch_index: int,\n batch_rows: list[dict[str, Any]],\n ) -> dict[str, int]:\n with belief_scope(\"TranslationExecutor._process_batch\"):\n batch_start = time.monotonic()\n\n # Create batch record\n batch = TranslationBatch(\n id=str(uuid.uuid4()),\n run_id=run_id,\n batch_index=batch_index,\n status=\"RUNNING\",\n total_records=len(batch_rows),\n started_at=datetime.now(UTC),\n )\n self.db.add(batch)\n self.db.flush()\n batch_id = batch.id\n\n result = {\"successful\": 0, \"failed\": 0, \"skipped\": 0, \"retries\": 0}\n\n # Extract source texts for dict filtering\n source_texts = [\n row.get(\"source_text\", \"\")\n for row in batch_rows\n if row.get(\"source_text\")\n ]\n\n # Filter dictionary entries with row context for priority matching\n row_context = batch_rows[0].get(\"source_data\") if batch_rows else None\n dict_matches = DictionaryManager.filter_for_batch(\n self.db, source_texts, job.id,\n row_context=row_context,\n )\n\n # For each row, determine if we need LLM translation or can use approved/preview edit\n rows_for_llm = []\n pre_translated = []\n\n for row in batch_rows:\n if row.get(\"approved_translation\"):\n pre_translated.append(row)\n continue\n\n # Check for preview edits carry-forward\n source_data = row.get(\"source_data\") or {}\n if source_data and self._preview_edits_cache:\n key_hash = self._compute_key_hash(source_data)\n preview_edit = self._preview_edits_cache.get(key_hash)\n if preview_edit:\n # Use the first edited language's value as the approved translation\n first_edit = next(iter(preview_edit.values()), None)\n if first_edit:\n row[\"approved_translation\"] = first_edit\n logger.reason(\"Using preview edit carry-forward\", {\n \"key_hash\": key_hash,\n \"langs\": list(preview_edit.keys()),\n })\n pre_translated.append(row)\n continue\n\n rows_for_llm.append(row)\n\n # Handle pre-translated (approved) rows\n target_languages = job.target_languages or [job.target_dialect or \"en\"]\n if not isinstance(target_languages, list):\n target_languages = [str(target_languages)]\n\n for row in pre_translated:\n record = TranslationRecord(\n id=str(uuid.uuid4()),\n batch_id=batch_id,\n run_id=run_id,\n source_sql=row.get(\"source_text\", \"\"),\n target_sql=row.get(\"approved_translation\"),\n source_object_type=\"table_row\",\n source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"),\n status=\"SUCCESS\",\n )\n self.db.add(record)\n\n # Create per-language entry for each target language (pre-approved)\n for lang_code in target_languages:\n lang_entry = TranslationLanguage(\n id=str(uuid.uuid4()),\n record_id=record.id,\n language_code=lang_code,\n source_language_detected=\"und\",\n translated_value=row.get(\"approved_translation\"),\n final_value=row.get(\"approved_translation\"),\n status=\"translated\",\n needs_review=False,\n )\n self.db.add(lang_entry)\n result[\"successful\"] += 1\n\n # Process rows needing LLM translation\n if rows_for_llm:\n # Check token budget for this batch to determine safe max_tokens\n token_budget = estimate_token_budget(\n source_rows=rows_for_llm,\n target_languages=target_languages,\n source_column=\"source_text\",\n context_columns=None, # Context is embedded in dict, not separate column\n dictionary_entries=dict_matches,\n batch_size=len(rows_for_llm),\n context_window=DEFAULT_CONTEXT_WINDOW,\n max_output_tokens=DEFAULT_MAX_OUTPUT_TOKENS,\n )\n if token_budget[\"warning\"]:\n logger.explore(\"Token budget warning for batch\", {\n \"batch_id\": batch_id,\n \"batch_index\": batch_index,\n \"warning\": token_budget[\"warning\"],\n })\n\n llm_result = self._call_llm_for_batch(\n job=job,\n run_id=run_id,\n batch_rows=rows_for_llm,\n dict_matches=dict_matches,\n batch_id=batch_id,\n max_tokens=token_budget[\"max_output_needed\"],\n )\n result[\"successful\"] += llm_result[\"successful\"]\n result[\"failed\"] += llm_result[\"failed\"]\n result[\"skipped\"] += llm_result[\"skipped\"]\n result[\"retries\"] += llm_result.get(\"retries\", 0)\n\n # Update batch status\n batch.successful_records = result[\"successful\"]\n batch.failed_records = result[\"failed\"]\n batch.completed_at = datetime.now(UTC)\n batch.status = \"COMPLETED\" if result[\"failed\"] == 0 else \"COMPLETED_WITH_ERRORS\"\n self.db.flush()\n\n batch_latency = int((time.monotonic() - batch_start) * 1000)\n logger.reason(f\"Batch {batch_index} complete\", {\n \"batch_id\": batch_id,\n \"latency_ms\": batch_latency,\n **result,\n })\n\n return {**result, \"batch_id\": batch_id}\n # endregion _process_batch\n\n # region _insert_batch_to_target [TYPE Function]\n # @PURPOSE: Insert successful records from a single batch into the target table via Superset SQL Lab.\n # @PRE: batch has committed TranslationRecords with status SUCCESS. job has target_table configured.\n # @POST: Per record, N+1 rows are INSERTED: 1 original + N translations.\n # Context columns are bundled into JSON in the `context` column.\n # `is_original=1` marks the source-language row.\n # @SIDE_EFFECT: HTTP call to Superset SQL Lab API. Writes to target database.\n def _insert_batch_to_target(\n self,\n job: TranslationJob,\n batch_id: str,\n run_id: str,\n ) -> None:\n with belief_scope(\"TranslationExecutor._insert_batch_to_target\"):\n records = (\n self.db.query(TranslationRecord)\n .options(joinedload(TranslationRecord.languages))\n .filter(\n TranslationRecord.batch_id == batch_id,\n TranslationRecord.status == \"SUCCESS\",\n TranslationRecord.target_sql.isnot(None),\n )\n .all()\n )\n\n if not records:\n return\n\n effective_target = job.target_column or job.translation_column\n primary_language = (job.target_languages or [\"en\"])[0]\n\n # Columns that exist in the target ClickHouse table\n columns = []\n if job.target_key_cols:\n columns.extend(job.target_key_cols)\n if effective_target:\n columns.append(effective_target)\n if job.target_language_column:\n columns.append(job.target_language_column)\n if job.target_source_column:\n columns.append(job.target_source_column)\n if job.target_source_language_column:\n columns.append(job.target_source_language_column)\n columns.append(\"context\")\n columns.append(\"is_original\")\n # Deduplicate while preserving order\n seen: set[str] = set()\n deduped: list[str] = []\n for c in columns:\n if c and c not in seen:\n deduped.append(c)\n seen.add(c)\n columns = deduped\n\n # Keys for the context JSON: context_columns + original translation_column\n context_keys = list(job.context_columns or [])\n if job.translation_column and job.translation_column != effective_target and job.translation_column not in context_keys:\n context_keys.append(job.translation_column)\n\n rows_for_sql: list[dict[str, object]] = []\n for rec in records:\n source_data = rec.source_data or {}\n\n # Detect source language from first TranslationLanguage entry\n detected_src_lang = \"und\"\n if rec.languages and len(rec.languages) > 0:\n detected_src_lang = rec.languages[0].source_language_detected or \"und\"\n\n # Build context JSON: all extra columns the user configured\n context_data: dict[str, str] = {}\n for key in context_keys:\n val = source_data.get(key)\n context_data[key] = str(val) if val is not None else \"\"\n\n # ── Shared base row (columns common to original and all translations) ──\n base_row: dict[str, object] = {}\n\n # Key columns (report_date, document_number)\n if job.target_key_cols:\n for k in job.target_key_cols:\n base_row[k] = source_data.get(k, \"\")\n\n # Source text: original\n if job.target_source_column:\n base_row[job.target_source_column] = rec.source_sql or \"\"\n\n # Source language (same for all rows of this record)\n if job.target_source_language_column:\n base_row[job.target_source_language_column] = detected_src_lang\n\n # Context JSON string\n base_row[\"context\"] = json.dumps(context_data, ensure_ascii=False)\n\n # ── 1. ORIGINAL row (is_original = 1) ──\n original_row = dict(base_row)\n if effective_target:\n original_row[effective_target] = rec.source_sql or \"\"\n if job.target_language_column:\n original_row[job.target_language_column] = detected_src_lang\n original_row[\"is_original\"] = 1\n rows_for_sql.append(original_row)\n\n # ── 2. TRANSLATION rows (is_original = 0) ──\n # Skip language that matches the source — the original row already covers it\n if rec.languages and len(rec.languages) > 0:\n for lang in rec.languages:\n if lang.language_code == detected_src_lang:\n continue\n trans_row = dict(base_row)\n trans_value = lang.final_value or lang.translated_value or \"\"\n if effective_target:\n trans_row[effective_target] = trans_value\n if job.target_language_column:\n trans_row[job.target_language_column] = lang.language_code\n trans_row[\"is_original\"] = 0\n rows_for_sql.append(trans_row)\n else:\n # Fallback: no per-language data → single translation row with primary language\n fallback_row = dict(base_row)\n if effective_target:\n fallback_row[effective_target] = rec.target_sql or \"\"\n if job.target_language_column:\n fallback_row[job.target_language_column] = primary_language\n fallback_row[\"is_original\"] = 0\n rows_for_sql.append(fallback_row)\n\n if not columns:\n columns = [effective_target or \"translated_text\"]\n rows_for_sql = [{columns[0]: rec.target_sql or \"\"} for rec in records]\n\n try:\n env_id = job.environment_id or job.source_dialect or \"\"\n executor = SupersetSqlLabExecutor(self.config_manager, env_id)\n executor.resolve_database_id(target_database_id=job.target_database_id)\n real_backend = executor.get_database_backend()\n except Exception as e:\n logger.explore(\"Failed to resolve database backend for batch insert\", {\n \"batch_id\": batch_id,\n \"error\": str(e),\n })\n real_backend = None\n\n dialect = real_backend or job.database_dialect or job.target_dialect or \"postgresql\"\n\n try:\n sql, row_count = SQLGenerator.generate(\n dialect=dialect,\n target_schema=job.target_schema,\n target_table=job.target_table or \"translated_data\",\n columns=columns,\n rows=rows_for_sql,\n key_columns=job.target_key_cols,\n upsert_strategy=job.upsert_strategy or \"MERGE\",\n )\n except ValueError as e:\n logger.explore(\"SQL generation failed for batch\", {\n \"batch_id\": batch_id,\n \"error\": str(e),\n })\n return\n\n try:\n result = executor.execute_and_poll(\n sql=sql,\n max_polls=30,\n poll_interval_seconds=2.0,\n )\n except Exception as e:\n logger.explore(\"Superset SQL submission failed for batch\", {\n \"batch_id\": batch_id,\n \"error\": str(e),\n })\n return\n\n logger.reason(f\"Batch {batch_id[:12]} inserted {row_count} rows\", {\n \"batch_id\": batch_id,\n \"rows\": row_count,\n \"status\": result.get(\"status\"),\n })\n # endregion _insert_batch_to_target\n\n # region _update_language_stats_incremental [TYPE Function]\n # @PURPOSE: Update per-language TranslationRunLanguageStats incrementally after each batch.\n # @PRE: language_stats_map has entries for all target languages.\n # @POST: Language stat objects updated with counts from committed TranslationLanguage rows.\n # @SIDE_EFFECT: Mutates ORM objects; caller must commit.\n def _update_language_stats_incremental(\n self,\n run_id: str,\n language_stats_map: dict[str, TranslationRunLanguageStats],\n ) -> None:\n with belief_scope(\"TranslationExecutor._update_language_stats_incremental\"):\n records = (\n self.db.query(TranslationRecord)\n .filter(TranslationRecord.run_id == run_id)\n .all()\n )\n record_ids = [r.id for r in records]\n if not record_ids:\n return\n\n lang_entries = (\n self.db.query(TranslationLanguage)\n .filter(TranslationLanguage.record_id.in_(record_ids))\n .all()\n )\n\n from collections import defaultdict\n agg: dict[str, dict[str, int]] = defaultdict(\n lambda: {\"total\": 0, \"translated\": 0, \"failed\": 0, \"skipped\": 0}\n )\n for le in lang_entries:\n code = le.language_code\n agg[code][\"total\"] += 1\n if le.status in (\"translated\", \"approved\", \"edited\"):\n agg[code][\"translated\"] += 1\n elif le.status == \"failed\":\n agg[code][\"failed\"] += 1\n elif le.status == \"skipped\":\n agg[code][\"skipped\"] += 1\n\n total_tokens_est = max(1, sum(len(le.translated_value or \"\") for le in lang_entries if le.translated_value) // 4)\n num_langs = len(language_stats_map) or 1\n cost_per_token = 0.002 / 1000\n\n for lang_code, lang_stat in language_stats_map.items():\n data = agg.get(lang_code, {\"total\": 0, \"translated\": 0, \"failed\": 0, \"skipped\": 0})\n lang_stat.total_rows = data[\"total\"]\n lang_stat.translated_rows = data[\"translated\"]\n lang_stat.failed_rows = data[\"failed\"]\n lang_stat.skipped_rows = data[\"skipped\"]\n lang_stat.token_count = total_tokens_est // num_langs\n lang_stat.estimated_cost = round((lang_stat.token_count / 1000) * cost_per_token, 6)\n\n self.db.flush()\n # endregion _update_language_stats_incremental\n\n # region _call_llm_for_batch [TYPE Function]\n # @PURPOSE: Call LLM for a batch of rows requiring translation. Parse structured JSON response.\n # @PRE: job has valid provider_id. batch_rows is non-empty.\n # @POST: Returns dict with successful/failed/skipped counts. Creates TranslationRecord rows.\n # @SIDE_EFFECT: HTTP call to LLM provider.\n def _call_llm_for_batch(\n self,\n job: TranslationJob,\n run_id: str,\n batch_rows: list[dict[str, Any]],\n dict_matches: list[dict[str, Any]],\n batch_id: str,\n max_tokens: int = 8192,\n ) -> dict[str, int]:\n with belief_scope(\"TranslationExecutor._call_llm_for_batch\"):\n # Build dictionary section using ContextAwarePromptBuilder\n dictionary_section = \"\"\n if dict_matches:\n # Get row_context from first batch row if available\n row_context = batch_rows[0].get(\"source_data\") if batch_rows else None\n\n # Use ContextAwarePromptBuilder for context-aware annotations\n annotated_entries = ContextAwarePromptBuilder.build_context_entries(\n dict_matches, row_context\n )\n glossary_lines = []\n for annotated_line in annotated_entries:\n glossary_lines.append(f\"- {annotated_line}\")\n dictionary_section = (\n \"Terminology dictionary (use these translations when applicable):\\n\"\n + \"\\n\".join(glossary_lines)\n + \"\\n\\n\"\n )\n\n # Resolve target languages\n target_languages = job.target_languages or [job.target_dialect or \"en\"]\n if not isinstance(target_languages, list):\n target_languages = [str(target_languages)]\n target_languages_str = \", \".join(target_languages)\n\n # Build rows JSON for LLM\n rows_json = json.dumps([\n {\n \"row_id\": str(row.get(\"row_index\", idx)),\n \"text\": row.get(\"source_text\", \"\"),\n }\n for idx, row in enumerate(batch_rows)\n ], indent=2)\n\n # Build prompt (use multi-language format)\n prompt = render_prompt(\n DEFAULT_EXECUTION_PROMPT_TEMPLATE,\n {\n \"source_language\": job.source_dialect or \"SQL\",\n \"target_language\": target_languages_str,\n \"target_languages\": target_languages_str,\n \"source_dialect\": job.source_dialect or \"\",\n \"target_dialect\": job.target_dialect or \"\",\n \"translation_column\": job.translation_column or \"\",\n \"dictionary_section\": dictionary_section,\n \"rows_json\": rows_json,\n \"row_count\": str(len(batch_rows)),\n },\n )\n\n # Call LLM with retry\n llm_response = None\n last_error = None\n retries = 0\n\n for attempt in range(1, MAX_RETRIES_PER_BATCH + 1):\n try:\n llm_response = self._call_llm(job, prompt, max_tokens=max_tokens)\n break\n except Exception as e:\n last_error = str(e)\n retries += 1\n logger.explore(f\"LLM call failed (attempt {attempt})\", {\n \"batch_id\": batch_id,\n \"error\": last_error,\n \"attempt\": attempt,\n })\n if attempt < MAX_RETRIES_PER_BATCH:\n time.sleep(2 ** attempt) # Exponential backoff\n else:\n logger.explore(\"LLM call exhausted retries\", {\n \"batch_id\": batch_id,\n \"last_error\": last_error,\n })\n\n if llm_response is None:\n # All retries failed — mark all rows as failed\n for row in batch_rows:\n record = TranslationRecord(\n id=str(uuid.uuid4()),\n batch_id=batch_id,\n run_id=run_id,\n source_sql=row.get(\"source_text\", \"\"),\n target_sql=None,\n source_object_type=\"table_row\",\n source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"),\n status=\"FAILED\",\n error_message=f\"LLM call failed after {retries} retries: {last_error}\",\n )\n self.db.add(record)\n return {\"successful\": 0, \"failed\": len(batch_rows), \"skipped\": 0, \"retries\": retries}\n\n # Parse LLM response (multi-language aware)\n try:\n translations = self._parse_llm_response(llm_response, len(batch_rows), target_languages=target_languages)\n except ValueError as e:\n # Parse failure — mark all rows as SKIPPED\n logger.explore(\"LLM response parse failed\", {\n \"batch_id\": batch_id,\n \"error\": str(e),\n \"response_preview\": llm_response[:500] if llm_response else \"\",\n })\n skipped = len(batch_rows)\n for row in batch_rows:\n record = TranslationRecord(\n id=str(uuid.uuid4()),\n batch_id=batch_id,\n run_id=run_id,\n source_sql=row.get(\"source_text\", \"\"),\n target_sql=None,\n source_object_type=\"table_row\",\n source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"),\n status=\"SKIPPED\",\n error_message=f\"LLM parse failure: {e}\",\n )\n self.db.add(record)\n return {\n \"successful\": 0,\n \"failed\": 0,\n \"skipped\": skipped,\n \"retries\": retries,\n }\n\n successful = 0\n failed = 0\n skipped = 0\n\n for row in batch_rows:\n row_id = str(row.get(\"row_index\", \"\"))\n translation_data = translations.get(row_id)\n source_text = row.get(\"source_text\", \"\")\n detected_lang = \"und\"\n if translation_data:\n detected_lang = translation_data.get(\"detected_source_language\", \"und\")\n\n if translation_data is None:\n # NULL translation — skip\n skipped += 1\n record = TranslationRecord(\n id=str(uuid.uuid4()),\n batch_id=batch_id,\n run_id=run_id,\n source_sql=source_text,\n target_sql=\"\",\n source_object_type=\"table_row\",\n source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"),\n status=\"SKIPPED\",\n error_message=\"NULL translation returned by LLM\",\n )\n self.db.add(record)\n continue\n\n # Collect per-language translated values\n per_lang_values: dict[str, str] = {}\n has_any_translation = False\n\n # First try multi-language format (per-language keys)\n for lang_code in target_languages:\n lang_val = translation_data.get(lang_code)\n if lang_val is not None and str(lang_val).strip():\n per_lang_values[lang_code] = str(lang_val)\n has_any_translation = True\n\n # Fallback to legacy single \"translation\" key format\n if not has_any_translation:\n translation_text = translation_data.get(\"translation\", \"\")\n if translation_text.strip():\n per_lang_values[target_languages[0]] = translation_text\n has_any_translation = True\n\n if not has_any_translation:\n # Empty/all-empty translations — skip\n skipped += 1\n record = TranslationRecord(\n id=str(uuid.uuid4()),\n batch_id=batch_id,\n run_id=run_id,\n source_sql=source_text,\n target_sql=\"\",\n source_object_type=\"table_row\",\n source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"),\n status=\"SKIPPED\",\n error_message=\"Empty translation returned by LLM\",\n )\n self.db.add(record)\n continue\n\n # Use the first language's value as the primary target_sql for backward compat\n primary_translation = next(iter(per_lang_values.values()), \"\")\n\n successful += 1\n record = TranslationRecord(\n id=str(uuid.uuid4()),\n batch_id=batch_id,\n run_id=run_id,\n source_sql=source_text,\n target_sql=primary_translation,\n source_object_type=\"table_row\",\n source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"),\n status=\"SUCCESS\",\n )\n self.db.add(record)\n\n # Create per-language entries — one TranslationLanguage per language_code\n for lang_code in target_languages:\n lang_translation = per_lang_values.get(lang_code, \"\")\n\n # Source-as-reference: if detected source language matches this target,\n # store the original text verbatim (no translation needed)\n if detected_lang != \"und\" and str(lang_code).lower() == str(detected_lang).lower():\n lang_translation = source_text\n\n # Check for undetermined source language\n lang_needs_review = (detected_lang == \"und\")\n\n if lang_needs_review:\n logger.explore(\"undetected language\", {\n \"record_id\": row_id,\n \"language_code\": lang_code,\n \"source_text\": source_text[:100],\n })\n\n lang_entry = TranslationLanguage(\n id=str(uuid.uuid4()),\n record_id=record.id,\n language_code=lang_code,\n source_language_detected=detected_lang,\n translated_value=lang_translation or \"\",\n final_value=lang_translation or \"\",\n status=\"translated\",\n needs_review=lang_needs_review,\n )\n self.db.add(lang_entry)\n\n return {\n \"successful\": successful,\n \"failed\": failed,\n \"skipped\": skipped,\n \"retries\": retries,\n }\n # endregion _call_llm_for_batch\n\n # region _call_llm [TYPE Function]\n # @PURPOSE: Call the configured LLM provider with the batch prompt.\n # @PRE: job has valid provider_id.\n # @POST: Returns raw LLM response string.\n # @SIDE_EFFECT: HTTP call to LLM provider.\n def _call_llm(self, job: TranslationJob, prompt: str, max_tokens: int = 8192) -> str:\n with belief_scope(\"TranslationExecutor._call_llm\"):\n if not job.provider_id:\n raise ValueError(\"Job has no LLM provider configured\")\n\n provider_svc = LLMProviderService(self.db)\n provider = provider_svc.get_provider(job.provider_id)\n if not provider:\n raise ValueError(f\"LLM provider '{job.provider_id}' not found\")\n\n api_key = provider_svc.get_decrypted_api_key(job.provider_id)\n if not api_key:\n raise ValueError(f\"Could not decrypt API key for provider '{job.provider_id}'\")\n\n model = provider.default_model or \"gpt-4o-mini\"\n provider_type = provider.provider_type.lower() if provider.provider_type else \"openai\"\n\n disable_reasoning = getattr(job, 'disable_reasoning', False)\n\n if provider_type in (\"openai\", \"openai_compatible\", \"openrouter\", \"kilo\"):\n response_text = self._call_openai_compatible(\n base_url=provider.base_url,\n api_key=api_key,\n model=model,\n prompt=prompt,\n provider_type=provider_type,\n max_tokens=max_tokens,\n disable_reasoning=disable_reasoning,\n )\n return response_text\n else:\n raise ValueError(f\"Unsupported provider type '{provider_type}'\")\n # endregion _call_llm\n\n # region _call_openai_compatible [TYPE Function]\n # @PURPOSE: Call OpenAI-compatible API for batch translation.\n # @PRE: Valid API endpoint, key, model, and prompt.\n # @POST: Returns response text.\n # @SIDE_EFFECT: HTTP POST to LLM API.\n @staticmethod\n def _call_openai_compatible(\n base_url: str,\n api_key: str,\n model: str,\n prompt: str,\n provider_type: str = \"openai\",\n max_tokens: int = 8192,\n disable_reasoning: bool = False,\n ) -> str:\n with belief_scope(\"TranslationExecutor._call_openai_compatible\"):\n import requests as http_requests\n\n url = f\"{base_url.rstrip('/')}/chat/completions\"\n headers = {\n \"Authorization\": f\"Bearer {api_key}\",\n \"Content-Type\": \"application/json\",\n }\n payload = {\n \"model\": model,\n \"messages\": [\n {\"role\": \"system\", \"content\": \"You are a database content translation assistant. Translate the provided text accurately, preserving data semantics.\"},\n {\"role\": \"user\", \"content\": prompt},\n ],\n \"temperature\": 0.1,\n \"max_tokens\": max_tokens,\n }\n # Structured output — OpenRouter and Kilo also support response_format, but some\n # upstream providers (e.g. StepFun) reject it. We try with response_format and\n # fall back on 400 \"structured_outputs is not supported\".\n if provider_type in (\"openai\", \"openai_compatible\", \"kilo\", \"openrouter\"):\n payload[\"response_format\"] = {\"type\": \"json_object\"}\n\n # Suppress Chain of Thought reasoning to save output tokens\n # NOTE: Kilo/OpenRouter do NOT support disabling reasoning (returns 400)\n if disable_reasoning:\n if provider_type not in (\"kilo\", \"openrouter\"):\n payload[\"reasoning_effort\"] = \"none\"\n payload[\"extra_body\"] = {\"reasoning_effort\": \"none\"}\n payload.pop(\"response_format\", None)\n payload[\"messages\"][0] = {\"role\": \"system\", \"content\": \"You are a database content translation assistant. Translate the provided text accurately, preserving data semantics. Respond directly with ONLY the JSON result. Do NOT include any reasoning, thinking, chain-of-thought, analysis, or explanation. Output ONLY valid JSON.\"}\n\n logger.reason(\n f\"LLM request url={base_url} model={payload.get('model')} \"\n f\"provider_type={provider_type} \"\n f\"response_format={'yes' if 'response_format' in payload else 'no'} \"\n f\"prompt_len={len(prompt)}\"\n )\n\n # ── Try request; retry once without response_format if upstream rejects it ──\n response = http_requests.post(url, headers=headers, json=payload, timeout=180)\n if not response.ok and response.status_code == 400 and \"structured_outputs is not supported\" in (response.text or \"\"):\n logger.explore(\"Structured outputs not supported by upstream, retrying without response_format\", extra={\"src\": \"executor\"})\n payload.pop(\"response_format\", None)\n response = http_requests.post(url, headers=headers, json=payload, timeout=180)\n if not response.ok:\n logger.explore(\n f\"LLM API error status={response.status_code} \"\n f\"model={payload.get('model')} \"\n f\"body={response.text[:2000]}\"\n )\n response.raise_for_status()\n data = response.json()\n\n choices = data.get(\"choices\", [])\n if not choices:\n logger.explore(\"LLM returned no choices\", extra={\"src\": \"executor\", \"response_keys\": list(data.keys()), \"response_preview\": str(data)[:2000]})\n raise ValueError(\"LLM returned no choices\")\n\n finish_reason = choices[0].get(\"finish_reason\") or \"none\"\n msg = choices[0].get(\"message\") or {}\n # Handle model refusal (content is empty/null, refusal field has reason)\n refusal = msg.get(\"refusal\")\n if refusal:\n logger.explore(\"LLM refused to respond\", extra={\n \"src\": \"executor\",\n \"refusal\": str(refusal)[:500],\n \"finish_reason\": finish_reason,\n })\n raise ValueError(f\"LLM refused to respond: {refusal}\")\n content = msg.get(\"content\") or \"\"\n logger.reason(f\"LLM response finish_reason={finish_reason} content_len={len(content)} msg_keys={list(msg.keys())}\")\n if not content:\n logger.explore(\"LLM returned empty content\", extra={\"src\": \"executor\", \"finish_reason\": finish_reason, \"msg_keys\": list(msg.keys()), \"response_preview\": str(data)[:2000]})\n raise ValueError(\"LLM returned empty content\")\n\n return content\n # endregion _call_openai_compatible\n\n # region _parse_llm_response [TYPE Function]\n # @PURPOSE: Parse LLM JSON response into dict of row_id -> per-language translations.\n # Supports multi-language format: {\"row_id\": 0, \"detected_source_language\": \"fr\", \"ru\": \"текст\", \"en\": \"text\"}\n # Backward-compat: old format {\"row_id\": 0, \"translation\": \"text\", \"detected_source_language\": \"fr\"}\n # @PRE: response_text is valid JSON with {\"rows\": [...]} structure.\n # @POST: Returns dict mapping row_id to dict with 'detected_source_language' and per-language codes.\n @staticmethod\n def _parse_llm_response(response_text: str, expected_count: int, target_languages: list[str] | None = None, finish_reason: str | None = None) -> dict[str, dict[str, str]]:\n with belief_scope(\"TranslationExecutor._parse_llm_response\"):\n try:\n data = json.loads(response_text)\n except json.JSONDecodeError:\n # Try to extract from markdown code block\n import re\n match = re.search(r'```(?:json)?\\s*\\n?(.*?)\\n?```', response_text, re.DOTALL)\n if match:\n try:\n data = json.loads(match.group(1))\n rows = data.get(\"rows\", [])\n if isinstance(rows, list) and rows:\n logger.reason(\"Parsed JSON from markdown code block\", {\"rows\": len(rows)})\n except json.JSONDecodeError:\n pass # fall through to partial recovery\n else:\n pass # fall through to partial recovery\n \n # If finish_reason=length, try to recover complete rows from truncated JSON\n logger.explore(\"LLM truncated, trying partial row recovery\", extra={\"src\": \"executor\", \"finish_reason\": finish_reason, \"response_length\": len(response_text)})\n rows_match = re.findall(r'\\{\\s*\"row_id\"\\s*:\\s*\"\\d+\".*?\\}\\s*', response_text, re.DOTALL)\n if rows_match:\n partial_rows = []\n for row_text in rows_match:\n try:\n row_data = json.loads(row_text)\n partial_rows.append(row_data)\n except json.JSONDecodeError:\n continue\n if partial_rows:\n logger.explore(f\"Recovered {len(partial_rows)}/{expected_count} complete rows from truncated response\", extra={\"src\": \"executor\"})\n data = {\"rows\": partial_rows}\n else:\n logger.explore(\"Could not recover any complete rows\", extra={\"src\": \"executor\", \"response_preview\": response_text[:1000]})\n raise ValueError(\"LLM response was not valid JSON (could not recover any rows)\")\n else:\n logger.explore(\"No complete rows found in truncated response\", extra={\"src\": \"executor\", \"response_preview\": response_text[:1000]})\n raise ValueError(\"LLM response was not valid JSON\")\n\n rows = data.get(\"rows\", [])\n if not isinstance(rows, list):\n raise ValueError(\"LLM response missing 'rows' array\")\n\n translations: dict[str, dict[str, str]] = {}\n for item in rows:\n row_id = str(item.get(\"row_id\", \"\"))\n if not row_id:\n continue\n\n detected_lang = str(item.get(\"detected_source_language\", \"und\")) if item.get(\"detected_source_language\") else \"und\"\n result: dict[str, str] = {\n \"detected_source_language\": detected_lang,\n }\n\n # Multi-language format: extract per-language keys\n has_language_data = False\n if target_languages:\n for lang_code in target_languages:\n lang_val = item.get(lang_code)\n if lang_val is not None and str(lang_val).strip():\n result[lang_code] = str(lang_val)\n has_language_data = True\n\n # Fallback to legacy single \"translation\" key format\n if not has_language_data:\n translation = item.get(\"translation\")\n if translation is not None:\n result[\"translation\"] = str(translation)\n has_language_data = True\n\n if has_language_data:\n translations[row_id] = result\n\n if len(translations) < expected_count:\n logger.explore(\n f\"LLM returned fewer translations expected={expected_count} \"\n f\"got={len(translations)}\"\n )\n\n return translations\n # endregion _parse_llm_response\n\n\n# #endregion TranslationExecutor\n# #endregion TranslationExecutor\n" + "body": "# #region TranslationExecutor [C:5] [TYPE Module] [SEMANTICS sqlalchemy, tenacity, translate, insert, llm-retry]\n# @BRIEF Process translation in batches: fetch source rows, call LLM, persist TranslationBatch and TranslationRecord rows.\n# @LAYER: Domain\n# @RELATION DEPENDS_ON -> [TranslationBatch]\n# @RELATION DEPENDS_ON -> [TranslationRecord]\n# @RELATION DEPENDS_ON -> [TranslationRun]\n# @RELATION DEPENDS_ON -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [DictionaryManager]\n# @RELATION DEPENDS_ON -> [TranslationPreview]\n# @PRE: Valid TranslationRun with job configuration. DB session is available.\n# @POST: TranslationBatch and TranslationRecord rows are created. Run status is updated.\n# @SIDE_EFFECT: Calls LLM provider; creates DB rows; updates run statistics.\n# @DATA_CONTRACT Input: TranslationRun + Job -> Output: updated Run with batch/record rows\n# @INVARIANT Batch processing is independent — one batch failure does not affect others.\n# @RATIONALE: Batch processing with retry — independent batches allow partial recovery.\n# @REJECTED: Single monolithic LLM call — would lose all progress on any failure.\n\nimport hashlib\nimport json\nimport re\nimport time\nimport uuid\nfrom collections.abc import Callable\nfrom datetime import UTC, datetime\nfrom typing import Any\n\nfrom sqlalchemy.orm import Session, joinedload\n\nfrom ...core.config_manager import ConfigManager\nfrom ...core.logger import belief_scope, logger\nfrom ...models.translate import (\n TranslationBatch,\n TranslationJob,\n TranslationLanguage,\n TranslationPreviewRecord,\n TranslationPreviewSession,\n TranslationRecord,\n TranslationRun,\n TranslationRunLanguageStats,\n)\nfrom ...services.llm_prompt_templates import render_prompt\nfrom ...services.llm_provider import LLMProviderService\nfrom ._token_budget import estimate_token_budget\nfrom .dictionary import DictionaryManager\nfrom .preview import DEFAULT_EXECUTION_PROMPT_TEMPLATE\nfrom .prompt_builder import ContextAwarePromptBuilder\nfrom .sql_generator import SQLGenerator, _normalize_timestamp_value\nfrom .superset_executor import SupersetSqlLabExecutor\n\n# #region MAX_RETRIES_PER_BATCH [TYPE Constant]\nMAX_RETRIES_PER_BATCH = 3\n# #endregion MAX_RETRIES_PER_BATCH\n\n# #region MAX_ROWS_PER_RUN [TYPE Constant]\n# Safety cap: without it, a datasource with thousands of rows blocks the single\n# uvicorn worker for minutes/hours. Preview uses sample_size (5-10). Full run\n# should stay within reasonable bounds.\nMAX_ROWS_PER_RUN = 10000\n# #endregion MAX_ROWS_PER_RUN\n\n# #region _enforce_dictionary [TYPE Function]\n# @BRIEF Post-processing: enforce dictionary entries in LLM output.\n# If a source term from the dictionary appears in the original text,\n# but the target term is missing from the translation, replace occurrences\n# of the source term in the translated output with the target term.\n# @PRE: dict_matches is a list of dict entries with source_term/target_term.\n# @POST: per_lang_values may be mutated to include forced dictionary replacements.\n# @SIDE_EFFECT: Logs when enforcement is applied.\ndef _enforce_dictionary(\n source_text: str,\n per_lang_values: dict[str, str],\n dict_matches: list[dict[str, Any]],\n batch_id: str,\n row_id: str,\n) -> None:\n \"\"\"Post-processing: enforce dictionary terms in LLM translation output.\n\n For each dictionary entry whose source_term appears in the source_text,\n verify that the target_term is present in each language's translation.\n If missing, replace any occurrence of the source term (which the LLM\n may have left untranslated) with the dictionary target term.\n \"\"\"\n if not dict_matches or not source_text:\n return\n\n text_lower = source_text.lower()\n\n for dm in dict_matches:\n src_term = dm.get(\"source_term\", \"\")\n tgt_term = dm.get(\"target_term\", \"\")\n if not src_term or not tgt_term:\n continue\n\n # Only process if source term actually appears in the original text\n if src_term.lower() not in text_lower:\n continue\n\n # Try to replace in each language\n for lang_code in list(per_lang_values.keys()):\n val = per_lang_values[lang_code]\n if not val:\n continue\n\n # Check if target term is already present (case-insensitive)\n if tgt_term.lower() in val.lower():\n continue\n\n # Try to find the source term (or a close variant) in the output\n # This catches cases where the LLM left the source term untranslated\n # Use lambda to prevent regex back-reference injection from tgt_term\n src_pattern = re.compile(re.escape(src_term), re.IGNORECASE)\n if src_pattern.search(val):\n new_val = src_pattern.sub(lambda _: tgt_term, val)\n if new_val != val:\n logger.reason(\"Dictionary enforcement applied\", {\n \"batch_id\": batch_id,\n \"row_id\": row_id,\n \"language_code\": lang_code,\n \"source_term\": src_term,\n \"target_term\": tgt_term,\n \"before\": val[:200],\n \"after\": new_val[:200],\n })\n per_lang_values[lang_code] = new_val\n# #endregion _enforce_dictionary\n\n\n# #region _compute_source_hash [TYPE Function]\n# @BRIEF Compute deterministic cache key for a source row.\n# SHA256 of (source_text + context_fields + dict_snapshot_hash + config_hash).\n# Key columns (row_id, primary keys) are EXCLUDED — only the text content\n# and meaningful context affect the hash. This ensures identical text with\n# different row identifiers still produces a cache hit.\ndef _compute_source_hash(\n source_text: str,\n source_data: dict | None,\n dict_snapshot_hash: str | None,\n config_hash: str | None,\n context_keys: list[str] | None = None,\n) -> str:\n \"\"\"Deterministic cache key for a translation source row.\n\n Only includes source_text and context-relevant fields from source_data.\n Key/identifier columns are excluded so identical text in different rows hits cache.\n \"\"\"\n # Extract only context-relevant fields from source_data (not keys/identifiers)\n context_data: dict[str, str] = {}\n if source_data and context_keys:\n for key in context_keys:\n val = source_data.get(key)\n if val is not None:\n context_data[key] = str(val)\n\n payload = json.dumps({\n \"text\": source_text,\n \"ctx\": context_data, # only context columns, no key/row_id\n \"dict_hash\": dict_snapshot_hash or \"\",\n \"config_hash\": config_hash or \"\",\n }, sort_keys=True, ensure_ascii=False)\n return hashlib.sha256(payload.encode(\"utf-8\")).hexdigest()\n# #endregion _compute_source_hash\n\n\n# #region _check_translation_cache [TYPE Function]\n# @BRIEF Look up a previously successful translation by source_hash.\n# Returns per-language dict {lang_code: final_value} or None.\ndef _check_translation_cache(\n db: Session,\n source_hash: str,\n) -> dict[str, str] | None:\n \"\"\"Check if this source_hash was already translated successfully.\"\"\"\n from sqlalchemy.orm import joinedload\n from ...models.translate import TranslationRecord, TranslationLanguage\n\n cached = (\n db.query(TranslationRecord)\n .options(joinedload(TranslationRecord.languages))\n .filter(\n TranslationRecord.source_hash == source_hash,\n TranslationRecord.status == \"SUCCESS\",\n )\n .order_by(TranslationRecord.created_at.desc())\n .first()\n )\n if not cached:\n return None\n\n lang_values: dict[str, str] = {}\n for lang in cached.languages:\n if lang.status == \"translated\" and lang.final_value:\n lang_values[lang.language_code] = lang.final_value\n\n return lang_values if lang_values else None\n# #endregion _check_translation_cache\n\n\n# #region estimate_row_tokens [C:4] [TYPE Function] [SEMANTICS translate, token, estimation]\n# @BRIEF Estimate token count for a single source row including context fields.\n# @PRE source_text is a string.\n# @POST Returns estimated token count >= 1.\n# @RELATION DEPENDS_ON -> [_estimate_tokens_for_text]\n\ndef estimate_row_tokens(\n source_text: str,\n source_data: dict | None,\n job,\n) -> int:\n \"\"\"Estimate token count for a single source row including context fields.\n\n Uses CJK-aware heuristics via _token_budget._estimate_tokens_for_text.\n Context fields from job.context_columns are included in the estimate.\n \"\"\"\n from ._token_budget import _estimate_tokens_for_text\n\n text_tokens = _estimate_tokens_for_text(source_text or \"\")\n\n context_keys = job.context_columns or []\n ctx_text = \"\"\n if source_data and context_keys:\n ctx_text = \" \".join(str(source_data.get(k, \"\")) for k in context_keys)\n ctx_tokens = _estimate_tokens_for_text(ctx_text)\n\n return text_tokens + ctx_tokens\n# #endregion estimate_row_tokens\n\n\n# #region TranslationExecutor [C:4] [TYPE Class]\n# @BRIEF Process translation batches: fetch source rows, filter dict, call LLM, persist results.\n# @PRE: DB session and config manager available.\n# @POST: Batches and records created with status tracking.\n# @SIDE_EFFECT: LLM API calls; DB writes.\nclass TranslationExecutor:\n\n def __init__(\n self,\n db: Session,\n config_manager: ConfigManager,\n current_user: str | None = None,\n on_batch_progress: Callable[[str, int, int, int, int], None] | None = None,\n ):\n self.db = db\n self.config_manager = config_manager\n self.current_user = current_user\n self.on_batch_progress = on_batch_progress\n self._current_run_id: str | None = None\n self._preview_edits_cache: dict[str, dict[str, str]] | None = None # key_hash -> {lang_code: edited_value}\n\n # region _resolve_provider_model [TYPE Function]\n # @BRIEF Resolve the LLM provider model name for token budget estimation.\n # @POST: Returns model name string or None if resolution fails.\n # @SIDE_EFFECT: DB query to LLM provider table.\n def _resolve_provider_model(self, job) -> str | None:\n \"\"\"Resolve the provider model name for token budget estimation.\"\"\"\n if not job.provider_id:\n return None\n try:\n p_svc = LLMProviderService(self.db)\n p = p_svc.get_provider(job.provider_id)\n if p:\n return p.default_model or \"gpt-4o-mini\"\n except Exception:\n pass\n return None\n # endregion _resolve_provider_model\n\n # region _auto_size_batches [TYPE Function]\n # @PURPOSE: Split source rows into variable-sized batches based on actual content length.\n # Uses estimate_token_budget to determine safe per-batch budgets and\n # _count_rows_that_fit logic to greedily fill each batch.\n # @PRE: source_rows is non-empty. job has valid config.\n # @POST: Returns list of batches, each batch is a list of row dicts.\n # Each batch fits within the estimated token budget for its rows.\n # @SIDE_EFFECT: DB query to resolve provider model. Logs batch statistics.\n # @RATIONALE: Fixed batch_size of 50 wastes LLM context for short rows and\n # overflows for long rows. Variable sizing adapts to row content length,\n # maximizing throughput while preventing truncation.\n # @REJECTED: Fixed batch_size of 50 — causes truncation on long-content rows.\n # Single monolithic batch — would lose all progress on any failure.\n def _auto_size_batches(\n self,\n job,\n source_rows: list[dict],\n target_languages: list[str],\n provider_info: str | None = None,\n ) -> list[list[dict]]:\n \"\"\"Split source rows into auto-sized batches based on content length.\n\n Each batch is sized so that its total estimated tokens fit within the\n available context window (input budget), accounting for prompt overhead,\n dictionary entries, and output tokens.\n\n Returns:\n List of batches, each batch is a list of row dicts.\n \"\"\"\n with belief_scope(\"TranslationExecutor._auto_size_batches\"):\n if not source_rows:\n return []\n\n # Resolve provider info if not provided\n if provider_info is None:\n provider_info = self._resolve_provider_model(job)\n\n # 1. Estimate per-row token counts\n row_tokens: list[int] = []\n for row in source_rows:\n source_text = row.get(\"source_text\", \"\")\n source_data = row.get(\"source_data\")\n tokens = estimate_row_tokens(source_text, source_data, job)\n row_tokens.append(tokens)\n\n # 2. Get budget recommendation from estimate_token_budget\n # Pass all rows to get a global safe batch size estimate.\n budget = estimate_token_budget(\n source_rows=source_rows,\n target_languages=target_languages,\n source_column=job.translation_column or \"source_text\",\n context_columns=job.context_columns,\n batch_size=len(source_rows),\n provider_info=provider_info,\n )\n\n recommended = budget.get(\"batch_size_adjusted\", 0)\n\n # Fallback: if budget calculation fails or returns zero, use fixed size\n if recommended <= 0:\n fallback_size = job.batch_size or 50\n logger.explore(\"Token budget returned zero — falling back to fixed batch size\", {\n \"fallback_size\": fallback_size,\n \"total_rows\": len(source_rows),\n })\n return [\n source_rows[i:i + fallback_size]\n for i in range(0, len(source_rows), fallback_size)\n ]\n\n # 3. Compute per-batch row-content budget\n # estimated_input_tokens includes PROMPT_BASE_TOKENS + dict_tokens +\n # sum of row tokens for the first `recommended` rows.\n # We subtract the prompt overhead to get the per-batch row budget.\n from ._token_budget import PROMPT_BASE_TOKENS\n\n estimated_input = budget.get(\"estimated_input_tokens\", 50000)\n per_batch_budget = estimated_input - PROMPT_BASE_TOKENS\n\n # Safety: if budget computation collapsed, fall back\n if per_batch_budget <= 0:\n fallback_size = job.batch_size or 50\n logger.explore(\"Per-batch budget collapsed — falling back to fixed batch size\", {\n \"estimated_input\": estimated_input,\n \"prompt_base\": PROMPT_BASE_TOKENS,\n \"fallback_size\": fallback_size,\n })\n return [\n source_rows[i:i + fallback_size]\n for i in range(0, len(source_rows), fallback_size)\n ]\n\n # 4. Greedy batch splitting: accumulate rows until the next row would\n # exceed the per-batch token budget. Use output-aware hard cap too:\n # a single batch never exceeds 2x the recommended batch size as\n # a safety net against wildly oversized estimates.\n max_rows_hard_cap = max(recommended * 2, 20)\n batches: list[list[dict]] = []\n current_batch: list[dict] = []\n current_tokens = 0\n\n for i, row in enumerate(source_rows):\n rt = row_tokens[i]\n\n # ── Edge case: single row exceeds entire per-batch budget ──\n if rt > per_batch_budget:\n # Flush current batch first\n if current_batch:\n batches.append(current_batch)\n current_batch = []\n current_tokens = 0\n logger.reason(\"Single row exceeds per-batch token budget — placing in own batch\", {\n \"row_index\": i,\n \"row_tokens\": rt,\n \"per_batch_budget\": per_batch_budget,\n })\n batches.append([row])\n continue\n\n # ── Start a new batch if: ──\n # a) Batch is non-empty AND adding this row would exceed budget\n # b) Hard row-count cap reached\n should_split = bool(\n current_batch\n and (current_tokens + rt > per_batch_budget\n or len(current_batch) >= max_rows_hard_cap)\n )\n\n if should_split:\n batches.append(current_batch)\n current_batch = [row]\n current_tokens = rt\n else:\n current_batch.append(row)\n current_tokens += rt\n\n if current_batch:\n batches.append(current_batch)\n\n # 5. Log adaptive batch statistics\n if batches:\n avg_size = sum(len(b) for b in batches) / max(1, len(batches))\n max_size = max(len(b) for b in batches)\n logger.reason(\"Auto-sized batches\", {\n \"total_rows\": len(source_rows),\n \"num_batches\": len(batches),\n \"avg_batch_size\": round(avg_size, 1),\n \"max_batch_size\": max_size,\n \"recommended_batch_size\": recommended,\n \"per_batch_budget\": per_batch_budget,\n })\n\n return batches\n # endregion _auto_size_batches\n\n # region execute_run [TYPE Function]\n # @PURPOSE: Run full translation execution for a TranslationRun.\n # @PRE: run is in PENDING or RUNNING status with valid job config.\n # @POST: Run is populated with batches and records.\n # @SIDE_EFFECT: LLM API calls; DB batch writes.\n def execute_run(\n self,\n run: TranslationRun,\n llm_progress_callback: Callable[[str, int, int, int], None] | None = None,\n language_stats_map: dict[str, TranslationRunLanguageStats] | None = None,\n ) -> TranslationRun:\n with belief_scope(\"TranslationExecutor.execute_run\"):\n job = self.db.query(TranslationJob).filter(TranslationJob.id == run.job_id).first()\n if not job:\n raise ValueError(f\"Job '{run.job_id}' not found for run '{run.id}'\")\n\n logger.reason(\"Starting translation execution\", {\n \"run_id\": run.id,\n \"job_id\": job.id,\n \"configured_batch_size\": job.batch_size,\n })\n\n # Load preview edits for carry-forward\n self._load_preview_edits(job.id)\n\n # Mark run as RUNNING\n run.status = \"RUNNING\"\n run.started_at = datetime.now(UTC)\n self.db.flush()\n\n # Determine whether this is a full translation (all rows) or incremental (new/changed only)\n full_translation = False\n if run.config_snapshot and isinstance(run.config_snapshot, dict):\n full_translation = run.config_snapshot.get(\"full_translation\", False)\n\n # Fetch source rows from the datasource\n source_rows = self._fetch_source_rows(job.id, run.id)\n if not source_rows:\n logger.explore(\"No source rows to translate\", {\"run_id\": run.id})\n run.status = \"COMPLETED\"\n run.completed_at = datetime.now(UTC)\n self.db.flush()\n return run\n\n # Apply new-key-only filtering for scheduled runs OR manual incremental runs\n if run.trigger_type == \"new_key_only\" or (not full_translation and run.trigger_type == \"manual\"):\n source_rows = self._filter_new_keys(job, run.id, source_rows)\n if not source_rows:\n logger.reason(\"run_noop — no new rows to translate\", {\n \"job_id\": job.id, \"run_id\": run.id,\n })\n run.status = \"COMPLETED\"\n run.insert_status = \"skipped\"\n run.total_records = 0\n run.completed_at = datetime.now(UTC)\n self.db.commit()\n return\n\n total_rows = len(source_rows)\n run.total_records = total_rows\n\n # Resolve target languages for batch sizing\n target_languages = job.target_languages or [job.target_dialect or \"en\"]\n if not isinstance(target_languages, list):\n target_languages = [str(target_languages)]\n\n # Split into auto-sized batches based on content length\n provider_model = self._resolve_provider_model(job)\n batches = self._auto_size_batches(\n job=job,\n source_rows=source_rows,\n target_languages=target_languages,\n provider_info=provider_model,\n )\n\n logger.reason(f\"Processing {len(batches)} batches\", {\n \"run_id\": run.id,\n \"total_rows\": total_rows,\n \"num_batches\": len(batches),\n \"avg_batch_size\": round(sum(len(b) for b in batches) / max(1, len(batches)), 1),\n \"max_batch_size\": max(len(b) for b in batches) if batches else 0,\n })\n\n successful_records = 0\n failed_records = 0\n skipped_records = 0\n\n for batch_idx, batch_rows in enumerate(batches):\n batch_result = self._process_batch(\n job=job,\n run_id=run.id,\n batch_index=batch_idx,\n batch_rows=batch_rows,\n dict_snapshot_hash=run.dict_snapshot_hash,\n config_hash=run.config_hash,\n )\n successful_records += batch_result[\"successful\"]\n failed_records += batch_result[\"failed\"]\n skipped_records += batch_result[\"skipped\"]\n\n # Update run stats incrementally\n run.successful_records = successful_records\n run.failed_records = failed_records\n run.skipped_records = skipped_records\n\n # Commit after each batch to release row locks and make RUNNING\n # status + batch progress visible to other DB sessions (frontend polling).\n self.db.commit()\n\n # Incremental INSERT into target table after each batch,\n # so data appears incrementally in the target view/table\n # without waiting for the entire run to complete.\n batch_id = batch_result.get(\"batch_id\")\n if batch_id and batch_result[\"successful\"] > 0:\n try:\n self._insert_batch_to_target(job, batch_id, run.id)\n except Exception as e:\n logger.explore(\"Batch INSERT failed (non-fatal, continuing)\", {\n \"batch_id\": batch_id,\n \"error\": str(e),\n })\n\n # Re-fetch run after commit to check for cancellation flag set by\n # cancel_run() fallback (direct SQL UPDATE of error_message).\n self.db.refresh(run)\n if run.error_message == \"CANCEL_REQUESTED\":\n logger.reason(\"Cancellation requested — stopping batch processing\", {\n \"run_id\": run.id,\n \"batch_index\": batch_idx,\n })\n run.status = \"CANCELLED\"\n run.completed_at = datetime.now(UTC)\n run.error_message = None # Clear the orchestration flag\n self.db.commit()\n return run\n\n # Update per-language statistics incrementally after each batch\n # so the frontend shows real-time per-language counts for RUNNING runs.\n if language_stats_map and batch_result[\"successful\"] > 0:\n try:\n self._update_language_stats_incremental(run.id, language_stats_map)\n except Exception as e:\n logger.explore(\"Language stats update failed (non-fatal)\", {\n \"batch_id\": batch_id,\n \"error\": str(e),\n })\n\n if self.on_batch_progress:\n self.on_batch_progress(\n run.id, batch_idx + 1, len(batches),\n successful_records, total_rows,\n )\n\n # Update final run status\n if failed_records == 0 and skipped_records == 0:\n run.status = \"COMPLETED\"\n elif successful_records == 0:\n run.status = \"FAILED\"\n else:\n run.status = \"COMPLETED\" # Partial success\n\n run.completed_at = datetime.now(UTC)\n self.db.flush()\n\n logger.reflect(\"Translation execution complete\", {\n \"run_id\": run.id,\n \"status\": run.status,\n \"total\": total_rows,\n \"successful\": successful_records,\n \"failed\": failed_records,\n \"skipped\": skipped_records,\n })\n\n return run\n # endregion execute_run\n\n # region _fetch_source_rows [TYPE Function]\n # @PURPOSE: Fetch full source dataset from Superset (via datasource) for full translation.\n # @PRE: job_id exists. Job may have source_datasource_id for full fetch.\n # @POST: Returns list of dicts with source data (all rows from the source datasource).\n # @SIDE_EFFECT: Makes HTTP call to Superset chart data API when datasource is configured.\n def _fetch_source_rows(self, job_id: str, run_id: str) -> list[dict[str, Any]]:\n with belief_scope(\"TranslationExecutor._fetch_source_rows\"):\n job = self.db.query(TranslationJob).filter(TranslationJob.id == job_id).first()\n\n # If source_datasource_id is configured, fetch ALL rows from the Superset chart data API\n if job and job.source_datasource_id:\n try:\n logger.reason(\"Fetching full dataset from Superset datasource\", {\n \"run_id\": run_id,\n \"datasource_id\": job.source_datasource_id,\n \"environment_id\": job.environment_id,\n })\n\n # Determine environment\n environments = self.config_manager.get_environments()\n target_env_id = job.environment_id or job.source_dialect or \"\"\n env_config = next(\n (e for e in environments if e.id == target_env_id),\n None,\n )\n if not env_config and environments:\n env_config = environments[0]\n\n if env_config:\n from ...core.superset_client import SupersetClient\n client = SupersetClient(env_config)\n\n # Fetch dataset detail to build proper query context\n dataset_detail = client.get_dataset_detail(int(job.source_datasource_id))\n\n # Build query context (same approach as preview but without row_limit)\n query_context = client.build_dataset_preview_query_context(\n dataset_id=int(job.source_datasource_id),\n dataset_record=dataset_detail,\n template_params={},\n effective_filters=[],\n )\n\n # Use a safety cap instead of removing row_limit entirely.\n # Preview uses sample_size (5-10). Full runs should not fetch unlimited rows\n # because each batch of 20 rows × 4 languages takes ~40s of LLM time.\n queries = query_context.get(\"queries\", [])\n if queries:\n queries[0][\"row_limit\"] = MAX_ROWS_PER_RUN\n queries[0].pop(\"result_type\", None)\n queries[0][\"metrics\"] = []\n query_context[\"result_type\"] = \"samples\"\n form_data = query_context.get(\"form_data\", {})\n form_data.pop(\"query_mode\", None)\n\n response = client.network.request(\n method=\"POST\",\n endpoint=\"/api/v1/chart/data\",\n data=json.dumps(query_context),\n headers={\"Content-Type\": \"application/json\"},\n )\n\n # Extract rows\n rows = self._extract_chart_data_rows(response)\n\n if rows:\n logger.reason(f\"Fetched {len(rows)} rows from Superset datasource\", {\n \"run_id\": run_id,\n })\n # Map rows to source_rows format\n source_rows = []\n for idx, row in enumerate(rows):\n source_data_dict = dict(row) if row else None\n source_text = str(row.get(job.translation_column, \"\")) if job.translation_column else json.dumps(row)\n source_rows.append({\n \"row_index\": str(idx),\n \"source_text\": source_text,\n \"approved_translation\": None,\n \"source_object_name\": f\"Row {idx}\",\n \"source_data\": source_data_dict,\n })\n return source_rows\n else:\n logger.explore(\"Superset datasource returned no rows\", {\n \"run_id\": run_id,\n \"datasource_id\": job.source_datasource_id,\n })\n else:\n logger.explore(\"No environment config found for datasource fetch\", {\n \"env_id\": target_env_id,\n })\n except Exception as e:\n logger.explore(\"Failed to fetch full dataset from Superset, falling back to preview\", {\n \"run_id\": run_id,\n \"error\": str(e),\n })\n # Fall through to preview-based fetch\n\n # Fallback: get the latest APPLIED preview session\n session = (\n self.db.query(TranslationPreviewSession)\n .filter(\n TranslationPreviewSession.job_id == job_id,\n TranslationPreviewSession.status == \"APPLIED\",\n )\n .order_by(TranslationPreviewSession.created_at.desc())\n .first()\n )\n if not session:\n logger.explore(\"No accepted preview session found\", {\"job_id\": job_id})\n return []\n\n # Fetch APPROVED or all records from the session\n records = (\n self.db.query(TranslationPreviewRecord)\n .filter(\n TranslationPreviewRecord.session_id == session.id,\n TranslationPreviewRecord.status.in_([\"APPROVED\", \"PENDING\"]),\n )\n .all()\n )\n\n source_rows = []\n for rec in records:\n source_data_dict = None\n if hasattr(rec, \"source_data\") and rec.source_data:\n source_data_dict = dict(rec.source_data)\n source_rows.append({\n \"row_index\": rec.source_object_id or \"0\",\n \"source_text\": rec.source_sql or \"\",\n \"approved_translation\": rec.target_sql if rec.status == \"APPROVED\" else None,\n \"source_object_name\": rec.source_object_name or \"\",\n \"source_data\": source_data_dict,\n })\n\n logger.reason(f\"Fetched {len(source_rows)} source rows from preview fallback\", {\n \"run_id\": run_id,\n \"session_id\": session.id,\n })\n return source_rows\n # endregion _fetch_source_rows\n\n # region _filter_new_keys [TYPE Function]\n # @PURPOSE: Filter source rows to only include those with keys absent from the last successful run.\n # @PRE: job and run are persisted; source_rows is a list of dicts with source_data containing key columns.\n # @POST: Returns filtered list of source rows with only new keys. Logs skip count.\n # @SIDE_EFFECT: Queries TranslationRecord from previous runs; no writes.\n def _filter_new_keys(self, job, run_id: str, source_rows: list) -> list:\n with belief_scope(\"TranslationExecutor._filter_new_keys\"):\n # Find most recent COMPLETED run with successful insert for this job\n prev_run = (\n self.db.query(TranslationRun)\n .filter(\n TranslationRun.job_id == job.id,\n TranslationRun.status == \"COMPLETED\",\n TranslationRun.insert_status == \"succeeded\",\n TranslationRun.id != run_id,\n )\n .order_by(TranslationRun.created_at.desc())\n .first()\n )\n if not prev_run:\n logger.reason(\"No prior successful run — all keys treated as new\", {\n \"job_id\": job.id,\n })\n return source_rows\n\n # Get successful records from that run\n prev_records = (\n self.db.query(TranslationRecord)\n .filter(\n TranslationRecord.run_id == prev_run.id,\n TranslationRecord.status == \"SUCCESS\",\n )\n .all()\n )\n if not prev_records:\n return source_rows\n\n # Build set of already-translated composite keys\n key_cols = job.target_key_cols or job.source_key_cols or []\n if not key_cols:\n logger.explore(\"No key columns configured — skipping new-key-only filter\",\n {\"job_id\": job.id})\n return source_rows\n existing_keys = set()\n for rec in prev_records:\n sd = rec.source_data or {}\n key_tuple = tuple(str(sd.get(k, \"\")) for k in key_cols)\n existing_keys.add(key_tuple)\n\n # Filter: keep only rows whose keys are NOT in the existing set\n filtered = []\n skipped = 0\n for row in source_rows:\n sd = row.get(\"source_data\", {}) or {}\n key_tuple = tuple(str(sd.get(k, \"\")) for k in key_cols)\n if key_tuple not in existing_keys:\n filtered.append(row)\n else:\n skipped += 1\n\n logger.reason(f\"New-key-only filter: {len(source_rows)} total → {len(filtered)} new, {skipped} skipped\", {\n \"job_id\": job.id,\n \"prev_run_id\": prev_run.id,\n \"key_cols\": key_cols,\n })\n return filtered\n # endregion _filter_new_keys\n\n # region _extract_chart_data_rows [TYPE Function]\n # @PURPOSE: Extract data rows from Superset chart data API response.\n # @POST: Returns list of dicts with column-value pairs.\n @staticmethod\n def _extract_chart_data_rows(response: dict[str, Any]) -> list[dict[str, Any]]:\n result = response.get(\"result\")\n if isinstance(result, list):\n for item in result:\n if isinstance(item, dict):\n data = item.get(\"data\")\n if isinstance(data, list) and data:\n return data\n if isinstance(result, dict):\n data = result.get(\"data\")\n if isinstance(data, list) and data:\n return data\n data = response.get(\"data\")\n if isinstance(data, list) and data:\n return data\n if isinstance(result, list):\n return result\n return []\n # endregion _extract_chart_data_rows\n\n # region _load_preview_edits [TYPE Function]\n # @PURPOSE: Load user edits from accepted preview session for carry-forward.\n # @PRE: job_id exists.\n # @POST: Populates _preview_edits_cache with key_hash -> {lang_code: edited_value}.\n # @SIDE_EFFECT: Queries TranslationPreviewLanguage and TranslationPreviewRecord.\n def _load_preview_edits(self, job_id: str) -> None:\n \"\"\"Load preview edits for carry-forward during execution.\"\"\"\n from ...models.translate import TranslationPreviewLanguage, TranslationPreviewRecord, TranslationPreviewSession\n\n with belief_scope(\"TranslationExecutor._load_preview_edits\"):\n session = (\n self.db.query(TranslationPreviewSession)\n .filter(\n TranslationPreviewSession.job_id == job_id,\n TranslationPreviewSession.status == \"APPLIED\",\n )\n .order_by(TranslationPreviewSession.created_at.desc())\n .first()\n )\n if not session:\n logger.reason(\"No applied preview session found — no edits to carry forward\", {\n \"job_id\": job_id,\n })\n self._preview_edits_cache = {}\n return\n\n records = (\n self.db.query(TranslationPreviewRecord)\n .filter(TranslationPreviewRecord.session_id == session.id)\n .all()\n )\n\n edits: dict[str, dict[str, str]] = {}\n for rec in records:\n if not rec.source_data:\n continue\n # Compute key hash from source_data\n key_hash = self._compute_key_hash(rec.source_data)\n edited_langs: dict[str, str] = {}\n for lang_entry in (rec.languages or []):\n if lang_entry.status in (\"edited\", \"approved\") and lang_entry.user_edit:\n edited_langs[lang_entry.language_code] = lang_entry.final_value or lang_entry.user_edit\n logger.reason(\"Carrying forward preview edit\", {\n \"key_hash\": key_hash,\n \"language_code\": lang_entry.language_code,\n })\n if edited_langs:\n edits[key_hash] = edited_langs\n\n self._preview_edits_cache = edits\n logger.reason(f\"Loaded {len(edits)} preview edits for carry-forward\", {\n \"job_id\": job_id,\n })\n # endregion _load_preview_edits\n\n # region _compute_key_hash [TYPE Function]\n # @PURPOSE: Compute a stable hash from source_data dict for matching preview edits.\n @staticmethod\n def _compute_key_hash(source_data: dict) -> str:\n import hashlib\n stable = json.dumps(source_data, sort_keys=True)\n return hashlib.sha256(stable.encode()).hexdigest()[:16]\n # endregion _compute_key_hash\n\n # region _process_batch [TYPE Function]\n # @PURPOSE: Process a single batch: filter dict, build prompt, call LLM, persist records.\n # @PRE: job and batch_rows are valid.\n # @POST: TranslationBatch and TranslationRecord rows are created.\n # @SIDE_EFFECT: LLM API call.\n def _process_batch(\n self,\n job: TranslationJob,\n run_id: str,\n batch_index: int,\n batch_rows: list[dict[str, Any]],\n dict_snapshot_hash: str | None = None,\n config_hash: str | None = None,\n ) -> dict[str, int]:\n with belief_scope(\"TranslationExecutor._process_batch\"):\n batch_start = time.monotonic()\n\n # Create batch record\n batch = TranslationBatch(\n id=str(uuid.uuid4()),\n run_id=run_id,\n batch_index=batch_index,\n status=\"RUNNING\",\n total_records=len(batch_rows),\n started_at=datetime.now(UTC),\n )\n self.db.add(batch)\n self.db.flush()\n batch_id = batch.id\n\n result = {\"successful\": 0, \"failed\": 0, \"skipped\": 0, \"retries\": 0}\n\n # Extract source texts for dict filtering\n source_texts = [\n row.get(\"source_text\", \"\")\n for row in batch_rows\n if row.get(\"source_text\")\n ]\n\n # Filter dictionary entries with row context for priority matching\n row_context = batch_rows[0].get(\"source_data\") if batch_rows else None\n dict_matches = DictionaryManager.filter_for_batch(\n self.db, source_texts, job.id,\n row_context=row_context,\n )\n\n # ── Translation cache check: skip LLM for rows translated before ──\n for row in batch_rows:\n if row.get(\"approved_translation\"):\n continue\n source_text = row.get(\"source_text\", \"\")\n if not source_text:\n continue\n source_data = row.get(\"source_data\")\n # Build context_keys from job config (exclude key columns from hash)\n ctx_keys = list(job.context_columns or [])\n source_hash = _compute_source_hash(\n source_text, source_data,\n dict_snapshot_hash, config_hash,\n context_keys=ctx_keys,\n )\n row[\"_source_hash\"] = source_hash\n cached = _check_translation_cache(self.db, source_hash)\n if cached:\n row[\"_cached_lang_values\"] = cached\n logger.reason(\"Translation cache hit\", {\n \"source_hash\": source_hash[:12],\n \"langs\": list(cached.keys()),\n })\n\n # For each row, determine if we need LLM translation or can use approved/preview edit/cache\n rows_for_llm = []\n pre_translated = []\n\n for row in batch_rows:\n if row.get(\"approved_translation\"):\n pre_translated.append(row)\n continue\n\n # Translation cache hit → treat as pre-translated\n # BUT only if cached langs cover ALL target languages\n cached_langs = row.get(\"_cached_lang_values\")\n if cached_langs:\n target_langs_for_check = job.target_languages or [job.target_dialect or \"en\"]\n if not isinstance(target_langs_for_check, list):\n target_langs_for_check = [str(target_langs_for_check)]\n cached_covers_all = all(\n lang_code in cached_langs\n for lang_code in target_langs_for_check\n )\n if cached_covers_all:\n pre_translated.append(row)\n continue\n else:\n logger.reason(\"Partial cache hit — missing languages, routing to LLM\", {\n \"cached_langs\": list(cached_langs.keys()),\n \"target_langs\": target_langs_for_check,\n })\n\n # Check for preview edits carry-forward\n source_data = row.get(\"source_data\") or {}\n if source_data and self._preview_edits_cache:\n key_hash = self._compute_key_hash(source_data)\n preview_edit = self._preview_edits_cache.get(key_hash)\n if preview_edit:\n # Use the first edited language's value as the approved translation\n first_edit = next(iter(preview_edit.values()), None)\n if first_edit:\n row[\"approved_translation\"] = first_edit\n logger.reason(\"Using preview edit carry-forward\", {\n \"key_hash\": key_hash,\n \"langs\": list(preview_edit.keys()),\n })\n pre_translated.append(row)\n continue\n\n rows_for_llm.append(row)\n\n # Handle pre-translated (approved) rows\n target_languages = job.target_languages or [job.target_dialect or \"en\"]\n if not isinstance(target_languages, list):\n target_languages = [str(target_languages)]\n\n for row in pre_translated:\n cached_langs = row.get(\"_cached_lang_values\") # None for approved, dict for cache hits\n record = TranslationRecord(\n id=str(uuid.uuid4()),\n batch_id=batch_id,\n run_id=run_id,\n source_sql=row.get(\"source_text\", \"\"),\n target_sql=row.get(\"approved_translation\", \"\"),\n source_object_type=\"table_row\",\n source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"),\n source_hash=row.get(\"_source_hash\"),\n status=\"SUCCESS\",\n )\n self.db.add(record)\n\n # Create per-language entry for each target language\n for lang_code in target_languages:\n if cached_langs and lang_code in cached_langs:\n final_val = cached_langs[lang_code]\n else:\n final_val = row.get(\"approved_translation\", \"\")\n lang_entry = TranslationLanguage(\n id=str(uuid.uuid4()),\n record_id=record.id,\n language_code=lang_code,\n source_language_detected=\"und\",\n translated_value=final_val,\n final_value=final_val,\n status=\"translated\",\n needs_review=False,\n )\n self.db.add(lang_entry)\n result[\"successful\"] += 1\n\n # Process rows needing LLM translation\n if rows_for_llm:\n # Resolve provider model for provider-aware token budget\n provider_model = None\n if job.provider_id:\n try:\n p_svc = LLMProviderService(self.db)\n p = p_svc.get_provider(job.provider_id)\n if p:\n provider_model = p.default_model or \"gpt-4o-mini\"\n except Exception:\n provider_model = None\n\n # Check token budget for this batch to determine safe max_tokens\n token_budget = estimate_token_budget(\n source_rows=rows_for_llm,\n target_languages=target_languages,\n source_column=\"source_text\",\n context_columns=None, # Context is embedded in dict, not separate column\n dictionary_entries=dict_matches,\n batch_size=len(rows_for_llm),\n provider_info=provider_model,\n )\n if token_budget[\"warning\"]:\n logger.explore(\"Token budget warning for batch\", {\n \"batch_id\": batch_id,\n \"batch_index\": batch_index,\n \"warning\": token_budget[\"warning\"],\n })\n\n llm_result = self._call_llm_for_batch(\n job=job,\n run_id=run_id,\n batch_rows=rows_for_llm,\n dict_matches=dict_matches,\n batch_id=batch_id,\n max_tokens=token_budget[\"max_output_needed\"],\n )\n result[\"successful\"] += llm_result[\"successful\"]\n result[\"failed\"] += llm_result[\"failed\"]\n result[\"skipped\"] += llm_result[\"skipped\"]\n result[\"retries\"] += llm_result.get(\"retries\", 0)\n\n # Update batch status\n batch.successful_records = result[\"successful\"]\n batch.failed_records = result[\"failed\"]\n batch.completed_at = datetime.now(UTC)\n batch.status = \"COMPLETED\" if result[\"failed\"] == 0 else \"COMPLETED_WITH_ERRORS\"\n self.db.flush()\n\n batch_latency = int((time.monotonic() - batch_start) * 1000)\n logger.reason(f\"Batch {batch_index} complete\", {\n \"batch_id\": batch_id,\n \"latency_ms\": batch_latency,\n **result,\n })\n\n return {**result, \"batch_id\": batch_id}\n # endregion _process_batch\n\n # region _insert_batch_to_target [TYPE Function]\n # @PURPOSE: Insert successful records from a single batch into the target table via Superset SQL Lab.\n # @PRE: batch has committed TranslationRecords with status SUCCESS. job has target_table configured.\n # @POST: Per record, N+1 rows are INSERTED: 1 original + N translations.\n # Context columns are bundled into JSON in the `context` column.\n # `is_original=1` marks the source-language row.\n # @SIDE_EFFECT: HTTP call to Superset SQL Lab API. Writes to target database.\n def _insert_batch_to_target(\n self,\n job: TranslationJob,\n batch_id: str,\n run_id: str,\n ) -> None:\n with belief_scope(\"TranslationExecutor._insert_batch_to_target\"):\n records = (\n self.db.query(TranslationRecord)\n .options(joinedload(TranslationRecord.languages))\n .filter(\n TranslationRecord.batch_id == batch_id,\n TranslationRecord.status == \"SUCCESS\",\n TranslationRecord.target_sql.isnot(None),\n )\n .all()\n )\n\n if not records:\n return\n\n effective_target = job.target_column or job.translation_column\n primary_language = (job.target_languages or [\"en\"])[0]\n\n # Columns that exist in the target ClickHouse table\n columns = []\n if job.target_key_cols:\n columns.extend(job.target_key_cols)\n if effective_target:\n columns.append(effective_target)\n if job.target_language_column:\n columns.append(job.target_language_column)\n if job.target_source_column:\n columns.append(job.target_source_column)\n if job.target_source_language_column:\n columns.append(job.target_source_language_column)\n columns.append(\"context\")\n columns.append(\"is_original\")\n # Deduplicate while preserving order\n seen: set[str] = set()\n deduped: list[str] = []\n for c in columns:\n if c and c not in seen:\n deduped.append(c)\n seen.add(c)\n columns = deduped\n\n # Keys for the context JSON: context_columns + original translation_column\n context_keys = list(job.context_columns or [])\n if job.translation_column and job.translation_column != effective_target and job.translation_column not in context_keys:\n context_keys.append(job.translation_column)\n\n rows_for_sql: list[dict[str, object]] = []\n for rec in records:\n source_data = rec.source_data or {}\n\n # Detect source language from first TranslationLanguage entry\n detected_src_lang = \"und\"\n if rec.languages and len(rec.languages) > 0:\n detected_src_lang = rec.languages[0].source_language_detected or \"und\"\n\n # Build context JSON: all extra columns the user configured\n context_data: dict[str, str] = {}\n for key in context_keys:\n val = source_data.get(key)\n context_data[key] = str(val) if val is not None else \"\"\n\n # ── Shared base row (columns common to original and all translations) ──\n base_row: dict[str, object] = {}\n\n # Key columns (report_date, document_number) — normalize timestamps to YYYY-MM-DD\n if job.target_key_cols:\n for k in job.target_key_cols:\n raw = source_data.get(k)\n if raw is not None:\n normalized = _normalize_timestamp_value(raw)\n base_row[k] = normalized if normalized else raw\n else:\n base_row[k] = None\n\n # Source text: original\n if job.target_source_column:\n base_row[job.target_source_column] = rec.source_sql or \"\"\n\n # Source language (same for all rows of this record)\n if job.target_source_language_column:\n base_row[job.target_source_language_column] = detected_src_lang\n\n # Context JSON string\n base_row[\"context\"] = json.dumps(context_data, ensure_ascii=False)\n\n # ── 1. ORIGINAL row (is_original = 1) ──\n original_row = dict(base_row)\n if effective_target:\n original_row[effective_target] = rec.source_sql or \"\"\n if job.target_language_column:\n original_row[job.target_language_column] = detected_src_lang\n original_row[\"is_original\"] = 1\n rows_for_sql.append(original_row)\n\n # ── 2. TRANSLATION rows (is_original = 0) ──\n # Skip language that matches the source — the original row already covers it\n if rec.languages and len(rec.languages) > 0:\n for lang in rec.languages:\n if lang.language_code == detected_src_lang:\n continue\n trans_row = dict(base_row)\n trans_value = lang.final_value or lang.translated_value or \"\"\n if effective_target:\n trans_row[effective_target] = trans_value\n if job.target_language_column:\n trans_row[job.target_language_column] = lang.language_code\n trans_row[\"is_original\"] = 0\n rows_for_sql.append(trans_row)\n else:\n # Fallback: no per-language data → single translation row with primary language\n fallback_row = dict(base_row)\n if effective_target:\n fallback_row[effective_target] = rec.target_sql or \"\"\n if job.target_language_column:\n fallback_row[job.target_language_column] = primary_language\n fallback_row[\"is_original\"] = 0\n rows_for_sql.append(fallback_row)\n\n if not columns:\n columns = [effective_target or \"translated_text\"]\n rows_for_sql = [{columns[0]: rec.target_sql or \"\"} for rec in records]\n\n try:\n env_id = job.environment_id or job.source_dialect or \"\"\n executor = SupersetSqlLabExecutor(self.config_manager, env_id)\n executor.resolve_database_id(target_database_id=job.target_database_id)\n real_backend = executor.get_database_backend()\n except Exception as e:\n logger.explore(\"Failed to resolve database backend for batch insert\", {\n \"batch_id\": batch_id,\n \"error\": str(e),\n })\n real_backend = None\n\n dialect = real_backend or job.database_dialect or job.target_dialect or \"postgresql\"\n\n try:\n sql, row_count = SQLGenerator.generate(\n dialect=dialect,\n target_schema=job.target_schema,\n target_table=job.target_table or \"translated_data\",\n columns=columns,\n rows=rows_for_sql,\n key_columns=job.target_key_cols,\n upsert_strategy=job.upsert_strategy or \"MERGE\",\n )\n except ValueError as e:\n logger.explore(\"SQL generation failed for batch\", {\n \"batch_id\": batch_id,\n \"error\": str(e),\n })\n return\n\n try:\n result = executor.execute_and_poll(\n sql=sql,\n max_polls=30,\n poll_interval_seconds=2.0,\n )\n except Exception as e:\n logger.explore(\"Superset SQL submission failed for batch\", {\n \"batch_id\": batch_id,\n \"error\": str(e),\n })\n return\n\n logger.reason(f\"Batch {batch_id[:12]} inserted {row_count} rows\", {\n \"batch_id\": batch_id,\n \"rows\": row_count,\n \"status\": result.get(\"status\"),\n })\n # endregion _insert_batch_to_target\n\n # region _update_language_stats_incremental [TYPE Function]\n # @PURPOSE: Update per-language TranslationRunLanguageStats incrementally after each batch.\n # @PRE: language_stats_map has entries for all target languages.\n # @POST: Language stat objects updated with counts from committed TranslationLanguage rows.\n # @SIDE_EFFECT: Mutates ORM objects; caller must commit.\n def _update_language_stats_incremental(\n self,\n run_id: str,\n language_stats_map: dict[str, TranslationRunLanguageStats],\n ) -> None:\n with belief_scope(\"TranslationExecutor._update_language_stats_incremental\"):\n records = (\n self.db.query(TranslationRecord)\n .filter(TranslationRecord.run_id == run_id)\n .all()\n )\n record_ids = [r.id for r in records]\n if not record_ids:\n return\n\n lang_entries = (\n self.db.query(TranslationLanguage)\n .filter(TranslationLanguage.record_id.in_(record_ids))\n .all()\n )\n\n from collections import defaultdict\n agg: dict[str, dict[str, int]] = defaultdict(\n lambda: {\"total\": 0, \"translated\": 0, \"failed\": 0, \"skipped\": 0}\n )\n for le in lang_entries:\n code = le.language_code\n agg[code][\"total\"] += 1\n if le.status in (\"translated\", \"approved\", \"edited\"):\n agg[code][\"translated\"] += 1\n elif le.status == \"failed\":\n agg[code][\"failed\"] += 1\n elif le.status == \"skipped\":\n agg[code][\"skipped\"] += 1\n\n total_tokens_est = max(1, sum(len(le.translated_value or \"\") for le in lang_entries if le.translated_value) // 4)\n num_langs = len(language_stats_map) or 1\n cost_per_token = 0.002 / 1000\n\n for lang_code, lang_stat in language_stats_map.items():\n data = agg.get(lang_code, {\"total\": 0, \"translated\": 0, \"failed\": 0, \"skipped\": 0})\n lang_stat.total_rows = data[\"total\"]\n lang_stat.translated_rows = data[\"translated\"]\n lang_stat.failed_rows = data[\"failed\"]\n lang_stat.skipped_rows = data[\"skipped\"]\n lang_stat.token_count = total_tokens_est // num_langs\n lang_stat.estimated_cost = round((lang_stat.token_count / 1000) * cost_per_token, 6)\n\n self.db.flush()\n # endregion _update_language_stats_incremental\n\n # region _call_llm_for_batch [TYPE Function]\n # @PURPOSE: Call LLM for a batch of rows requiring translation. Parse structured JSON response.\n # @PRE: job has valid provider_id. batch_rows is non-empty.\n # @POST: Returns dict with successful/failed/skipped counts. Creates TranslationRecord rows.\n # @SIDE_EFFECT: HTTP call to LLM provider.\n def _call_llm_for_batch(\n self,\n job: TranslationJob,\n run_id: str,\n batch_rows: list[dict[str, Any]],\n dict_matches: list[dict[str, Any]],\n batch_id: str,\n max_tokens: int = 8192,\n _recursion_depth: int = 0,\n ) -> dict[str, int]:\n with belief_scope(\"TranslationExecutor._call_llm_for_batch\"):\n # Build dictionary section using ContextAwarePromptBuilder\n dictionary_section = \"\"\n if dict_matches:\n # Get row_context from first batch row if available\n row_context = batch_rows[0].get(\"source_data\") if batch_rows else None\n\n # Use ContextAwarePromptBuilder for context-aware annotations\n annotated_entries = ContextAwarePromptBuilder.build_context_entries(\n dict_matches, row_context\n )\n glossary_lines = []\n for annotated_line in annotated_entries:\n glossary_lines.append(f\"- {annotated_line}\")\n dictionary_section = (\n \"Terminology dictionary (use these translations when applicable):\\n\"\n + \"\\n\".join(glossary_lines)\n + \"\\n\\n\"\n )\n\n # Resolve target languages\n target_languages = job.target_languages or [job.target_dialect or \"en\"]\n if not isinstance(target_languages, list):\n target_languages = [str(target_languages)]\n target_languages_str = \", \".join(target_languages)\n\n # Build rows JSON for LLM\n rows_json = json.dumps([\n {\n \"row_id\": str(row.get(\"row_index\", idx)),\n \"text\": row.get(\"source_text\", \"\"),\n }\n for idx, row in enumerate(batch_rows)\n ], indent=2)\n\n # Build prompt (use multi-language format)\n prompt = render_prompt(\n DEFAULT_EXECUTION_PROMPT_TEMPLATE,\n {\n \"source_language\": job.source_dialect or \"SQL\",\n \"target_language\": target_languages_str,\n \"target_languages\": target_languages_str,\n \"source_dialect\": job.source_dialect or \"\",\n \"target_dialect\": job.target_dialect or \"\",\n \"translation_column\": job.translation_column or \"\",\n \"dictionary_section\": dictionary_section,\n \"rows_json\": rows_json,\n \"row_count\": str(len(batch_rows)),\n },\n )\n\n # Call LLM with retry\n llm_response = None\n last_error = None\n retries = 0\n\n finish_reason: str | None = None\n for attempt in range(1, MAX_RETRIES_PER_BATCH + 1):\n try:\n llm_response, finish_reason = self._call_llm(job, prompt, max_tokens=max_tokens)\n break\n except Exception as e:\n last_error = str(e)\n retries += 1\n logger.explore(f\"LLM call failed (attempt {attempt})\", {\n \"batch_id\": batch_id,\n \"error\": last_error,\n \"attempt\": attempt,\n })\n if attempt < MAX_RETRIES_PER_BATCH:\n time.sleep(2 ** attempt) # Exponential backoff\n else:\n logger.explore(\"LLM call exhausted retries\", {\n \"batch_id\": batch_id,\n \"last_error\": last_error,\n })\n\n if llm_response is None:\n # All retries failed — mark all rows as failed\n for row in batch_rows:\n record = TranslationRecord(\n id=str(uuid.uuid4()),\n batch_id=batch_id,\n run_id=run_id,\n source_sql=row.get(\"source_text\", \"\"),\n target_sql=None,\n source_object_type=\"table_row\",\n source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"),\n status=\"FAILED\",\n error_message=f\"LLM call failed after {retries} retries: {last_error}\",\n )\n self.db.add(record)\n return {\"successful\": 0, \"failed\": len(batch_rows), \"skipped\": 0, \"retries\": retries}\n\n # ── Truncation detection: finish_reason=\"length\" → split batch ──\n if finish_reason == \"length\" and len(batch_rows) >= 2 and run_id:\n if _recursion_depth < MAX_RETRIES_PER_BATCH:\n mid = len(batch_rows) // 2\n logger.explore(\"LLM output truncated — splitting batch\", {\n \"batch_id\": batch_id,\n \"batch_size\": len(batch_rows),\n \"split_at\": mid,\n \"recursion_depth\": _recursion_depth,\n \"finish_reason\": finish_reason,\n })\n left_result = self._call_llm_for_batch(\n job=job,\n run_id=run_id,\n batch_rows=batch_rows[:mid],\n dict_matches=dict_matches,\n batch_id=batch_id + \"_L\",\n max_tokens=max_tokens,\n _recursion_depth=_recursion_depth + 1,\n )\n right_result = self._call_llm_for_batch(\n job=job,\n run_id=run_id,\n batch_rows=batch_rows[mid:],\n dict_matches=dict_matches,\n batch_id=batch_id + \"_R\",\n max_tokens=max_tokens,\n _recursion_depth=_recursion_depth + 1,\n )\n merged = {\n \"successful\": left_result[\"successful\"] + right_result[\"successful\"],\n \"failed\": left_result[\"failed\"] + right_result[\"failed\"],\n \"skipped\": left_result[\"skipped\"] + right_result[\"skipped\"],\n \"retries\": retries + left_result.get(\"retries\", 0) + right_result.get(\"retries\", 0),\n }\n logger.reason(\"Truncation resolved by batch splitting\", {\n \"batch_id\": batch_id,\n \"left_successful\": left_result[\"successful\"],\n \"right_successful\": right_result[\"successful\"],\n \"left_size\": len(batch_rows[:mid]),\n \"right_size\": len(batch_rows[mid:]),\n })\n return merged\n else:\n logger.explore(\"Truncation recursion depth exceeded — accepting truncated output\", {\n \"batch_id\": batch_id,\n \"recursion_depth\": _recursion_depth,\n \"max_depth\": MAX_RETRIES_PER_BATCH,\n })\n # Fall through to parse truncated response\n\n # Parse LLM response (multi-language aware)\n try:\n translations = self._parse_llm_response(llm_response, len(batch_rows), target_languages=target_languages)\n except ValueError as e:\n # Parse failure — mark all rows as SKIPPED\n logger.explore(\"LLM response parse failed\", {\n \"batch_id\": batch_id,\n \"error\": str(e),\n \"response_preview\": llm_response[:500] if llm_response else \"\",\n })\n skipped = len(batch_rows)\n for row in batch_rows:\n record = TranslationRecord(\n id=str(uuid.uuid4()),\n batch_id=batch_id,\n run_id=run_id,\n source_sql=row.get(\"source_text\", \"\"),\n target_sql=None,\n source_object_type=\"table_row\",\n source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"),\n status=\"SKIPPED\",\n error_message=f\"LLM parse failure: {e}\",\n )\n self.db.add(record)\n return {\n \"successful\": 0,\n \"failed\": 0,\n \"skipped\": skipped,\n \"retries\": retries,\n }\n\n successful = 0\n failed = 0\n skipped = 0\n\n for row in batch_rows:\n row_id = str(row.get(\"row_index\", \"\"))\n translation_data = translations.get(row_id)\n source_text = row.get(\"source_text\", \"\")\n detected_lang = \"und\"\n if translation_data:\n detected_lang = translation_data.get(\"detected_source_language\", \"und\")\n\n if translation_data is None:\n # NULL translation — skip\n skipped += 1\n record = TranslationRecord(\n id=str(uuid.uuid4()),\n batch_id=batch_id,\n run_id=run_id,\n source_sql=source_text,\n target_sql=\"\",\n source_object_type=\"table_row\",\n source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"),\n status=\"SKIPPED\",\n error_message=\"NULL translation returned by LLM\",\n )\n self.db.add(record)\n continue\n\n # Collect per-language translated values\n per_lang_values: dict[str, str] = {}\n has_any_translation = False\n\n # First try multi-language format (per-language keys)\n for lang_code in target_languages:\n lang_val = translation_data.get(lang_code)\n if lang_val is not None and str(lang_val).strip():\n per_lang_values[lang_code] = str(lang_val)\n has_any_translation = True\n\n # Fallback to legacy single \"translation\" key format\n if not has_any_translation:\n translation_text = translation_data.get(\"translation\", \"\")\n if translation_text.strip():\n per_lang_values[target_languages[0]] = translation_text\n has_any_translation = True\n\n # ── Dictionary post-processing enforcement ──\n # If a dictionary entry matches the source text but the target term\n # is missing from the LLM output, apply forced replacement.\n if dict_matches and source_text:\n _enforce_dictionary(source_text, per_lang_values, dict_matches,\n batch_id, row_id)\n # ── End dictionary enforcement ──\n\n if not has_any_translation:\n # Empty/all-empty translations — skip\n skipped += 1\n record = TranslationRecord(\n id=str(uuid.uuid4()),\n batch_id=batch_id,\n run_id=run_id,\n source_sql=source_text,\n target_sql=\"\",\n source_object_type=\"table_row\",\n source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"),\n status=\"SKIPPED\",\n error_message=\"Empty translation returned by LLM\",\n )\n self.db.add(record)\n continue\n\n # Use the first language's value as the primary target_sql for backward compat\n primary_translation = next(iter(per_lang_values.values()), \"\")\n\n successful += 1\n record = TranslationRecord(\n id=str(uuid.uuid4()),\n batch_id=batch_id,\n run_id=run_id,\n source_sql=source_text,\n target_sql=primary_translation,\n source_object_type=\"table_row\",\n source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"),\n source_hash=row.get(\"_source_hash\"),\n status=\"SUCCESS\",\n )\n self.db.add(record)\n\n # Create per-language entries — one TranslationLanguage per language_code\n for lang_code in target_languages:\n # Skip if this language matches the detected source language —\n # no translation needed, and it shouldn't appear in stats\n if detected_lang != \"und\" and str(lang_code).lower() == str(detected_lang).lower():\n continue\n\n lang_translation = per_lang_values.get(lang_code, \"\")\n\n # Check for undetermined source language\n lang_needs_review = (detected_lang == \"und\")\n\n if lang_needs_review:\n logger.explore(\"undetected language\", {\n \"record_id\": row_id,\n \"language_code\": lang_code,\n \"source_text\": source_text[:100],\n })\n\n lang_entry = TranslationLanguage(\n id=str(uuid.uuid4()),\n record_id=record.id,\n language_code=lang_code,\n source_language_detected=detected_lang,\n translated_value=lang_translation or \"\",\n final_value=lang_translation or \"\",\n status=\"translated\",\n needs_review=lang_needs_review,\n )\n self.db.add(lang_entry)\n\n return {\n \"successful\": successful,\n \"failed\": failed,\n \"skipped\": skipped,\n \"retries\": retries,\n }\n # endregion _call_llm_for_batch\n\n # region _call_llm [TYPE Function]\n # @PURPOSE: Call the configured LLM provider with the batch prompt.\n # @PRE: job has valid provider_id.\n # @POST: Returns raw LLM response string.\n # @SIDE_EFFECT: HTTP call to LLM provider.\n def _call_llm(self, job: TranslationJob, prompt: str, max_tokens: int = 8192) -> tuple[str, str | None]:\n with belief_scope(\"TranslationExecutor._call_llm\"):\n if not job.provider_id:\n raise ValueError(\"Job has no LLM provider configured\")\n\n provider_svc = LLMProviderService(self.db)\n provider = provider_svc.get_provider(job.provider_id)\n if not provider:\n raise ValueError(f\"LLM provider '{job.provider_id}' not found\")\n\n api_key = provider_svc.get_decrypted_api_key(job.provider_id)\n if not api_key:\n raise ValueError(f\"Could not decrypt API key for provider '{job.provider_id}'\")\n\n model = provider.default_model or \"gpt-4o-mini\"\n provider_type = provider.provider_type.lower() if provider.provider_type else \"openai\"\n\n disable_reasoning = getattr(job, 'disable_reasoning', False)\n\n if provider_type in (\"openai\", \"openai_compatible\", \"openrouter\", \"kilo\", \"litellm\"):\n response_text, finish_reason = self._call_openai_compatible(\n base_url=provider.base_url,\n api_key=api_key,\n model=model,\n prompt=prompt,\n provider_type=provider_type,\n max_tokens=max_tokens,\n disable_reasoning=disable_reasoning,\n )\n return response_text, finish_reason\n else:\n raise ValueError(f\"Unsupported provider type '{provider_type}'\")\n # endregion _call_llm\n\n # region _call_openai_compatible [TYPE Function]\n # @PURPOSE: Call OpenAI-compatible API for batch translation.\n # @PRE: Valid API endpoint, key, model, and prompt.\n # @POST: Returns response text.\n # @SIDE_EFFECT: HTTP POST to LLM API.\n @staticmethod\n def _call_openai_compatible(\n base_url: str,\n api_key: str,\n model: str,\n prompt: str,\n provider_type: str = \"openai\",\n max_tokens: int = 8192,\n disable_reasoning: bool = False,\n ) -> tuple[str, str | None]:\n with belief_scope(\"TranslationExecutor._call_openai_compatible\"):\n if not base_url:\n raise ValueError(\"LLM provider has no base_url configured\")\n import requests as http_requests\n\n url = f\"{base_url.rstrip('/')}/chat/completions\"\n headers = {\n \"Authorization\": f\"Bearer {api_key}\",\n \"Content-Type\": \"application/json\",\n }\n # Reasoning-safe system prompt: always forbid chain-of-thought in output.\n # Reasoning models (DeepSeek, QwQ, etc.) may leak reasoning into content\n # when response_format=json_object is set. Explicit suppression in the\n # system message prevents this regardless of the disable_reasoning flag.\n system_content = (\n \"You are a database content translation assistant. \"\n \"Translate the provided text accurately, preserving data semantics. \"\n \"Respond directly with ONLY the JSON result. \"\n \"Do NOT include any reasoning, thinking, chain-of-thought, analysis, \"\n \"or explanation. Output ONLY valid JSON.\"\n )\n\n payload = {\n \"model\": model,\n \"messages\": [\n {\"role\": \"system\", \"content\": system_content},\n {\"role\": \"user\", \"content\": prompt},\n ],\n \"temperature\": 0.1,\n \"max_tokens\": max_tokens,\n }\n\n # Structured output — OpenRouter and Kilo also support response_format, but some\n # upstream providers (e.g. StepFun) reject it. We try with response_format and\n # fall back on 400 \"structured_outputs is not supported\".\n # NOTE: Reasoning models (deepseek, qwen with reasoning, etc.) often break with\n # response_format=json_object, producing reasoning text instead of JSON.\n # When disable_reasoning is set, we remove response_format and rely on the\n # system prompt to enforce JSON-only output.\n if provider_type in (\"openai\", \"openai_compatible\", \"kilo\", \"openrouter\", \"litellm\"):\n if not disable_reasoning:\n payload[\"response_format\"] = {\"type\": \"json_object\"}\n\n # Suppress Chain of Thought reasoning to save output tokens\n # NOTE: Kilo/OpenRouter/LiteLLM do NOT support disabling reasoning (returns 400)\n if disable_reasoning:\n if provider_type not in (\"kilo\", \"openrouter\", \"litellm\"):\n payload[\"reasoning_effort\"] = \"none\"\n # response_format already skipped above when disable_reasoning is True\n # Use caller-provided max_tokens instead of hardcoded 8192\n payload[\"max_tokens\"] = max_tokens\n\n logger.reason(\n f\"LLM request url={base_url} model={payload.get('model')} \"\n f\"provider_type={provider_type} \"\n f\"response_format={'yes' if 'response_format' in payload else 'no'} \"\n f\"prompt_len={len(prompt)}\"\n )\n\n # ── Handle rate limiting with Retry-After header ──\n import time as _time\n _max_retry_429 = 3\n _retry_count_429 = 0\n while _retry_count_429 < _max_retry_429:\n response = http_requests.post(url, headers=headers, json=payload, timeout=180)\n if response.status_code == 429:\n _retry_count_429 += 1\n retry_after = response.headers.get(\"Retry-After\")\n if retry_after:\n try:\n wait = int(retry_after)\n except (ValueError, TypeError):\n wait = 2 ** _retry_count_429\n else:\n wait = 2 ** _retry_count_429\n logger.explore(\n f\"Rate limited (429), retry {_retry_count_429}/{_max_retry_429} \"\n f\"after {wait}s\",\n extra={\"src\": \"executor\", \"retry_after\": retry_after, \"wait\": wait},\n )\n _time.sleep(wait)\n if _retry_count_429 >= _max_retry_429:\n break\n else:\n break\n\n _response_format_error_patterns = (\"response_format\", \"structured_outputs\", \"structured\", \"json_object\")\n if (\n not response.ok\n and response.status_code == 400\n and any(p in (response.text or \"\").lower() for p in _response_format_error_patterns)\n ):\n logger.explore(\"Structured outputs not supported by upstream, retrying without response_format\", extra={\"src\": \"executor\"})\n payload.pop(\"response_format\", None)\n response = http_requests.post(url, headers=headers, json=payload, timeout=180)\n if not response.ok:\n logger.explore(\n f\"LLM API error status={response.status_code} \"\n f\"model={payload.get('model')} \"\n f\"body={response.text[:2000]}\"\n )\n response.raise_for_status()\n data = response.json()\n\n choices = data.get(\"choices\", [])\n if not choices:\n logger.explore(\"LLM returned no choices\", extra={\"src\": \"executor\", \"response_keys\": list(data.keys()), \"response_preview\": str(data)[:2000]})\n raise ValueError(\"LLM returned no choices\")\n\n try:\n finish_reason = choices[0].get(\"finish_reason\") or \"none\"\n msg = choices[0].get(\"message\") or {}\n except (TypeError, AttributeError) as e:\n logger.explore(\"TypeError processing LLM response choices\", extra={\n \"src\": \"executor_diag\",\n \"error\": str(e),\n \"choices_0_type\": type(choices[0]).__name__ if choices else \"N/A\",\n \"choices_0_repr\": repr(choices[0])[:2000] if choices else \"N/A\",\n \"data_type\": type(data).__name__,\n \"data_preview\": str(data)[:2000],\n })\n raise ValueError(f\"LLM response processing failed: {e}\")\n\n # Handle model refusal (content is empty/null, refusal field has reason)\n refusal = msg.get(\"refusal\") if isinstance(msg, dict) else None\n if refusal:\n logger.explore(\"LLM refused to respond\", extra={\n \"src\": \"executor\",\n \"refusal\": str(refusal)[:500],\n \"finish_reason\": finish_reason,\n })\n raise ValueError(f\"LLM refused to respond: {refusal}\")\n content = msg.get(\"content\") if isinstance(msg, dict) else \"\"\n if not content and isinstance(msg, dict):\n content = msg.get(\"content\") or \"\"\n logger.reason(f\"LLM response finish_reason={finish_reason} content_len={len(content)} msg_keys={list(msg.keys()) if isinstance(msg, dict) else []}\")\n if not content:\n logger.explore(\"LLM returned empty content\", extra={\"src\": \"executor\", \"finish_reason\": finish_reason, \"msg_keys\": list(msg.keys()) if isinstance(msg, dict) else [], \"response_preview\": str(data)[:2000]})\n raise ValueError(\"LLM returned empty content\")\n\n return content, finish_reason\n # endregion _call_openai_compatible\n\n # region _parse_llm_response [TYPE Function]\n # @PURPOSE: Parse LLM JSON response into dict of row_id -> per-language translations.\n # Supports multi-language format: {\"row_id\": 0, \"detected_source_language\": \"fr\", \"ru\": \"текст\", \"en\": \"text\"}\n # Backward-compat: old format {\"row_id\": 0, \"translation\": \"text\", \"detected_source_language\": \"fr\"}\n # @PRE: response_text is valid JSON with {\"rows\": [...]} structure.\n # @POST: Returns dict mapping row_id to dict with 'detected_source_language' and per-language codes.\n @staticmethod\n def _parse_llm_response(response_text: str, expected_count: int, target_languages: list[str] | None = None, finish_reason: str | None = None) -> dict[str, dict[str, str]]:\n with belief_scope(\"TranslationExecutor._parse_llm_response\"):\n try:\n data = json.loads(response_text)\n except json.JSONDecodeError:\n # Try to extract from markdown code block\n import re\n match = re.search(r'```(?:json)?\\s*\\n?(.*?)\\n?```', response_text, re.DOTALL)\n if match:\n try:\n data = json.loads(match.group(1))\n rows = data.get(\"rows\", [])\n if isinstance(rows, list) and rows:\n logger.reason(\"Parsed JSON from markdown code block\", {\"rows\": len(rows)})\n except json.JSONDecodeError:\n pass # fall through to partial recovery\n else:\n pass # fall through to partial recovery\n \n # If finish_reason=length, try to recover complete rows from truncated JSON\n logger.explore(\"LLM truncated, trying partial row recovery\", extra={\"src\": \"executor\", \"finish_reason\": finish_reason, \"response_length\": len(response_text)})\n rows_match = re.findall(r'\\{\\s*\"row_id\"\\s*:\\s*(?:\\d+|\"\\d+\").*?\\}\\s*', response_text, re.DOTALL)\n if rows_match:\n partial_rows = []\n for row_text in rows_match:\n try:\n row_data = json.loads(row_text)\n partial_rows.append(row_data)\n except json.JSONDecodeError:\n continue\n if partial_rows:\n logger.explore(f\"Recovered {len(partial_rows)}/{expected_count} complete rows from truncated response\", extra={\"src\": \"executor\"})\n data = {\"rows\": partial_rows}\n else:\n logger.explore(\"Could not recover any complete rows\", extra={\"src\": \"executor\", \"response_preview\": response_text[:1000]})\n raise ValueError(\"LLM response was not valid JSON (could not recover any rows)\")\n else:\n logger.explore(\"No complete rows found in truncated response\", extra={\"src\": \"executor\", \"response_preview\": response_text[:1000]})\n raise ValueError(\"LLM response was not valid JSON\")\n\n rows = data.get(\"rows\", [])\n if not isinstance(rows, list):\n raise ValueError(\"LLM response missing 'rows' array\")\n\n translations: dict[str, dict[str, str]] = {}\n for item in rows:\n row_id = str(item.get(\"row_id\", \"\"))\n if not row_id:\n continue\n\n detected_lang = str(item.get(\"detected_source_language\", \"und\")) if item.get(\"detected_source_language\") else \"und\"\n result: dict[str, str] = {\n \"detected_source_language\": detected_lang,\n }\n\n # Multi-language format: extract per-language keys\n has_language_data = False\n if target_languages:\n for lang_code in target_languages:\n lang_val = item.get(lang_code)\n if lang_val is not None and str(lang_val).strip():\n result[lang_code] = str(lang_val)\n has_language_data = True\n\n # Fallback to legacy single \"translation\" key format\n if not has_language_data:\n translation = item.get(\"translation\")\n if translation is not None:\n result[\"translation\"] = str(translation)\n has_language_data = True\n\n if has_language_data:\n translations[row_id] = result\n\n if len(translations) < expected_count:\n logger.explore(\n f\"LLM returned fewer translations expected={expected_count} \"\n f\"got={len(translations)}\"\n )\n\n return translations\n # endregion _parse_llm_response\n\n\n# #endregion TranslationExecutor\n# #endregion TranslationExecutor\n" }, { "contract_id": "MAX_RETRIES_PER_BATCH", "contract_type": "Constant", "file_path": "backend/src/plugins/translate/executor.py", - "start_line": 48, - "end_line": 50, + "start_line": 50, + "end_line": 52, "tier": "TIER_1", "complexity": 1, "metadata": {}, @@ -49916,8 +49176,8 @@ "contract_id": "MAX_ROWS_PER_RUN", "contract_type": "Constant", "file_path": "backend/src/plugins/translate/executor.py", - "start_line": 52, - "end_line": 57, + "start_line": 54, + "end_line": 59, "tier": "TIER_1", "complexity": 1, "metadata": {}, @@ -49927,16 +49187,104 @@ "tier_source": "AutoCalculated", "body": "# #region MAX_ROWS_PER_RUN [TYPE Constant]\n# Safety cap: without it, a datasource with thousands of rows blocks the single\n# uvicorn worker for minutes/hours. Preview uses sample_size (5-10). Full run\n# should stay within reasonable bounds.\nMAX_ROWS_PER_RUN = 10000\n# #endregion MAX_ROWS_PER_RUN\n" }, + { + "contract_id": "_enforce_dictionary", + "contract_type": "Function", + "file_path": "backend/src/plugins/translate/executor.py", + "start_line": 61, + "end_line": 125, + "tier": "TIER_1", + "complexity": 1, + "metadata": { + "PURPOSE": "Post-processing: enforce dictionary entries in LLM output." + }, + "relations": [], + "schema_warnings": [], + "anchor_syntax": "region", + "tier_source": "AutoCalculated", + "body": "# #region _enforce_dictionary [TYPE Function]\n# @BRIEF Post-processing: enforce dictionary entries in LLM output.\n# If a source term from the dictionary appears in the original text,\n# but the target term is missing from the translation, replace occurrences\n# of the source term in the translated output with the target term.\n# @PRE: dict_matches is a list of dict entries with source_term/target_term.\n# @POST: per_lang_values may be mutated to include forced dictionary replacements.\n# @SIDE_EFFECT: Logs when enforcement is applied.\ndef _enforce_dictionary(\n source_text: str,\n per_lang_values: dict[str, str],\n dict_matches: list[dict[str, Any]],\n batch_id: str,\n row_id: str,\n) -> None:\n \"\"\"Post-processing: enforce dictionary terms in LLM translation output.\n\n For each dictionary entry whose source_term appears in the source_text,\n verify that the target_term is present in each language's translation.\n If missing, replace any occurrence of the source term (which the LLM\n may have left untranslated) with the dictionary target term.\n \"\"\"\n if not dict_matches or not source_text:\n return\n\n text_lower = source_text.lower()\n\n for dm in dict_matches:\n src_term = dm.get(\"source_term\", \"\")\n tgt_term = dm.get(\"target_term\", \"\")\n if not src_term or not tgt_term:\n continue\n\n # Only process if source term actually appears in the original text\n if src_term.lower() not in text_lower:\n continue\n\n # Try to replace in each language\n for lang_code in list(per_lang_values.keys()):\n val = per_lang_values[lang_code]\n if not val:\n continue\n\n # Check if target term is already present (case-insensitive)\n if tgt_term.lower() in val.lower():\n continue\n\n # Try to find the source term (or a close variant) in the output\n # This catches cases where the LLM left the source term untranslated\n # Use lambda to prevent regex back-reference injection from tgt_term\n src_pattern = re.compile(re.escape(src_term), re.IGNORECASE)\n if src_pattern.search(val):\n new_val = src_pattern.sub(lambda _: tgt_term, val)\n if new_val != val:\n logger.reason(\"Dictionary enforcement applied\", {\n \"batch_id\": batch_id,\n \"row_id\": row_id,\n \"language_code\": lang_code,\n \"source_term\": src_term,\n \"target_term\": tgt_term,\n \"before\": val[:200],\n \"after\": new_val[:200],\n })\n per_lang_values[lang_code] = new_val\n# #endregion _enforce_dictionary\n" + }, + { + "contract_id": "_compute_source_hash", + "contract_type": "Function", + "file_path": "backend/src/plugins/translate/executor.py", + "start_line": 128, + "end_line": 161, + "tier": "TIER_1", + "complexity": 1, + "metadata": { + "PURPOSE": "Compute deterministic cache key for a source row." + }, + "relations": [], + "schema_warnings": [], + "anchor_syntax": "region", + "tier_source": "AutoCalculated", + "body": "# #region _compute_source_hash [TYPE Function]\n# @BRIEF Compute deterministic cache key for a source row.\n# SHA256 of (source_text + context_fields + dict_snapshot_hash + config_hash).\n# Key columns (row_id, primary keys) are EXCLUDED — only the text content\n# and meaningful context affect the hash. This ensures identical text with\n# different row identifiers still produces a cache hit.\ndef _compute_source_hash(\n source_text: str,\n source_data: dict | None,\n dict_snapshot_hash: str | None,\n config_hash: str | None,\n context_keys: list[str] | None = None,\n) -> str:\n \"\"\"Deterministic cache key for a translation source row.\n\n Only includes source_text and context-relevant fields from source_data.\n Key/identifier columns are excluded so identical text in different rows hits cache.\n \"\"\"\n # Extract only context-relevant fields from source_data (not keys/identifiers)\n context_data: dict[str, str] = {}\n if source_data and context_keys:\n for key in context_keys:\n val = source_data.get(key)\n if val is not None:\n context_data[key] = str(val)\n\n payload = json.dumps({\n \"text\": source_text,\n \"ctx\": context_data, # only context columns, no key/row_id\n \"dict_hash\": dict_snapshot_hash or \"\",\n \"config_hash\": config_hash or \"\",\n }, sort_keys=True, ensure_ascii=False)\n return hashlib.sha256(payload.encode(\"utf-8\")).hexdigest()\n# #endregion _compute_source_hash\n" + }, + { + "contract_id": "_check_translation_cache", + "contract_type": "Function", + "file_path": "backend/src/plugins/translate/executor.py", + "start_line": 164, + "end_line": 194, + "tier": "TIER_1", + "complexity": 1, + "metadata": { + "PURPOSE": "Look up a previously successful translation by source_hash." + }, + "relations": [], + "schema_warnings": [], + "anchor_syntax": "region", + "tier_source": "AutoCalculated", + "body": "# #region _check_translation_cache [TYPE Function]\n# @BRIEF Look up a previously successful translation by source_hash.\n# Returns per-language dict {lang_code: final_value} or None.\ndef _check_translation_cache(\n db: Session,\n source_hash: str,\n) -> dict[str, str] | None:\n \"\"\"Check if this source_hash was already translated successfully.\"\"\"\n from sqlalchemy.orm import joinedload\n from ...models.translate import TranslationRecord, TranslationLanguage\n\n cached = (\n db.query(TranslationRecord)\n .options(joinedload(TranslationRecord.languages))\n .filter(\n TranslationRecord.source_hash == source_hash,\n TranslationRecord.status == \"SUCCESS\",\n )\n .order_by(TranslationRecord.created_at.desc())\n .first()\n )\n if not cached:\n return None\n\n lang_values: dict[str, str] = {}\n for lang in cached.languages:\n if lang.status == \"translated\" and lang.final_value:\n lang_values[lang.language_code] = lang.final_value\n\n return lang_values if lang_values else None\n# #endregion _check_translation_cache\n" + }, + { + "contract_id": "estimate_row_tokens", + "contract_type": "Function", + "file_path": "backend/src/plugins/translate/executor.py", + "start_line": 197, + "end_line": 224, + "tier": "TIER_2", + "complexity": 4, + "metadata": { + "COMPLEXITY": 4, + "POST": "Returns estimated token count >= 1.", + "PRE": "source_text is a string.", + "PURPOSE": "Estimate token count for a single source row including context fields." + }, + "relations": [ + { + "source_id": "estimate_row_tokens", + "relation_type": "DEPENDS_ON", + "target_id": "_estimate_tokens_for_text", + "target_ref": "[_estimate_tokens_for_text]" + } + ], + "schema_warnings": [ + { + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", + "detail": { + "actual_complexity": 4, + "contract_type": "Function" + } + } + ], + "anchor_syntax": "region", + "tier_source": "AutoCalculated", + "body": "# #region estimate_row_tokens [C:4] [TYPE Function] [SEMANTICS translate, token, estimation]\n# @BRIEF Estimate token count for a single source row including context fields.\n# @PRE source_text is a string.\n# @POST Returns estimated token count >= 1.\n# @RELATION DEPENDS_ON -> [_estimate_tokens_for_text]\n\ndef estimate_row_tokens(\n source_text: str,\n source_data: dict | None,\n job,\n) -> int:\n \"\"\"Estimate token count for a single source row including context fields.\n\n Uses CJK-aware heuristics via _token_budget._estimate_tokens_for_text.\n Context fields from job.context_columns are included in the estimate.\n \"\"\"\n from ._token_budget import _estimate_tokens_for_text\n\n text_tokens = _estimate_tokens_for_text(source_text or \"\")\n\n context_keys = job.context_columns or []\n ctx_text = \"\"\n if source_data and context_keys:\n ctx_text = \" \".join(str(source_data.get(k, \"\")) for k in context_keys)\n ctx_tokens = _estimate_tokens_for_text(ctx_text)\n\n return text_tokens + ctx_tokens\n# #endregion estimate_row_tokens\n" + }, { "contract_id": "TranslationMetrics", "contract_type": "Module", "file_path": "backend/src/plugins/translate/metrics.py", "start_line": 1, - "end_line": 191, + "end_line": 192, "tier": "TIER_2", - "complexity": 3, + "complexity": 4, "metadata": { - "COMPLEXITY": 3, + "COMPLEXITY": "4", "LAYER": "Domain", "POST": "Metrics are aggregated and returned; no side effects.", "PRE": "Database session is open.", @@ -49948,20 +49296,20 @@ { "source_id": "TranslationMetrics", "relation_type": "DEPENDS_ON", - "target_id": "TranslationEvent:Class", - "target_ref": "[TranslationEvent:Class]" + "target_id": "TranslationSchedule:Class", + "target_ref": "[TranslationSchedule:Class]" }, { "source_id": "TranslationMetrics", "relation_type": "DEPENDS_ON", - "target_id": "MetricSnapshot:Class", - "target_ref": "[MetricSnapshot:Class]" + "target_id": "TranslationSchedule:Class", + "target_ref": "[TranslationSchedule:Class]" }, { "source_id": "TranslationMetrics", "relation_type": "DEPENDS_ON", - "target_id": "TranslationRun:Class", - "target_ref": "[TranslationRun:Class]" + "target_id": "TranslationSchedule:Class", + "target_ref": "[TranslationSchedule:Class]" }, { "source_id": "TranslationMetrics", @@ -49972,34 +49320,25 @@ ], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Module' at C3", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Module' at C4", "detail": { - "actual_complexity": 3, - "contract_type": "Module" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Module' at C3", - "detail": { - "actual_complexity": 3, + "actual_complexity": 4, "contract_type": "Module" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslationMetrics [C:3] [TYPE Module] [SEMANTICS sqlalchemy, translate, metrics, job, statistics]\n# @BRIEF Aggregate translation metrics from live TranslationEvent + MetricSnapshot for per-job reporting.\n# @LAYER: Domain\n# @RELATION DEPENDS_ON -> [TranslationEvent:Class]\n# @RELATION DEPENDS_ON -> [MetricSnapshot:Class]\n# @RELATION DEPENDS_ON -> [TranslationRun:Class]\n# @RELATION DEPENDS_ON -> [TranslationSchedule:Class]\n# @PRE: Database session is open.\n# @POST: Metrics are aggregated and returned; no side effects.\n# @RATIONALE: Live events (<90 days) + MetricSnapshot (>=90 days) fusion for complete picture.\n# @REJECTED: Querying all events for all time — would be slow; MetricSnapshot provides historical summary.\n\nfrom datetime import UTC, datetime\nfrom typing import Any\n\nfrom sqlalchemy import func\nfrom sqlalchemy.orm import Session\n\nfrom ...core.logger import belief_scope\nfrom ...models.translate import (\n MetricSnapshot,\n TranslationEvent,\n TranslationRun,\n TranslationRunLanguageStats,\n TranslationSchedule,\n)\n\n\n# #region TranslationMetrics [C:3] [TYPE Class]\n# @BRIEF Aggregate translation metrics from live events and MetricSnapshot.\nclass TranslationMetrics:\n\n def __init__(self, db: Session):\n self.db = db\n\n # region get_job_metrics [TYPE Function]\n # @PURPOSE: Get aggregated metrics for a specific job.\n # @PRE: job_id exists.\n # @POST: Returns dict with metrics from events + latest snapshot.\n def get_job_metrics(self, job_id: str) -> dict[str, Any]:\n with belief_scope(\"TranslationMetrics.get_job_metrics\"):\n # Run counts from TranslationRun\n run_counts = (\n self.db.query(\n TranslationRun.status,\n func.count(TranslationRun.id),\n )\n .filter(TranslationRun.job_id == job_id)\n .group_by(TranslationRun.status)\n .all()\n )\n\n total_runs = 0\n status_counts: dict[str, int] = {}\n for status_val, count in run_counts:\n status_counts[status_val] = count\n total_runs += count\n\n # Aggregate record stats from runs\n record_stats = (\n self.db.query(\n func.coalesce(func.sum(TranslationRun.total_records), 0),\n func.coalesce(func.sum(TranslationRun.successful_records), 0),\n func.coalesce(func.sum(TranslationRun.failed_records), 0),\n func.coalesce(func.sum(TranslationRun.skipped_records), 0),\n )\n .filter(TranslationRun.job_id == job_id)\n .first()\n )\n total_records = record_stats[0] if record_stats else 0\n successful_records = record_stats[1] if record_stats else 0\n failed_records = record_stats[2] if record_stats else 0\n skipped_records = record_stats[3] if record_stats else 0\n\n # Average duration from runs\n avg_duration = (\n self.db.query(\n func.avg(\n func.extract('epoch', TranslationRun.completed_at - TranslationRun.started_at) * 1000\n )\n )\n .filter(\n TranslationRun.job_id == job_id,\n TranslationRun.started_at.isnot(None),\n TranslationRun.completed_at.isnot(None),\n )\n .scalar()\n )\n\n # Last run\n last_run = (\n self.db.query(TranslationRun)\n .filter(TranslationRun.job_id == job_id)\n .order_by(TranslationRun.created_at.desc())\n .first()\n )\n\n # Next scheduled run\n next_schedule = (\n self.db.query(TranslationSchedule)\n .filter(\n TranslationSchedule.job_id == job_id,\n TranslationSchedule.is_active == True,\n )\n .first()\n )\n\n # Cumulative tokens/cost from MetricSnapshot + events\n cumulative_tokens = 0\n cumulative_cost = 0.0\n\n # Latest MetricSnapshot\n latest_snapshot = (\n self.db.query(MetricSnapshot)\n .filter(MetricSnapshot.job_id == job_id)\n .order_by(MetricSnapshot.snapshot_date.desc())\n .first()\n )\n if latest_snapshot:\n # MetricSnapshot stores per-snapshot aggregated tokens/cost\n # Here we sum what we stored — in practice MetricSnapshot.covers_events_before\n # indicates cutoff\n pass\n\n # Per-language metrics from TranslationRunLanguageStats (live runs)\n per_language: dict[str, dict[str, int | float]] = {}\n lang_stats_rows = (\n self.db.query(TranslationRunLanguageStats)\n .join(TranslationRun, TranslationRunLanguageStats.run_id == TranslationRun.id)\n .filter(TranslationRun.job_id == job_id)\n .all()\n )\n for ls in lang_stats_rows:\n lang = ls.language_code\n if lang not in per_language:\n per_language[lang] = {\"tokens\": 0, \"cost\": 0.0, \"runs\": 0, \"translated_rows\": 0}\n per_language[lang][\"tokens\"] += ls.token_count or 0\n per_language[lang][\"cost\"] += ls.estimated_cost or 0.0\n per_language[lang][\"runs\"] += 1\n per_language[lang][\"translated_rows\"] += ls.translated_rows or 0\n\n # Merge in per-language data from MetricSnapshot (pruned period)\n latest_snapshot = (\n self.db.query(MetricSnapshot)\n .filter(MetricSnapshot.job_id == job_id)\n .order_by(MetricSnapshot.snapshot_date.desc())\n .first()\n )\n if latest_snapshot and latest_snapshot.per_language_metrics:\n for lang, snap_data in latest_snapshot.per_language_metrics.items():\n if lang not in per_language:\n per_language[lang] = {\"tokens\": 0, \"cost\": 0.0, \"runs\": 0, \"translated_rows\": 0}\n per_language[lang][\"tokens\"] += snap_data.get(\"cumulative_tokens\", 0)\n per_language[lang][\"cost\"] += snap_data.get(\"cumulative_cost\", 0.0)\n per_language[lang][\"runs\"] += snap_data.get(\"runs\", 0)\n\n return {\n \"job_id\": job_id,\n \"total_runs\": total_runs,\n \"successful_runs\": status_counts.get(\"COMPLETED\", 0),\n \"failed_runs\": status_counts.get(\"FAILED\", 0),\n \"cancelled_runs\": status_counts.get(\"CANCELLED\", 0),\n \"total_records\": int(total_records),\n \"successful_records\": int(successful_records),\n \"failed_records\": int(failed_records),\n \"skipped_records\": int(skipped_records),\n \"cumulative_tokens\": cumulative_tokens,\n \"cumulative_cost\": cumulative_cost,\n \"avg_duration_ms\": int(avg_duration) if avg_duration else None,\n \"last_run_at\": last_run.created_at.isoformat() if last_run else None,\n \"next_scheduled_run\": next_schedule.last_run_at.isoformat() if next_schedule and next_schedule.last_run_at else None,\n \"per_language_metrics\": per_language,\n }\n # endregion get_job_metrics\n\n # region get_all_metrics [TYPE Function]\n # @PURPOSE: Get aggregated metrics for all jobs.\n # @POST: Returns list of per-job metrics.\n def get_all_metrics(self) -> list[dict[str, Any]]:\n with belief_scope(\"TranslationMetrics.get_all_metrics\"):\n job_ids = (\n self.db.query(TranslationRun.job_id)\n .distinct()\n .all()\n )\n return [self.get_job_metrics(jid[0]) for jid in job_ids if jid[0]]\n # endregion get_all_metrics\n\n\n# #endregion TranslationMetrics\n# #endregion TranslationMetrics\n" + "body": "# #region TranslationMetrics [C:3] [TYPE Module] [SEMANTICS sqlalchemy, translate, metrics, job, statistics]\n# @BRIEF Aggregate translation metrics from live TranslationEvent + MetricSnapshot for per-job reporting.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [TranslationSchedule:Class]\n# @RELATION DEPENDS_ON -> [TranslationSchedule:Class]\n# @RELATION DEPENDS_ON -> [TranslationSchedule:Class]\n# @RELATION DEPENDS_ON -> [TranslationSchedule:Class]\n# @PRE Database session is open.\n# @POST Metrics are aggregated and returned; no side effects.\n# @RATIONALE Live events (<90 days) + MetricSnapshot (>=90 days) fusion for complete picture.\n# @REJECTED Querying all events for all time — would be slow; MetricSnapshot provides historical summary.\n# @COMPLEXITY 4\n\nfrom datetime import UTC, datetime\nfrom typing import Any\n\nfrom sqlalchemy import func\nfrom sqlalchemy.orm import Session\n\nfrom ...core.logger import belief_scope\nfrom ...models.translate import (\n MetricSnapshot,\n TranslationEvent,\n TranslationRun,\n TranslationRunLanguageStats,\n TranslationSchedule,\n)\n\n\n# #region TranslationMetrics [C:3] [TYPE Class]\n# @BRIEF Aggregate translation metrics from live events and MetricSnapshot.\nclass TranslationMetrics:\n\n def __init__(self, db: Session):\n self.db = db\n\n # region get_job_metrics [TYPE Function]\n # @PURPOSE Get aggregated metrics for a specific job.\n # @PRE job_id exists.\n # @POST Returns dict with metrics from events + latest snapshot.\n def get_job_metrics(self, job_id: str) -> dict[str, Any]:\n with belief_scope(\"TranslationMetrics.get_job_metrics\"):\n # Run counts from TranslationRun\n run_counts = (\n self.db.query(\n TranslationRun.status,\n func.count(TranslationRun.id),\n )\n .filter(TranslationRun.job_id == job_id)\n .group_by(TranslationRun.status)\n .all()\n )\n\n total_runs = 0\n status_counts: dict[str, int] = {}\n for status_val, count in run_counts:\n status_counts[status_val] = count\n total_runs += count\n\n # Aggregate record stats from runs\n record_stats = (\n self.db.query(\n func.coalesce(func.sum(TranslationRun.total_records), 0),\n func.coalesce(func.sum(TranslationRun.successful_records), 0),\n func.coalesce(func.sum(TranslationRun.failed_records), 0),\n func.coalesce(func.sum(TranslationRun.skipped_records), 0),\n )\n .filter(TranslationRun.job_id == job_id)\n .first()\n )\n total_records = record_stats[0] if record_stats else 0\n successful_records = record_stats[1] if record_stats else 0\n failed_records = record_stats[2] if record_stats else 0\n skipped_records = record_stats[3] if record_stats else 0\n\n # Average duration from runs\n avg_duration = (\n self.db.query(\n func.avg(\n func.extract('epoch', TranslationRun.completed_at - TranslationRun.started_at) * 1000\n )\n )\n .filter(\n TranslationRun.job_id == job_id,\n TranslationRun.started_at.isnot(None),\n TranslationRun.completed_at.isnot(None),\n )\n .scalar()\n )\n\n # Last run\n last_run = (\n self.db.query(TranslationRun)\n .filter(TranslationRun.job_id == job_id)\n .order_by(TranslationRun.created_at.desc())\n .first()\n )\n\n # Next scheduled run\n next_schedule = (\n self.db.query(TranslationSchedule)\n .filter(\n TranslationSchedule.job_id == job_id,\n TranslationSchedule.is_active == True,\n )\n .first()\n )\n\n # Cumulative tokens/cost from MetricSnapshot + events\n cumulative_tokens = 0\n cumulative_cost = 0.0\n\n # Latest MetricSnapshot\n latest_snapshot = (\n self.db.query(MetricSnapshot)\n .filter(MetricSnapshot.job_id == job_id)\n .order_by(MetricSnapshot.snapshot_date.desc())\n .first()\n )\n if latest_snapshot:\n # MetricSnapshot stores per-snapshot aggregated tokens/cost\n # Here we sum what we stored — in practice MetricSnapshot.covers_events_before\n # indicates cutoff\n pass\n\n # Per-language metrics from TranslationRunLanguageStats (live runs)\n per_language: dict[str, dict[str, int | float]] = {}\n lang_stats_rows = (\n self.db.query(TranslationRunLanguageStats)\n .join(TranslationRun, TranslationRunLanguageStats.run_id == TranslationRun.id)\n .filter(TranslationRun.job_id == job_id)\n .all()\n )\n for ls in lang_stats_rows:\n lang = ls.language_code\n if lang not in per_language:\n per_language[lang] = {\"tokens\": 0, \"cost\": 0.0, \"runs\": 0, \"translated_rows\": 0}\n per_language[lang][\"tokens\"] += ls.token_count or 0\n per_language[lang][\"cost\"] += ls.estimated_cost or 0.0\n per_language[lang][\"runs\"] += 1\n per_language[lang][\"translated_rows\"] += ls.translated_rows or 0\n\n # Merge in per-language data from MetricSnapshot (pruned period)\n latest_snapshot = (\n self.db.query(MetricSnapshot)\n .filter(MetricSnapshot.job_id == job_id)\n .order_by(MetricSnapshot.snapshot_date.desc())\n .first()\n )\n if latest_snapshot and latest_snapshot.per_language_metrics:\n for lang, snap_data in latest_snapshot.per_language_metrics.items():\n if lang not in per_language:\n per_language[lang] = {\"tokens\": 0, \"cost\": 0.0, \"runs\": 0, \"translated_rows\": 0}\n per_language[lang][\"tokens\"] += snap_data.get(\"cumulative_tokens\", 0)\n per_language[lang][\"cost\"] += snap_data.get(\"cumulative_cost\", 0.0)\n per_language[lang][\"runs\"] += snap_data.get(\"runs\", 0)\n\n return {\n \"job_id\": job_id,\n \"total_runs\": total_runs,\n \"successful_runs\": status_counts.get(\"COMPLETED\", 0),\n \"failed_runs\": status_counts.get(\"FAILED\", 0),\n \"cancelled_runs\": status_counts.get(\"CANCELLED\", 0),\n \"total_records\": int(total_records),\n \"successful_records\": int(successful_records),\n \"failed_records\": int(failed_records),\n \"skipped_records\": int(skipped_records),\n \"cumulative_tokens\": cumulative_tokens,\n \"cumulative_cost\": cumulative_cost,\n \"avg_duration_ms\": int(avg_duration) if avg_duration else None,\n \"last_run_at\": last_run.created_at.isoformat() if last_run else None,\n \"next_scheduled_run\": next_schedule.last_run_at.isoformat() if next_schedule and next_schedule.last_run_at else None,\n \"per_language_metrics\": per_language,\n }\n # endregion get_job_metrics\n\n # region get_all_metrics [TYPE Function]\n # @PURPOSE Get aggregated metrics for all jobs.\n # @POST Returns list of per-job metrics.\n def get_all_metrics(self) -> list[dict[str, Any]]:\n with belief_scope(\"TranslationMetrics.get_all_metrics\"):\n job_ids = (\n self.db.query(TranslationRun.job_id)\n .distinct()\n .all()\n )\n return [self.get_job_metrics(jid[0]) for jid in job_ids if jid[0]]\n # endregion get_all_metrics\n\n\n# #endregion TranslationMetrics\n# #endregion TranslationMetrics\n" }, { "contract_id": "TranslationOrchestrator", "contract_type": "Class", "file_path": "backend/src/plugins/translate/orchestrator.py", "start_line": 46, - "end_line": 1115, + "end_line": 1137, "tier": "TIER_3", "complexity": 5, "metadata": { @@ -50033,7 +49372,7 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslationOrchestrator [C:5] [TYPE Class]\n# @BRIEF Coordinates full translation run lifecycle: validation, execution, SQL generation, Superset submission, event logging.\n# @PRE: DB session and config manager are available.\n# @POST: Runs are created, executed, and finalized with event records.\n# @SIDE_EFFECT: Creates/modifies TranslationRun, TranslationBatch, TranslationRecord, TranslationEvent rows.\n# @INVARIANT: State transitions: PENDING -> RUNNING -> COMPLETED|FAILED|CANCELLED.\nclass TranslationOrchestrator:\n\n def __init__(\n self,\n db: Session,\n config_manager: ConfigManager,\n current_user: str | None = None,\n ):\n self.db = db\n self.config_manager = config_manager\n self.current_user = current_user\n self.event_log = TranslationEventLog(db)\n self._job: TranslationJob | None = None\n\n # region start_run [TYPE Function]\n # @PURPOSE: Start a new translation run for a job.\n # @PRE: job_id exists. For manual runs, there must be an accepted preview session.\n # @POST: TranslationRun is created in PENDING status with hash fields and config snapshot. Events are recorded.\n # @SIDE_EFFECT: DB writes.\n def start_run(\n self,\n job_id: str,\n is_scheduled: bool = False,\n trigger_type: str | None = None,\n full_translation: bool = False,\n ) -> TranslationRun:\n with belief_scope(\"TranslationOrchestrator.start_run\"):\n # Load and validate job\n job = self.db.query(TranslationJob).filter(TranslationJob.id == job_id).first()\n if not job:\n raise ValueError(f\"Translation job '{job_id}' not found\")\n self._job = job\n\n logger.reason(\"Starting translation run\", {\n \"job_id\": job_id,\n \"is_scheduled\": is_scheduled,\n })\n\n # Validate preconditions\n self._validate_preconditions(job, is_scheduled=is_scheduled)\n\n # Compute hashes\n config_hash = self._compute_config_hash(job)\n dict_snapshot_hash = self._compute_dict_snapshot_hash(job_id)\n\n # Build config snapshot\n config_snapshot = {\n \"source_dialect\": job.source_dialect,\n \"target_dialect\": job.target_dialect,\n \"database_dialect\": job.database_dialect,\n \"source_datasource_id\": job.source_datasource_id,\n \"source_table\": job.source_table,\n \"target_schema\": job.target_schema,\n \"target_table\": job.target_table,\n \"source_key_cols\": job.source_key_cols,\n \"target_key_cols\": job.target_key_cols,\n \"translation_column\": job.translation_column,\n \"target_column\": job.target_column,\n \"context_columns\": job.context_columns,\n \"provider_id\": job.provider_id,\n \"batch_size\": job.batch_size,\n \"upsert_strategy\": job.upsert_strategy,\n \"dictionary_ids\": self._compute_dict_snapshot_hash(job_id),\n \"full_translation\": full_translation,\n }\n\n # Compute key_hash from source_key_cols\n import hashlib\n key_hash_input = json.dumps({\n \"source_key_cols\": job.source_key_cols,\n \"source_datasource_id\": job.source_datasource_id,\n \"source_table\": job.source_table,\n }, sort_keys=True)\n key_hash = hashlib.sha256(key_hash_input.encode()).hexdigest()[:16]\n\n # Create run record with all hash/snapshot fields\n run = TranslationRun(\n id=str(uuid.uuid4()),\n job_id=job_id,\n status=\"PENDING\",\n trigger_type=trigger_type or (\"scheduled\" if is_scheduled else \"manual\"),\n config_snapshot=config_snapshot,\n key_hash=key_hash,\n config_hash=config_hash,\n dict_snapshot_hash=dict_snapshot_hash,\n created_by=self.current_user,\n created_at=datetime.now(UTC),\n )\n self.db.add(run)\n self.db.flush()\n\n # Record event\n self.event_log.log_event(\n job_id=job_id,\n run_id=run.id,\n event_type=\"RUN_STARTED\",\n payload={\n \"is_scheduled\": is_scheduled,\n \"trigger_type\": run.trigger_type,\n \"config_hash\": config_hash,\n \"dict_snapshot_hash\": dict_snapshot_hash,\n \"key_hash\": key_hash,\n },\n created_by=self.current_user,\n )\n\n self.db.commit()\n self.db.refresh(run)\n\n logger.reflect(\"Run created\", {\n \"run_id\": run.id,\n \"job_id\": job_id,\n \"status\": run.status,\n \"trigger_type\": run.trigger_type,\n })\n return run\n # endregion start_run\n\n # region execute_run [TYPE Function]\n # @PURPOSE: Execute a translation run: dispatch executor, generate SQL, submit to Superset.\n # @PRE: run is in PENDING status.\n # @POST: Run is executed, SQL generated, Superset submission attempted.\n # @SIDE_EFFECT: LLM calls, DB writes, Superset API calls.\n def execute_run(\n self,\n run: TranslationRun,\n on_batch_progress: Callable[[str, int, int, int, int], None] | None = None,\n skip_insert: bool = False,\n ) -> TranslationRun:\n with belief_scope(\"TranslationOrchestrator.execute_run\"):\n job = self.db.query(TranslationJob).filter(TranslationJob.id == run.job_id).first()\n if not job:\n raise ValueError(f\"Job '{run.job_id}' not found\")\n self._job = job\n\n if run.status != \"PENDING\":\n raise ValueError(\n f\"Cannot execute run in status '{run.status}'. \"\n f\"Run must be in PENDING status.\"\n )\n\n logger.reason(\"Executing run\", {\n \"run_id\": run.id,\n \"job_id\": job.id,\n \"skip_insert\": skip_insert,\n })\n\n # Record translation phase start\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=\"TRANSLATION_PHASE_STARTED\",\n payload={},\n created_by=self.current_user,\n )\n\n # Initialize per-language stats\n target_languages = job.target_languages or [job.target_dialect or \"en\"]\n if not isinstance(target_languages, list):\n target_languages = [str(target_languages)]\n language_stats_map: dict[str, TranslationRunLanguageStats] = {}\n for lang_code in target_languages:\n lang_stat = TranslationRunLanguageStats(\n id=str(uuid.uuid4()),\n run_id=run.id,\n language_code=lang_code,\n total_rows=0,\n translated_rows=0,\n failed_rows=0,\n skipped_rows=0,\n token_count=0,\n estimated_cost=0.0,\n )\n self.db.add(lang_stat)\n language_stats_map[lang_code] = lang_stat\n self.db.flush()\n\n # Dispatch executor\n executor = TranslationExecutor(\n self.db, self.config_manager, self.current_user,\n on_batch_progress=on_batch_progress,\n )\n try:\n run = executor.execute_run(run, llm_progress_callback=None, language_stats_map=language_stats_map)\n except Exception as e:\n logger.explore(\"Translation execution failed\", {\n \"run_id\": run.id,\n \"error\": str(e),\n })\n run.status = \"FAILED\"\n run.error_message = f\"Translation execution failed: {e}\"\n run.completed_at = datetime.now(UTC)\n self.db.flush()\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=\"RUN_FAILED\",\n payload={\"error\": str(e), \"phase\": \"translation\"},\n created_by=self.current_user,\n )\n self.db.commit()\n return run\n\n # Check if executor cancelled itself due to cancellation flag\n if run.status == \"CANCELLED\":\n self._update_language_stats(run.id, language_stats_map)\n self.db.commit()\n logger.reflect(\"Run cancelled via cancellation flag\", {\n \"run_id\": run.id,\n })\n return run\n\n # Aggregate per-language statistics after executor completes\n self._update_language_stats(run.id, language_stats_map)\n\n # Record translation phase complete\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=\"TRANSLATION_PHASE_COMPLETED\",\n payload={\n \"total\": run.total_records,\n \"successful\": run.successful_records,\n \"failed\": run.failed_records,\n \"skipped\": run.skipped_records,\n },\n created_by=self.current_user,\n )\n\n # Skip insert phase if requested (e.g., for preview-only execution)\n if skip_insert:\n run.status = \"COMPLETED\"\n run.completed_at = datetime.now(UTC)\n self.db.flush()\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=\"RUN_COMPLETED\",\n payload={\"skip_insert\": True},\n created_by=self.current_user,\n )\n self.db.commit()\n return run\n\n # Generate SQL and submit to Superset\n insert_result = self._generate_and_insert_sql(job, run)\n run.insert_status = insert_result.get(\"status\")\n run.superset_execution_id = str(insert_result.get(\"query_id\") or \"\")\n run.superset_execution_log = insert_result\n # Preserve the translation-phase status. If the executor already\n # marked the run FAILED (all LLM calls failed) we do NOT upgrade it\n # to COMPLETED just because the insert phase ran.\n if run.status != \"FAILED\":\n run.status = \"COMPLETED\"\n if insert_result.get(\"error_message\"):\n run.error_message = insert_result[\"error_message\"]\n run.completed_at = datetime.now(UTC)\n self.db.flush()\n\n # Record terminal event\n terminal_event = \"RUN_COMPLETED\"\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=terminal_event,\n payload={\n \"insert_status\": insert_result.get(\"status\"),\n \"query_id\": insert_result.get(\"query_id\"),\n \"rows_affected\": insert_result.get(\"rows_affected\"),\n \"total_records\": run.total_records,\n \"successful\": run.successful_records,\n \"failed\": run.failed_records,\n \"skipped\": run.skipped_records,\n },\n created_by=self.current_user,\n )\n\n self.db.commit()\n # Re-query run after commit — refresh may fail if the object was\n # created in a different session or became detached during commit.\n run = self.db.query(TranslationRun).filter(TranslationRun.id == run.id).first()\n\n logger.reflect(\"Run execution complete\", {\n \"run_id\": run.id,\n \"status\": run.status,\n \"insert_status\": run.insert_status,\n })\n return run\n # endregion execute_run\n\n # region _generate_and_insert_sql [TYPE Function]\n # @PURPOSE: Generate INSERT SQL from successful records and submit to Superset SQL Lab.\n # @PRE: job has target table configured. run has successful records.\n # @POST: SQL is generated and submitted. Returns execution result.\n # @SIDE_EFFECT: Superset API call.\n def _generate_and_insert_sql(\n self,\n job: TranslationJob,\n run: TranslationRun,\n ) -> dict[str, Any]:\n with belief_scope(\"TranslationOrchestrator._generate_and_insert_sql\"):\n # Fetch successful records with eager-loaded language data\n records = (\n self.db.query(TranslationRecord)\n .options(joinedload(TranslationRecord.languages))\n .filter(\n TranslationRecord.run_id == run.id,\n TranslationRecord.status == \"SUCCESS\",\n TranslationRecord.target_sql.isnot(None),\n )\n .all()\n )\n\n if not records:\n logger.reason(\"No successful records to insert\", {\"run_id\": run.id})\n return {\"status\": \"skipped\", \"reason\": \"no_records\", \"query_id\": None}\n\n logger.reason(f\"Generating SQL for {len(records)} records\", {\n \"run_id\": run.id,\n \"dialect\": job.database_dialect or job.target_dialect,\n })\n\n effective_target = job.target_column or job.translation_column\n primary_language = (job.target_languages or [\"en\"])[0]\n\n # Columns that exist in the target ClickHouse table\n columns = []\n if job.target_key_cols:\n columns.extend(job.target_key_cols)\n if effective_target:\n columns.append(effective_target)\n if job.target_language_column:\n columns.append(job.target_language_column)\n if job.target_source_column:\n columns.append(job.target_source_column)\n if job.target_source_language_column:\n columns.append(job.target_source_language_column)\n columns.append(\"context\")\n columns.append(\"is_original\")\n # Deduplicate while preserving order\n seen: set[str] = set()\n deduped: list[str] = []\n for c in columns:\n if c and c not in seen:\n deduped.append(c)\n seen.add(c)\n columns = deduped\n\n # Keys for the context JSON: context_columns + original translation_column\n context_keys = list(job.context_columns or [])\n if job.translation_column and job.translation_column != effective_target and job.translation_column not in context_keys:\n context_keys.append(job.translation_column)\n\n rows_for_sql: list[dict[str, object]] = []\n for rec in records:\n source_data = rec.source_data or {}\n\n # Detect source language from first TranslationLanguage entry\n detected_src_lang = \"und\"\n if rec.languages and len(rec.languages) > 0:\n detected_src_lang = rec.languages[0].source_language_detected or \"und\"\n\n # Build context JSON: all extra columns the user configured\n context_data: dict[str, str] = {}\n for key in context_keys:\n val = source_data.get(key)\n context_data[key] = str(val) if val is not None else \"\"\n\n # ── Shared base row ──\n base_row: dict[str, object] = {}\n\n if job.target_key_cols:\n for k in job.target_key_cols:\n base_row[k] = source_data.get(k, \"\")\n\n if job.target_source_column:\n base_row[job.target_source_column] = rec.source_sql or \"\"\n\n if job.target_source_language_column:\n base_row[job.target_source_language_column] = detected_src_lang\n\n base_row[\"context\"] = json.dumps(context_data, ensure_ascii=False)\n\n # ── 1. ORIGINAL row (is_original = 1) ──\n original_row = dict(base_row)\n if effective_target:\n original_row[effective_target] = rec.source_sql or \"\"\n if job.target_language_column:\n original_row[job.target_language_column] = detected_src_lang\n original_row[\"is_original\"] = 1\n rows_for_sql.append(original_row)\n\n # ── 2. TRANSLATION rows (is_original = 0) ──\n # Skip language that matches the source — the original row already covers it\n if rec.languages and len(rec.languages) > 0:\n for lang in rec.languages:\n if lang.language_code == detected_src_lang:\n continue\n trans_row = dict(base_row)\n trans_value = lang.final_value or lang.translated_value or \"\"\n if effective_target:\n trans_row[effective_target] = trans_value\n if job.target_language_column:\n trans_row[job.target_language_column] = lang.language_code\n trans_row[\"is_original\"] = 0\n rows_for_sql.append(trans_row)\n else:\n # Fallback: no per-language data\n fallback_row = dict(base_row)\n if effective_target:\n fallback_row[effective_target] = rec.target_sql or \"\"\n if job.target_language_column:\n fallback_row[job.target_language_column] = primary_language\n fallback_row[\"is_original\"] = 0\n rows_for_sql.append(fallback_row)\n\n if not columns:\n columns = [effective_target or \"translated_text\"]\n rows_for_sql = [{columns[0]: rec.target_sql or \"\"} for rec in records]\n\n # Resolve the real database backend engine from Superset\n try:\n env_id = job.environment_id or job.source_dialect or \"\"\n executor = SupersetSqlLabExecutor(self.config_manager, env_id)\n executor.resolve_database_id(\n target_database_id=job.target_database_id,\n )\n real_backend = executor.get_database_backend()\n except Exception as e:\n logger.explore(\"Failed to resolve database backend, falling back to job dialet\", {\n \"error\": str(e),\n })\n real_backend = None\n\n dialect = real_backend or job.database_dialect or job.target_dialect or \"postgresql\"\n\n # Generate SQL\n try:\n sql, row_count = SQLGenerator.generate(\n dialect=dialect,\n target_schema=job.target_schema,\n target_table=job.target_table or \"translated_data\",\n columns=columns,\n rows=rows_for_sql,\n key_columns=job.target_key_cols,\n upsert_strategy=job.upsert_strategy or \"MERGE\",\n )\n except ValueError as e:\n logger.explore(\"SQL generation failed\", {\"error\": str(e)})\n return {\"status\": \"failed\", \"error_message\": str(e), \"query_id\": None}\n\n logger.reason(\"SQL generated with dialect\", {\n \"dialect\": dialect,\n \"real_backend\": real_backend,\n \"job_database_dialect\": job.database_dialect,\n \"job_target_dialect\": job.target_dialect,\n })\n\n # Log insert phase start\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=\"INSERT_PHASE_STARTED\",\n payload={\"sql_length\": len(sql), \"row_count\": row_count, \"dialect\": dialect},\n created_by=self.current_user,\n )\n\n # Submit to Superset\n try:\n result = executor.execute_and_poll(\n sql=sql,\n max_polls=30,\n poll_interval_seconds=2.0,\n )\n except Exception as e:\n logger.explore(\"Superset SQL submission failed\", {\n \"run_id\": run.id,\n \"error\": str(e),\n })\n result = {\"status\": \"failed\", \"error_message\": str(e), \"query_id\": None}\n\n # Log insert phase complete\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=\"INSERT_PHASE_COMPLETED\",\n payload=result,\n created_by=self.current_user,\n )\n\n return result\n # endregion _generate_and_insert_sql\n\n # region _validate_preconditions [TYPE Function]\n # @PURPOSE: Validate preconditions before starting a run.\n # @PRE: None.\n # @POST: Raises ValueError if preconditions are not met.\n # @SIDE_EFFECT: None.\n def _validate_preconditions(\n self,\n job: TranslationJob,\n is_scheduled: bool = False,\n ) -> None:\n with belief_scope(\"TranslationOrchestrator._validate_preconditions\"):\n # Job must be in valid status\n if job.status in (\"DRAFT\",):\n raise ValueError(\n f\"Cannot run job '{job.id}' in status '{job.status}'. \"\n f\"Job must be READY, ACTIVE, or COMPLETED.\"\n )\n\n # Must have target table configured\n if not job.target_table:\n raise ValueError(\n f\"Job '{job.id}' has no target table configured. \"\n \"Configure a target table before running.\"\n )\n\n # Must have LLM provider configured\n if not job.provider_id:\n raise ValueError(\n f\"Job '{job.id}' has no LLM provider configured. \"\n \"Select an LLM provider before running.\"\n )\n\n # Must have a translation column\n if not job.translation_column:\n raise ValueError(\n f\"Job '{job.id}' has no translation column configured. \"\n \"Select a translation column before running.\"\n )\n\n # For manual runs, must have accepted preview\n if not is_scheduled:\n accepted_session = (\n self.db.query(TranslationPreviewSession)\n .filter(\n TranslationPreviewSession.job_id == job.id,\n TranslationPreviewSession.status == \"APPLIED\",\n )\n .order_by(TranslationPreviewSession.created_at.desc())\n .first()\n )\n if not accepted_session:\n raise ValueError(\n f\"Job '{job.id}' has no accepted preview session. \"\n \"Run and accept a preview before executing a manual translation run.\"\n )\n\n logger.reason(\"Preconditions validated\", {\n \"job_id\": job.id,\n \"is_scheduled\": is_scheduled,\n })\n # endregion _validate_preconditions\n\n # region retry_failed_batches [TYPE Function]\n # @PURPOSE: Retry failed batches in a run.\n # @PRE: run exists and has failed batches.\n # @POST: Failed batches are re-processed.\n # @SIDE_EFFECT: LLM calls, DB writes.\n def retry_failed_batches(\n self,\n run_id: str,\n ) -> TranslationRun:\n with belief_scope(\"TranslationOrchestrator.retry_failed_batches\"):\n run = self.db.query(TranslationRun).filter(TranslationRun.id == run_id).first()\n if not run:\n raise ValueError(f\"Run '{run_id}' not found\")\n\n job = self.db.query(TranslationJob).filter(TranslationJob.id == run.job_id).first()\n if not job:\n raise ValueError(f\"Job '{run.job_id}' not found\")\n self._job = job\n\n # Find failed batches\n failed_batches = (\n self.db.query(TranslationBatch)\n .filter(\n TranslationBatch.run_id == run_id,\n TranslationBatch.status.in_([\"FAILED\", \"COMPLETED_WITH_ERRORS\"]),\n )\n .all()\n )\n\n if not failed_batches:\n raise ValueError(f\"No failed batches found for run '{run_id}'\")\n\n logger.reason(\"Retrying failed batches\", {\n \"run_id\": run_id,\n \"batch_count\": len(failed_batches),\n })\n\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=\"RUN_RETRYING\",\n payload={\"batch_count\": len(failed_batches)},\n created_by=self.current_user,\n )\n\n # Re-process each failed batch\n executor = TranslationExecutor(self.db, self.config_manager, self.current_user)\n run.status = \"RUNNING\"\n self.db.flush()\n\n for batch in failed_batches:\n # Fetch failed records for this batch\n failed_records = (\n self.db.query(TranslationRecord)\n .filter(\n TranslationRecord.batch_id == batch.id,\n TranslationRecord.status == \"FAILED\",\n )\n .all()\n )\n\n if not failed_records:\n continue\n\n # Build rows from failed records\n retry_rows = []\n for rec in failed_records:\n retry_rows.append({\n \"row_index\": rec.source_object_id or \"0\",\n \"source_text\": rec.source_sql or \"\",\n \"approved_translation\": None,\n \"source_object_name\": rec.source_object_name or \"\",\n })\n\n # Process retry batch\n result = executor._process_batch(\n job=job,\n run_id=run_id,\n batch_index=batch.batch_index,\n batch_rows=retry_rows,\n )\n\n # Update run stats\n run.successful_records = (run.successful_records or 0) + result[\"successful\"]\n run.failed_records = (run.failed_records or 0) + result[\"failed\"]\n run.skipped_records = (run.skipped_records or 0) + result[\"skipped\"]\n self.db.flush()\n\n # Update run status\n if run.failed_records == 0:\n run.status = \"COMPLETED\"\n elif run.successful_records == 0:\n run.status = \"FAILED\"\n else:\n run.status = \"COMPLETED\"\n\n run.completed_at = datetime.now(UTC)\n self.db.flush()\n\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=\"RUN_COMPLETED\",\n payload={\"retry\": True},\n created_by=self.current_user,\n )\n\n self.db.commit()\n logger.reflect(\"Retry complete\", {\n \"run_id\": run_id,\n \"status\": run.status,\n })\n return run\n # endregion retry_failed_batches\n\n # region retry_insert [TYPE Function]\n # @PURPOSE: Retry the SQL insert phase for a completed run.\n # @PRE: run exists and has successful records.\n # @POST: SQL is regenerated and re-submitted to Superset.\n # @SIDE_EFFECT: Superset API call.\n def retry_insert(\n self,\n run_id: str,\n ) -> TranslationRun:\n with belief_scope(\"TranslationOrchestrator.retry_insert\"):\n run = self.db.query(TranslationRun).filter(TranslationRun.id == run_id).first()\n if not run:\n raise ValueError(f\"Run '{run_id}' not found\")\n\n job = self.db.query(TranslationJob).filter(TranslationJob.id == run.job_id).first()\n if not job:\n raise ValueError(f\"Job '{run.job_id}' not found\")\n self._job = job\n\n logger.reason(\"Retrying insert phase\", {\n \"run_id\": run_id,\n })\n\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=\"RUN_RETRY_INSERT\",\n payload={},\n created_by=self.current_user,\n )\n\n # Regenerate SQL and submit\n insert_result = self._generate_and_insert_sql(job, run)\n\n # Update run\n run.insert_status = insert_result.get(\"status\")\n run.superset_execution_id = str(insert_result.get(\"query_id\") or \"\")\n if insert_result.get(\"error_message\"):\n run.error_message = insert_result[\"error_message\"]\n self.db.flush()\n self.db.commit()\n self.db.refresh(run)\n\n logger.reflect(\"Insert retry complete\", {\n \"run_id\": run_id,\n \"insert_status\": run.insert_status,\n })\n return run\n # endregion retry_insert\n\n # region cancel_run [TYPE Function]\n # @PURPOSE: Cancel a running translation.\n # @PRE: run is in PENDING or RUNNING status.\n # @POST: Run status is set to CANCELLED.\n # @SIDE_EFFECT: DB write; records event.\n def cancel_run(self, run_id: str) -> TranslationRun:\n with belief_scope(\"TranslationOrchestrator.cancel_run\"):\n # Set short lock timeout to avoid blocking on row lock held by\n # background executor thread (which holds RowExclusiveLock during\n # batch processing). If the row is locked, we fall back to setting\n # a cancellation flag via direct SQL UPDATE, which the executor\n # checks after each batch commit.\n try:\n self.db.execute(text(\"SET LOCAL lock_timeout = '3s'\"))\n run = self.db.query(TranslationRun).filter(TranslationRun.id == run_id).first()\n except Exception:\n # Row is locked — set cancellation flag via direct SQL\n logger.explore(\"Row lock timeout — setting cancellation flag via direct SQL\", {\n \"run_id\": run_id,\n })\n self.db.execute(\n text(\"UPDATE translation_runs SET error_message = 'CANCEL_REQUESTED' WHERE id = :run_id\"),\n {\"run_id\": run_id},\n )\n self.db.commit()\n run = self.db.query(TranslationRun).filter(TranslationRun.id == run_id).first()\n if not run:\n raise ValueError(f\"Run '{run_id}' not found\")\n logger.reflect(\"Cancellation flag set for locked run\", {\n \"run_id\": run_id,\n })\n return run\n\n if not run:\n raise ValueError(f\"Run '{run_id}' not found\")\n\n if run.status not in (\"PENDING\", \"RUNNING\"):\n raise ValueError(\n f\"Cannot cancel run in status '{run.status}'. \"\n f\"Only PENDING or RUNNING runs can be cancelled.\"\n )\n\n run.status = \"CANCELLED\"\n run.completed_at = datetime.now(UTC)\n self.db.flush()\n\n self.event_log.log_event(\n job_id=run.job_id,\n run_id=run.id,\n event_type=\"RUN_CANCELLED\",\n payload={},\n created_by=self.current_user,\n )\n\n self.db.commit()\n self.db.refresh(run)\n\n logger.reflect(\"Run cancelled\", {\n \"run_id\": run_id,\n })\n return run\n # endregion cancel_run\n\n # region get_run_status [TYPE Function]\n # @PURPOSE: Get run status with statistics.\n # @PRE: run_id exists.\n # @POST: Returns dict with run details.\n def get_run_status(self, run_id: str) -> dict[str, Any]:\n with belief_scope(\"TranslationOrchestrator.get_run_status\"):\n run = self.db.query(TranslationRun).filter(TranslationRun.id == run_id).first()\n if not run:\n raise ValueError(f\"Run '{run_id}' not found\")\n\n # Count batches\n batch_count = (\n self.db.query(TranslationBatch)\n .filter(TranslationBatch.run_id == run_id)\n .count()\n )\n\n # Get event summary\n event_summary = self.event_log.get_run_event_summary(run_id)\n\n # Get language stats\n language_stats_entries = (\n self.db.query(TranslationRunLanguageStats)\n .filter(TranslationRunLanguageStats.run_id == run_id)\n .all()\n )\n language_stats = [\n {\n \"language_code\": ls.language_code,\n \"total_rows\": ls.total_rows or 0,\n \"translated_rows\": ls.translated_rows or 0,\n \"failed_rows\": ls.failed_rows or 0,\n \"skipped_rows\": ls.skipped_rows or 0,\n \"token_count\": ls.token_count or 0,\n \"estimated_cost\": ls.estimated_cost or 0.0,\n }\n for ls in language_stats_entries\n ]\n\n return {\n \"id\": run.id,\n \"job_id\": run.job_id,\n \"status\": run.status,\n \"started_at\": run.started_at.isoformat() if run.started_at else None,\n \"completed_at\": run.completed_at.isoformat() if run.completed_at else None,\n \"error_message\": run.error_message,\n \"total_records\": run.total_records or 0,\n \"successful_records\": run.successful_records or 0,\n \"failed_records\": run.failed_records or 0,\n \"skipped_records\": run.skipped_records or 0,\n \"insert_status\": run.insert_status,\n \"superset_execution_id\": run.superset_execution_id,\n \"batch_count\": batch_count,\n \"language_stats\": language_stats,\n \"event_invariants\": {\n \"has_run_started\": event_summary[\"has_run_started\"],\n \"terminal_event_count\": event_summary[\"terminal_event_count\"],\n \"invariant_valid\": event_summary[\"invariant_valid\"],\n },\n \"created_by\": run.created_by,\n \"created_at\": run.created_at.isoformat() if run.created_at else None,\n }\n # endregion get_run_status\n\n # region get_run_records [TYPE Function]\n # @PURPOSE: Get paginated records for a run.\n # @PRE: run_id exists.\n # @POST: Returns dict with records and pagination info.\n def get_run_records(\n self,\n run_id: str,\n page: int = 1,\n page_size: int = 50,\n status_filter: str | None = None,\n ) -> dict[str, Any]:\n with belief_scope(\"TranslationOrchestrator.get_run_records\"):\n query = (\n self.db.query(TranslationRecord)\n .options(selectinload(TranslationRecord.languages))\n .filter(TranslationRecord.run_id == run_id)\n )\n\n if status_filter:\n query = query.filter(TranslationRecord.status == status_filter)\n\n total = query.count()\n offset = (page - 1) * page_size\n records = (\n query.order_by(TranslationRecord.created_at.desc())\n .offset(offset)\n .limit(page_size)\n .all()\n )\n\n return {\n \"items\": [\n {\n \"id\": r.id,\n \"batch_id\": r.batch_id,\n \"source_sql\": r.source_sql,\n \"target_sql\": r.target_sql,\n \"source_object_type\": r.source_object_type,\n \"source_object_id\": r.source_object_id,\n \"source_object_name\": r.source_object_name,\n \"status\": r.status,\n \"error_message\": r.error_message,\n \"created_at\": r.created_at.isoformat() if r.created_at else None,\n \"languages\": [\n {\n \"language_code\": tl.language_code,\n \"translated_value\": tl.translated_value,\n \"final_value\": tl.final_value or tl.translated_value,\n \"source_language_detected\": tl.source_language_detected,\n \"status\": tl.status,\n \"needs_review\": tl.needs_review or False,\n }\n for tl in (r.languages or [])\n ],\n }\n for r in records\n ],\n \"total\": total,\n \"page\": page,\n \"page_size\": page_size,\n \"status_filter\": status_filter,\n }\n # endregion get_run_records\n\n # region get_run_history [TYPE Function]\n # @PURPOSE: Get run history for a job.\n # @PRE: job_id exists.\n # @POST: Returns list of runs.\n def get_run_history(\n self,\n job_id: str,\n page: int = 1,\n page_size: int = 20,\n ) -> tuple[int, list[dict[str, Any]]]:\n with belief_scope(\"TranslationOrchestrator.get_run_history\"):\n query = self.db.query(TranslationRun).filter(\n TranslationRun.job_id == job_id\n )\n total = query.count()\n runs = (\n query.order_by(TranslationRun.created_at.desc())\n .offset((page - 1) * page_size)\n .limit(page_size)\n .all()\n )\n\n return total, [\n {\n \"id\": r.id,\n \"job_id\": r.job_id,\n \"status\": r.status,\n \"started_at\": r.started_at.isoformat() if r.started_at else None,\n \"completed_at\": r.completed_at.isoformat() if r.completed_at else None,\n \"error_message\": r.error_message,\n \"total_records\": r.total_records or 0,\n \"successful_records\": r.successful_records or 0,\n \"failed_records\": r.failed_records or 0,\n \"skipped_records\": r.skipped_records or 0,\n \"insert_status\": r.insert_status,\n \"superset_execution_id\": r.superset_execution_id,\n \"created_by\": r.created_by,\n \"created_at\": r.created_at.isoformat() if r.created_at else None,\n }\n for r in runs\n ]\n # endregion get_run_history\n\n # region _update_language_stats [TYPE Function]\n # @PURPOSE: Aggregate TranslationLanguage entries by language_code and update TranslationRunLanguageStats.\n # @PRE: run_id and language_stats_map are valid. DB session is available.\n # @POST: Language stats are updated with row counts and estimated tokens/cost.\n # @SIDE_EFFECT: DB writes on language_stats objects.\n def _update_language_stats(\n self,\n run_id: str,\n language_stats_map: dict[str, TranslationRunLanguageStats],\n ) -> None:\n with belief_scope(\"TranslationOrchestrator._update_language_stats\"):\n # Get all records for this run to join with TranslationLanguage\n records = (\n self.db.query(TranslationRecord)\n .filter(TranslationRecord.run_id == run_id)\n .all()\n )\n record_ids = [r.id for r in records]\n\n if not record_ids:\n logger.reason(\"No records for language stats aggregation\", {\"run_id\": run_id})\n return\n\n # Get all language entries for this run's records\n lang_entries = (\n self.db.query(TranslationLanguage)\n .filter(TranslationLanguage.record_id.in_(record_ids))\n .all()\n )\n\n # Aggregate by language_code\n from collections import defaultdict\n agg: dict[str, dict[str, int]] = defaultdict(lambda: {\"total\": 0, \"translated\": 0, \"failed\": 0, \"skipped\": 0})\n\n for le in lang_entries:\n code = le.language_code\n agg[code][\"total\"] += 1\n if le.status in (\"translated\", \"approved\", \"edited\"):\n agg[code][\"translated\"] += 1\n elif le.status == \"failed\":\n agg[code][\"failed\"] += 1\n elif le.status == \"skipped\":\n agg[code][\"skipped\"] += 1\n\n # Estimate tokens: heuristic based on character count of translated values\n total_chars = sum(\n len(le.translated_value or \"\") for le in lang_entries if le.translated_value\n )\n total_tokens = max(1, total_chars // 4) # ~4 chars per token\n cost_per_token = 0.002 / 1000 # $0.002 per 1K tokens\n\n # Update each language stat entry\n for lang_code, lang_stat in language_stats_map.items():\n data = agg.get(lang_code, {\"total\": 0, \"translated\": 0, \"failed\": 0, \"skipped\": 0})\n lang_stat.total_rows = data[\"total\"]\n lang_stat.translated_rows = data[\"translated\"]\n lang_stat.failed_rows = data[\"failed\"]\n lang_stat.skipped_rows = data[\"skipped\"]\n\n # Proportional token split: share tokens across languages\n num_langs = len(language_stats_map)\n if num_langs > 0:\n lang_stat.token_count = total_tokens // num_langs\n lang_stat.estimated_cost = round((lang_stat.token_count / 1000) * cost_per_token, 6)\n\n self.db.flush()\n\n logger.reason(\"Language stats updated\", {\n \"run_id\": run_id,\n \"languages\": list(language_stats_map.keys()),\n \"total_tokens_est\": total_tokens,\n })\n # endregion _update_language_stats\n\n # region _compute_config_hash [TYPE Function]\n # @PURPOSE: Compute a hash of the job's current configuration for snapshot comparison.\n @staticmethod\n def _compute_config_hash(job: TranslationJob) -> str:\n import hashlib\n config_str = json.dumps({\n \"source_dialect\": job.source_dialect,\n \"target_dialect\": job.target_dialect,\n \"source_datasource_id\": job.source_datasource_id,\n \"translation_column\": job.translation_column,\n \"context_columns\": job.context_columns,\n \"target_languages\": sorted(job.target_languages) if job.target_languages else [],\n \"provider_id\": job.provider_id,\n \"batch_size\": job.batch_size,\n \"upsert_strategy\": job.upsert_strategy,\n }, sort_keys=True)\n return hashlib.sha256(config_str.encode()).hexdigest()[:16]\n # endregion _compute_config_hash\n\n # region _compute_dict_snapshot_hash [TYPE Function]\n # @PURPOSE: Compute a hash of dictionary state for snapshot comparison.\n def _compute_dict_snapshot_hash(self, job_id: str) -> str:\n import hashlib\n\n from ...models.translate import TranslationJobDictionary\n dict_links = (\n self.db.query(TranslationJobDictionary)\n .filter(TranslationJobDictionary.job_id == job_id)\n .all()\n )\n dict_ids = sorted([dl.dictionary_id for dl in dict_links])\n hash_input = \",\".join(dict_ids)\n return hashlib.sha256(hash_input.encode()).hexdigest()[:16]\n # endregion _compute_dict_snapshot_hash\n\n# #endregion TranslationOrchestrator\n" + "body": "# #region TranslationOrchestrator [C:5] [TYPE Class]\n# @BRIEF Coordinates full translation run lifecycle: validation, execution, SQL generation, Superset submission, event logging.\n# @PRE: DB session and config manager are available.\n# @POST: Runs are created, executed, and finalized with event records.\n# @SIDE_EFFECT: Creates/modifies TranslationRun, TranslationBatch, TranslationRecord, TranslationEvent rows.\n# @INVARIANT: State transitions: PENDING -> RUNNING -> COMPLETED|FAILED|CANCELLED.\nclass TranslationOrchestrator:\n\n def __init__(\n self,\n db: Session,\n config_manager: ConfigManager,\n current_user: str | None = None,\n ):\n self.db = db\n self.config_manager = config_manager\n self.current_user = current_user\n self.event_log = TranslationEventLog(db)\n self._job: TranslationJob | None = None\n\n # region start_run [TYPE Function]\n # @PURPOSE: Start a new translation run for a job.\n # @PRE: job_id exists. For manual runs, there must be an accepted preview session.\n # @POST: TranslationRun is created in PENDING status with hash fields and config snapshot. Events are recorded.\n # @SIDE_EFFECT: DB writes.\n def start_run(\n self,\n job_id: str,\n is_scheduled: bool = False,\n trigger_type: str | None = None,\n full_translation: bool = False,\n ) -> TranslationRun:\n with belief_scope(\"TranslationOrchestrator.start_run\"):\n # Load and validate job\n job = self.db.query(TranslationJob).filter(TranslationJob.id == job_id).first()\n if not job:\n raise ValueError(f\"Translation job '{job_id}' not found\")\n self._job = job\n\n logger.reason(\"Starting translation run\", {\n \"job_id\": job_id,\n \"is_scheduled\": is_scheduled,\n })\n\n # Validate preconditions\n self._validate_preconditions(job, is_scheduled=is_scheduled)\n\n # Compute hashes\n config_hash = self._compute_config_hash(job)\n dict_snapshot_hash = self._compute_dict_snapshot_hash(job_id)\n\n # Build config snapshot\n config_snapshot = {\n \"source_dialect\": job.source_dialect,\n \"target_dialect\": job.target_dialect,\n \"database_dialect\": job.database_dialect,\n \"source_datasource_id\": job.source_datasource_id,\n \"source_table\": job.source_table,\n \"target_schema\": job.target_schema,\n \"target_table\": job.target_table,\n \"source_key_cols\": job.source_key_cols,\n \"target_key_cols\": job.target_key_cols,\n \"translation_column\": job.translation_column,\n \"target_column\": job.target_column,\n \"context_columns\": job.context_columns,\n \"provider_id\": job.provider_id,\n \"batch_size\": job.batch_size,\n \"upsert_strategy\": job.upsert_strategy,\n \"dictionary_ids\": self._compute_dict_snapshot_hash(job_id),\n \"full_translation\": full_translation,\n }\n\n # Compute key_hash from source_key_cols\n import hashlib\n key_hash_input = json.dumps({\n \"source_key_cols\": job.source_key_cols,\n \"source_datasource_id\": job.source_datasource_id,\n \"source_table\": job.source_table,\n }, sort_keys=True)\n key_hash = hashlib.sha256(key_hash_input.encode()).hexdigest()[:16]\n\n # Create run record with all hash/snapshot fields\n run = TranslationRun(\n id=str(uuid.uuid4()),\n job_id=job_id,\n status=\"PENDING\",\n trigger_type=trigger_type or (\"scheduled\" if is_scheduled else \"manual\"),\n config_snapshot=config_snapshot,\n key_hash=key_hash,\n config_hash=config_hash,\n dict_snapshot_hash=dict_snapshot_hash,\n created_by=self.current_user,\n created_at=datetime.now(UTC),\n )\n self.db.add(run)\n self.db.flush()\n\n # Record event\n self.event_log.log_event(\n job_id=job_id,\n run_id=run.id,\n event_type=\"RUN_STARTED\",\n payload={\n \"is_scheduled\": is_scheduled,\n \"trigger_type\": run.trigger_type,\n \"config_hash\": config_hash,\n \"dict_snapshot_hash\": dict_snapshot_hash,\n \"key_hash\": key_hash,\n },\n created_by=self.current_user,\n )\n\n self.db.commit()\n self.db.refresh(run)\n\n logger.reflect(\"Run created\", {\n \"run_id\": run.id,\n \"job_id\": job_id,\n \"status\": run.status,\n \"trigger_type\": run.trigger_type,\n })\n return run\n # endregion start_run\n\n # region execute_run [TYPE Function]\n # @PURPOSE: Execute a translation run: dispatch executor, generate SQL, submit to Superset.\n # @PRE: run is in PENDING status.\n # @POST: Run is executed, SQL generated, Superset submission attempted.\n # @SIDE_EFFECT: LLM calls, DB writes, Superset API calls.\n def execute_run(\n self,\n run: TranslationRun,\n on_batch_progress: Callable[[str, int, int, int, int], None] | None = None,\n skip_insert: bool = False,\n ) -> TranslationRun:\n with belief_scope(\"TranslationOrchestrator.execute_run\"):\n job = self.db.query(TranslationJob).filter(TranslationJob.id == run.job_id).first()\n if not job:\n raise ValueError(f\"Job '{run.job_id}' not found\")\n self._job = job\n\n if run.status != \"PENDING\":\n raise ValueError(\n f\"Cannot execute run in status '{run.status}'. \"\n f\"Run must be in PENDING status.\"\n )\n\n logger.reason(\"Executing run\", {\n \"run_id\": run.id,\n \"job_id\": job.id,\n \"skip_insert\": skip_insert,\n })\n\n # Record translation phase start\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=\"TRANSLATION_PHASE_STARTED\",\n payload={},\n created_by=self.current_user,\n )\n\n # Initialize per-language stats\n target_languages = job.target_languages or [job.target_dialect or \"en\"]\n if not isinstance(target_languages, list):\n target_languages = [str(target_languages)]\n language_stats_map: dict[str, TranslationRunLanguageStats] = {}\n for lang_code in target_languages:\n lang_stat = TranslationRunLanguageStats(\n id=str(uuid.uuid4()),\n run_id=run.id,\n language_code=lang_code,\n total_rows=0,\n translated_rows=0,\n failed_rows=0,\n skipped_rows=0,\n token_count=0,\n estimated_cost=0.0,\n )\n self.db.add(lang_stat)\n language_stats_map[lang_code] = lang_stat\n self.db.flush()\n\n # Dispatch executor\n executor = TranslationExecutor(\n self.db, self.config_manager, self.current_user,\n on_batch_progress=on_batch_progress,\n )\n try:\n run = executor.execute_run(run, llm_progress_callback=None, language_stats_map=language_stats_map)\n except Exception as e:\n logger.explore(\"Translation execution failed\", {\n \"run_id\": run.id,\n \"error\": str(e),\n })\n # Rollback the session if it's in a broken state (e.g. after a\n # failed flush from a previous exception in executor.execute_run).\n # Without this, subsequent flush()/commit() calls raise\n # \"This Session's transaction has been rolled back\".\n try:\n self.db.rollback()\n except Exception:\n pass\n run = self.db.merge(run)\n run.status = \"FAILED\"\n run.error_message = f\"Translation execution failed: {e}\"\n run.completed_at = datetime.now(UTC)\n self.db.flush()\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=\"RUN_FAILED\",\n payload={\"error\": str(e), \"phase\": \"translation\"},\n created_by=self.current_user,\n )\n self.db.commit()\n return run\n\n # Check if executor cancelled itself due to cancellation flag\n if run.status == \"CANCELLED\":\n self._update_language_stats(run.id, language_stats_map)\n self.event_log.log_event(\n job_id=job.id if job else (self._job.id if self._job else run.job_id),\n run_id=run.id,\n event_type=\"RUN_CANCELLED\",\n payload={\"reason\": \"cancellation_flag\"},\n created_by=self.current_user,\n )\n self.db.commit()\n logger.reflect(\"Run cancelled via cancellation flag\", {\n \"run_id\": run.id,\n })\n return run\n\n # Aggregate per-language statistics after executor completes\n self._update_language_stats(run.id, language_stats_map)\n\n # Record translation phase complete\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=\"TRANSLATION_PHASE_COMPLETED\",\n payload={\n \"total\": run.total_records,\n \"successful\": run.successful_records,\n \"failed\": run.failed_records,\n \"skipped\": run.skipped_records,\n },\n created_by=self.current_user,\n )\n\n # Skip insert phase if requested (e.g., for preview-only execution)\n if skip_insert:\n run.status = \"COMPLETED\"\n run.completed_at = datetime.now(UTC)\n self.db.flush()\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=\"RUN_COMPLETED\",\n payload={\"skip_insert\": True},\n created_by=self.current_user,\n )\n self.db.commit()\n return run\n\n # Generate SQL and submit to Superset\n insert_result = self._generate_and_insert_sql(job, run)\n run.insert_status = insert_result.get(\"status\")\n run.superset_execution_id = str(insert_result.get(\"query_id\") or \"\")\n run.superset_execution_log = insert_result\n # Preserve the translation-phase status. If the executor already\n # marked the run FAILED (all LLM calls failed) we do NOT upgrade it\n # to COMPLETED just because the insert phase ran.\n if run.status != \"FAILED\":\n run.status = \"COMPLETED\"\n if insert_result.get(\"error_message\"):\n run.error_message = insert_result[\"error_message\"]\n run.completed_at = datetime.now(UTC)\n self.db.flush()\n\n # Record terminal event\n terminal_event = \"RUN_COMPLETED\"\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=terminal_event,\n payload={\n \"insert_status\": insert_result.get(\"status\"),\n \"query_id\": insert_result.get(\"query_id\"),\n \"rows_affected\": insert_result.get(\"rows_affected\"),\n \"total_records\": run.total_records,\n \"successful\": run.successful_records,\n \"failed\": run.failed_records,\n \"skipped\": run.skipped_records,\n },\n created_by=self.current_user,\n )\n\n self.db.commit()\n # Re-query run after commit — refresh may fail if the object was\n # created in a different session or became detached during commit.\n run = self.db.query(TranslationRun).filter(TranslationRun.id == run.id).first()\n\n logger.reflect(\"Run execution complete\", {\n \"run_id\": run.id,\n \"status\": run.status,\n \"insert_status\": run.insert_status,\n })\n return run\n # endregion execute_run\n\n # region _generate_and_insert_sql [TYPE Function]\n # @PURPOSE: Generate INSERT SQL from successful records and submit to Superset SQL Lab.\n # @PRE: job has target table configured. run has successful records.\n # @POST: SQL is generated and submitted. Returns execution result.\n # @SIDE_EFFECT: Superset API call.\n def _generate_and_insert_sql(\n self,\n job: TranslationJob,\n run: TranslationRun,\n ) -> dict[str, Any]:\n with belief_scope(\"TranslationOrchestrator._generate_and_insert_sql\"):\n # Fetch successful records with eager-loaded language data\n records = (\n self.db.query(TranslationRecord)\n .options(joinedload(TranslationRecord.languages))\n .filter(\n TranslationRecord.run_id == run.id,\n TranslationRecord.status == \"SUCCESS\",\n TranslationRecord.target_sql.isnot(None),\n )\n .all()\n )\n\n if not records:\n logger.reason(\"No successful records to insert\", {\"run_id\": run.id})\n return {\"status\": \"skipped\", \"reason\": \"no_records\", \"query_id\": None}\n\n logger.reason(f\"Generating SQL for {len(records)} records\", {\n \"run_id\": run.id,\n \"dialect\": job.database_dialect or job.target_dialect,\n })\n\n effective_target = job.target_column or job.translation_column\n primary_language = (job.target_languages or [\"en\"])[0]\n\n # Columns that exist in the target ClickHouse table\n columns = []\n if job.target_key_cols:\n columns.extend(job.target_key_cols)\n if effective_target:\n columns.append(effective_target)\n if job.target_language_column:\n columns.append(job.target_language_column)\n if job.target_source_column:\n columns.append(job.target_source_column)\n if job.target_source_language_column:\n columns.append(job.target_source_language_column)\n columns.append(\"context\")\n columns.append(\"is_original\")\n # Deduplicate while preserving order\n seen: set[str] = set()\n deduped: list[str] = []\n for c in columns:\n if c and c not in seen:\n deduped.append(c)\n seen.add(c)\n columns = deduped\n\n # Keys for the context JSON: context_columns + original translation_column\n context_keys = list(job.context_columns or [])\n if job.translation_column and job.translation_column != effective_target and job.translation_column not in context_keys:\n context_keys.append(job.translation_column)\n\n rows_for_sql: list[dict[str, object]] = []\n for rec in records:\n source_data = rec.source_data or {}\n\n # Detect source language from first TranslationLanguage entry\n detected_src_lang = \"und\"\n if rec.languages and len(rec.languages) > 0:\n detected_src_lang = rec.languages[0].source_language_detected or \"und\"\n\n # Build context JSON: all extra columns the user configured\n context_data: dict[str, str] = {}\n for key in context_keys:\n val = source_data.get(key)\n context_data[key] = str(val) if val is not None else \"\"\n\n # ── Shared base row ──\n base_row: dict[str, object] = {}\n\n if job.target_key_cols:\n for k in job.target_key_cols:\n raw = source_data.get(k)\n if raw is not None:\n normalized = _normalize_timestamp_value(raw)\n base_row[k] = normalized if normalized else raw\n else:\n base_row[k] = None\n\n if job.target_source_column:\n base_row[job.target_source_column] = rec.source_sql or \"\"\n\n if job.target_source_language_column:\n base_row[job.target_source_language_column] = detected_src_lang\n\n base_row[\"context\"] = json.dumps(context_data, ensure_ascii=False)\n\n # ── 1. ORIGINAL row (is_original = 1) ──\n original_row = dict(base_row)\n if effective_target:\n original_row[effective_target] = rec.source_sql or \"\"\n if job.target_language_column:\n original_row[job.target_language_column] = detected_src_lang\n original_row[\"is_original\"] = 1\n rows_for_sql.append(original_row)\n\n # ── 2. TRANSLATION rows (is_original = 0) ──\n # Skip language that matches the source — the original row already covers it\n if rec.languages and len(rec.languages) > 0:\n for lang in rec.languages:\n if lang.language_code == detected_src_lang:\n continue\n trans_row = dict(base_row)\n trans_value = lang.final_value or lang.translated_value or \"\"\n if effective_target:\n trans_row[effective_target] = trans_value\n if job.target_language_column:\n trans_row[job.target_language_column] = lang.language_code\n trans_row[\"is_original\"] = 0\n rows_for_sql.append(trans_row)\n else:\n # Fallback: no per-language data\n fallback_row = dict(base_row)\n if effective_target:\n fallback_row[effective_target] = rec.target_sql or \"\"\n if job.target_language_column:\n fallback_row[job.target_language_column] = primary_language\n fallback_row[\"is_original\"] = 0\n rows_for_sql.append(fallback_row)\n\n if not columns:\n columns = [effective_target or \"translated_text\"]\n rows_for_sql = [{columns[0]: rec.target_sql or \"\"} for rec in records]\n\n # Resolve the real database backend engine from Superset\n try:\n env_id = job.environment_id or job.source_dialect or \"\"\n executor = SupersetSqlLabExecutor(self.config_manager, env_id)\n executor.resolve_database_id(\n target_database_id=job.target_database_id,\n )\n real_backend = executor.get_database_backend()\n except Exception as e:\n logger.explore(\"Failed to resolve database backend, falling back to job dialet\", {\n \"error\": str(e),\n })\n real_backend = None\n\n dialect = real_backend or job.database_dialect or job.target_dialect or \"postgresql\"\n\n # Generate SQL\n try:\n sql, row_count = SQLGenerator.generate(\n dialect=dialect,\n target_schema=job.target_schema,\n target_table=job.target_table or \"translated_data\",\n columns=columns,\n rows=rows_for_sql,\n key_columns=job.target_key_cols,\n upsert_strategy=job.upsert_strategy or \"MERGE\",\n )\n except ValueError as e:\n logger.explore(\"SQL generation failed\", {\"error\": str(e)})\n return {\"status\": \"failed\", \"error_message\": str(e), \"query_id\": None}\n\n logger.reason(\"SQL generated with dialect\", {\n \"dialect\": dialect,\n \"real_backend\": real_backend,\n \"job_database_dialect\": job.database_dialect,\n \"job_target_dialect\": job.target_dialect,\n })\n\n # Log insert phase start\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=\"INSERT_PHASE_STARTED\",\n payload={\"sql_length\": len(sql), \"row_count\": row_count, \"dialect\": dialect},\n created_by=self.current_user,\n )\n\n # Submit to Superset\n try:\n result = executor.execute_and_poll(\n sql=sql,\n max_polls=30,\n poll_interval_seconds=2.0,\n )\n except Exception as e:\n logger.explore(\"Superset SQL submission failed\", {\n \"run_id\": run.id,\n \"error\": str(e),\n })\n result = {\"status\": \"failed\", \"error_message\": str(e), \"query_id\": None}\n\n # Log insert phase complete\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=\"INSERT_PHASE_COMPLETED\",\n payload=result,\n created_by=self.current_user,\n )\n\n return result\n # endregion _generate_and_insert_sql\n\n # region _validate_preconditions [TYPE Function]\n # @PURPOSE: Validate preconditions before starting a run.\n # @PRE: None.\n # @POST: Raises ValueError if preconditions are not met.\n # @SIDE_EFFECT: None.\n def _validate_preconditions(\n self,\n job: TranslationJob,\n is_scheduled: bool = False,\n ) -> None:\n with belief_scope(\"TranslationOrchestrator._validate_preconditions\"):\n # Job must be in valid status\n if job.status in (\"DRAFT\",):\n raise ValueError(\n f\"Cannot run job '{job.id}' in status '{job.status}'. \"\n f\"Job must be READY, ACTIVE, or COMPLETED.\"\n )\n\n # Must have target table configured\n if not job.target_table:\n raise ValueError(\n f\"Job '{job.id}' has no target table configured. \"\n \"Configure a target table before running.\"\n )\n\n # Must have LLM provider configured\n if not job.provider_id:\n raise ValueError(\n f\"Job '{job.id}' has no LLM provider configured. \"\n \"Select an LLM provider before running.\"\n )\n\n # Must have a translation column\n if not job.translation_column:\n raise ValueError(\n f\"Job '{job.id}' has no translation column configured. \"\n \"Select a translation column before running.\"\n )\n\n # For manual runs, must have accepted preview\n if not is_scheduled:\n accepted_session = (\n self.db.query(TranslationPreviewSession)\n .filter(\n TranslationPreviewSession.job_id == job.id,\n TranslationPreviewSession.status == \"APPLIED\",\n )\n .order_by(TranslationPreviewSession.created_at.desc())\n .first()\n )\n if not accepted_session:\n raise ValueError(\n f\"Job '{job.id}' has no accepted preview session. \"\n \"Run and accept a preview before executing a manual translation run.\"\n )\n\n logger.reason(\"Preconditions validated\", {\n \"job_id\": job.id,\n \"is_scheduled\": is_scheduled,\n })\n # endregion _validate_preconditions\n\n # region retry_failed_batches [TYPE Function]\n # @PURPOSE: Retry failed batches in a run.\n # @PRE: run exists and has failed batches.\n # @POST: Failed batches are re-processed.\n # @SIDE_EFFECT: LLM calls, DB writes.\n def retry_failed_batches(\n self,\n run_id: str,\n ) -> TranslationRun:\n with belief_scope(\"TranslationOrchestrator.retry_failed_batches\"):\n run = self.db.query(TranslationRun).filter(TranslationRun.id == run_id).first()\n if not run:\n raise ValueError(f\"Run '{run_id}' not found\")\n\n job = self.db.query(TranslationJob).filter(TranslationJob.id == run.job_id).first()\n if not job:\n raise ValueError(f\"Job '{run.job_id}' not found\")\n self._job = job\n\n # Find failed batches\n failed_batches = (\n self.db.query(TranslationBatch)\n .filter(\n TranslationBatch.run_id == run_id,\n TranslationBatch.status.in_([\"FAILED\", \"COMPLETED_WITH_ERRORS\"]),\n )\n .all()\n )\n\n if not failed_batches:\n raise ValueError(f\"No failed batches found for run '{run_id}'\")\n\n logger.reason(\"Retrying failed batches\", {\n \"run_id\": run_id,\n \"batch_count\": len(failed_batches),\n })\n\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=\"RUN_RETRYING\",\n payload={\"batch_count\": len(failed_batches)},\n created_by=self.current_user,\n )\n\n # Re-process each failed batch\n executor = TranslationExecutor(self.db, self.config_manager, self.current_user)\n run.status = \"RUNNING\"\n self.db.flush()\n\n for batch in failed_batches:\n # Fetch failed records for this batch\n failed_records = (\n self.db.query(TranslationRecord)\n .filter(\n TranslationRecord.batch_id == batch.id,\n TranslationRecord.status == \"FAILED\",\n )\n .all()\n )\n\n if not failed_records:\n continue\n\n # Build rows from failed records\n retry_rows = []\n for rec in failed_records:\n retry_rows.append({\n \"row_index\": rec.source_object_id or \"0\",\n \"source_text\": rec.source_sql or \"\",\n \"approved_translation\": None,\n \"source_object_name\": rec.source_object_name or \"\",\n })\n\n # Process retry batch\n result = executor._process_batch(\n job=job,\n run_id=run_id,\n batch_index=batch.batch_index,\n batch_rows=retry_rows,\n )\n\n # Update run stats\n run.successful_records = (run.successful_records or 0) + result[\"successful\"]\n run.failed_records = (run.failed_records or 0) + result[\"failed\"]\n run.skipped_records = (run.skipped_records or 0) + result[\"skipped\"]\n self.db.flush()\n\n # Update run status\n if run.failed_records == 0:\n run.status = \"COMPLETED\"\n elif run.successful_records == 0:\n run.status = \"FAILED\"\n else:\n run.status = \"COMPLETED\"\n\n run.completed_at = datetime.now(UTC)\n self.db.flush()\n\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=\"RUN_COMPLETED\",\n payload={\"retry\": True},\n created_by=self.current_user,\n )\n\n self.db.commit()\n logger.reflect(\"Retry complete\", {\n \"run_id\": run_id,\n \"status\": run.status,\n })\n return run\n # endregion retry_failed_batches\n\n # region retry_insert [TYPE Function]\n # @PURPOSE: Retry the SQL insert phase for a completed run.\n # @PRE: run exists and has successful records.\n # @POST: SQL is regenerated and re-submitted to Superset.\n # @SIDE_EFFECT: Superset API call.\n def retry_insert(\n self,\n run_id: str,\n ) -> TranslationRun:\n with belief_scope(\"TranslationOrchestrator.retry_insert\"):\n run = self.db.query(TranslationRun).filter(TranslationRun.id == run_id).first()\n if not run:\n raise ValueError(f\"Run '{run_id}' not found\")\n\n job = self.db.query(TranslationJob).filter(TranslationJob.id == run.job_id).first()\n if not job:\n raise ValueError(f\"Job '{run.job_id}' not found\")\n self._job = job\n\n logger.reason(\"Retrying insert phase\", {\n \"run_id\": run_id,\n })\n\n self.event_log.log_event(\n job_id=job.id,\n run_id=run.id,\n event_type=\"RUN_RETRY_INSERT\",\n payload={},\n created_by=self.current_user,\n )\n\n # Regenerate SQL and submit\n insert_result = self._generate_and_insert_sql(job, run)\n\n # Update run\n run.insert_status = insert_result.get(\"status\")\n run.superset_execution_id = str(insert_result.get(\"query_id\") or \"\")\n if insert_result.get(\"error_message\"):\n run.error_message = insert_result[\"error_message\"]\n self.db.flush()\n self.db.commit()\n self.db.refresh(run)\n\n logger.reflect(\"Insert retry complete\", {\n \"run_id\": run_id,\n \"insert_status\": run.insert_status,\n })\n return run\n # endregion retry_insert\n\n # region cancel_run [TYPE Function]\n # @PURPOSE: Cancel a running translation.\n # @PRE: run is in PENDING or RUNNING status.\n # @POST: Run status is set to CANCELLED.\n # @SIDE_EFFECT: DB write; records event.\n def cancel_run(self, run_id: str) -> TranslationRun:\n with belief_scope(\"TranslationOrchestrator.cancel_run\"):\n # Set short lock timeout to avoid blocking on row lock held by\n # background executor thread (which holds RowExclusiveLock during\n # batch processing). If the row is locked, we fall back to setting\n # a cancellation flag via direct SQL UPDATE, which the executor\n # checks after each batch commit.\n try:\n self.db.execute(text(\"SET LOCAL lock_timeout = '3s'\"))\n run = self.db.query(TranslationRun).filter(TranslationRun.id == run_id).first()\n except Exception:\n # Row is locked — set cancellation flag via direct SQL\n logger.explore(\"Row lock timeout — setting cancellation flag via direct SQL\", {\n \"run_id\": run_id,\n })\n self.db.execute(\n text(\"UPDATE translation_runs SET error_message = 'CANCEL_REQUESTED' WHERE id = :run_id\"),\n {\"run_id\": run_id},\n )\n self.db.commit()\n run = self.db.query(TranslationRun).filter(TranslationRun.id == run_id).first()\n if not run:\n raise ValueError(f\"Run '{run_id}' not found\")\n logger.reflect(\"Cancellation flag set for locked run\", {\n \"run_id\": run_id,\n })\n return run\n\n if not run:\n raise ValueError(f\"Run '{run_id}' not found\")\n\n if run.status not in (\"PENDING\", \"RUNNING\"):\n raise ValueError(\n f\"Cannot cancel run in status '{run.status}'. \"\n f\"Only PENDING or RUNNING runs can be cancelled.\"\n )\n\n run.status = \"CANCELLED\"\n run.completed_at = datetime.now(UTC)\n self.db.flush()\n\n self.event_log.log_event(\n job_id=run.job_id,\n run_id=run.id,\n event_type=\"RUN_CANCELLED\",\n payload={},\n created_by=self.current_user,\n )\n\n self.db.commit()\n self.db.refresh(run)\n\n logger.reflect(\"Run cancelled\", {\n \"run_id\": run_id,\n })\n return run\n # endregion cancel_run\n\n # region get_run_status [TYPE Function]\n # @PURPOSE: Get run status with statistics.\n # @PRE: run_id exists.\n # @POST: Returns dict with run details.\n def get_run_status(self, run_id: str) -> dict[str, Any]:\n with belief_scope(\"TranslationOrchestrator.get_run_status\"):\n run = self.db.query(TranslationRun).filter(TranslationRun.id == run_id).first()\n if not run:\n raise ValueError(f\"Run '{run_id}' not found\")\n\n # Count batches\n batch_count = (\n self.db.query(TranslationBatch)\n .filter(TranslationBatch.run_id == run_id)\n .count()\n )\n\n # Get event summary\n event_summary = self.event_log.get_run_event_summary(run_id)\n\n # Get language stats\n language_stats_entries = (\n self.db.query(TranslationRunLanguageStats)\n .filter(TranslationRunLanguageStats.run_id == run_id)\n .all()\n )\n language_stats = [\n {\n \"language_code\": ls.language_code,\n \"total_rows\": ls.total_rows or 0,\n \"translated_rows\": ls.translated_rows or 0,\n \"failed_rows\": ls.failed_rows or 0,\n \"skipped_rows\": ls.skipped_rows or 0,\n \"token_count\": ls.token_count or 0,\n \"estimated_cost\": ls.estimated_cost or 0.0,\n }\n for ls in language_stats_entries\n ]\n\n return {\n \"id\": run.id,\n \"job_id\": run.job_id,\n \"status\": run.status,\n \"trigger_type\": run.trigger_type,\n \"started_at\": run.started_at.isoformat() if run.started_at else None,\n \"completed_at\": run.completed_at.isoformat() if run.completed_at else None,\n \"error_message\": run.error_message,\n \"total_records\": run.total_records or 0,\n \"successful_records\": run.successful_records or 0,\n \"failed_records\": run.failed_records or 0,\n \"skipped_records\": run.skipped_records or 0,\n \"insert_status\": run.insert_status,\n \"superset_execution_id\": run.superset_execution_id,\n \"batch_count\": batch_count,\n \"language_stats\": language_stats,\n \"event_invariants\": {\n \"has_run_started\": event_summary[\"has_run_started\"],\n \"terminal_event_count\": event_summary[\"terminal_event_count\"],\n \"invariant_valid\": event_summary[\"invariant_valid\"],\n },\n \"created_by\": run.created_by,\n \"created_at\": run.created_at.isoformat() if run.created_at else None,\n }\n # endregion get_run_status\n\n # region get_run_records [TYPE Function]\n # @PURPOSE: Get paginated records for a run.\n # @PRE: run_id exists.\n # @POST: Returns dict with records and pagination info.\n def get_run_records(\n self,\n run_id: str,\n page: int = 1,\n page_size: int = 50,\n status_filter: str | None = None,\n ) -> dict[str, Any]:\n with belief_scope(\"TranslationOrchestrator.get_run_records\"):\n query = (\n self.db.query(TranslationRecord)\n .options(selectinload(TranslationRecord.languages))\n .filter(TranslationRecord.run_id == run_id)\n )\n\n if status_filter:\n query = query.filter(TranslationRecord.status == status_filter)\n\n total = query.count()\n offset = (page - 1) * page_size\n records = (\n query.order_by(TranslationRecord.created_at.desc())\n .offset(offset)\n .limit(page_size)\n .all()\n )\n\n return {\n \"items\": [\n {\n \"id\": r.id,\n \"batch_id\": r.batch_id,\n \"source_sql\": r.source_sql,\n \"target_sql\": r.target_sql,\n \"source_object_type\": r.source_object_type,\n \"source_object_id\": r.source_object_id,\n \"source_object_name\": r.source_object_name,\n \"status\": r.status,\n \"error_message\": r.error_message,\n \"created_at\": r.created_at.isoformat() if r.created_at else None,\n \"languages\": [\n {\n \"language_code\": tl.language_code,\n \"translated_value\": tl.translated_value,\n \"final_value\": tl.final_value or tl.translated_value,\n \"source_language_detected\": tl.source_language_detected,\n \"status\": tl.status,\n \"needs_review\": tl.needs_review or False,\n }\n for tl in (r.languages or [])\n ],\n }\n for r in records\n ],\n \"total\": total,\n \"page\": page,\n \"page_size\": page_size,\n \"status_filter\": status_filter,\n }\n # endregion get_run_records\n\n # region get_run_history [TYPE Function]\n # @PURPOSE: Get run history for a job.\n # @PRE: job_id exists.\n # @POST: Returns list of runs.\n def get_run_history(\n self,\n job_id: str,\n page: int = 1,\n page_size: int = 20,\n ) -> tuple[int, list[dict[str, Any]]]:\n with belief_scope(\"TranslationOrchestrator.get_run_history\"):\n query = self.db.query(TranslationRun).filter(\n TranslationRun.job_id == job_id\n )\n total = query.count()\n runs = (\n query.order_by(TranslationRun.created_at.desc())\n .offset((page - 1) * page_size)\n .limit(page_size)\n .all()\n )\n\n return total, [\n {\n \"id\": r.id,\n \"job_id\": r.job_id,\n \"status\": r.status,\n \"started_at\": r.started_at.isoformat() if r.started_at else None,\n \"completed_at\": r.completed_at.isoformat() if r.completed_at else None,\n \"error_message\": r.error_message,\n \"total_records\": r.total_records or 0,\n \"successful_records\": r.successful_records or 0,\n \"failed_records\": r.failed_records or 0,\n \"skipped_records\": r.skipped_records or 0,\n \"insert_status\": r.insert_status,\n \"superset_execution_id\": r.superset_execution_id,\n \"created_by\": r.created_by,\n \"created_at\": r.created_at.isoformat() if r.created_at else None,\n }\n for r in runs\n ]\n # endregion get_run_history\n\n # region _update_language_stats [TYPE Function]\n # @PURPOSE: Aggregate TranslationLanguage entries by language_code and update TranslationRunLanguageStats.\n # @PRE: run_id and language_stats_map are valid. DB session is available.\n # @POST: Language stats are updated with row counts and estimated tokens/cost.\n # @SIDE_EFFECT: DB writes on language_stats objects.\n def _update_language_stats(\n self,\n run_id: str,\n language_stats_map: dict[str, TranslationRunLanguageStats],\n ) -> None:\n with belief_scope(\"TranslationOrchestrator._update_language_stats\"):\n # Get all records for this run to join with TranslationLanguage\n records = (\n self.db.query(TranslationRecord)\n .filter(TranslationRecord.run_id == run_id)\n .all()\n )\n record_ids = [r.id for r in records]\n\n if not record_ids:\n logger.reason(\"No records for language stats aggregation\", {\"run_id\": run_id})\n return\n\n # Get all language entries for this run's records\n lang_entries = (\n self.db.query(TranslationLanguage)\n .filter(TranslationLanguage.record_id.in_(record_ids))\n .all()\n )\n\n # Aggregate by language_code\n from collections import defaultdict\n agg: dict[str, dict[str, int]] = defaultdict(lambda: {\"total\": 0, \"translated\": 0, \"failed\": 0, \"skipped\": 0})\n\n for le in lang_entries:\n code = le.language_code\n agg[code][\"total\"] += 1\n if le.status in (\"translated\", \"approved\", \"edited\"):\n agg[code][\"translated\"] += 1\n elif le.status == \"failed\":\n agg[code][\"failed\"] += 1\n elif le.status == \"skipped\":\n agg[code][\"skipped\"] += 1\n\n # Estimate tokens: heuristic based on character count of translated values\n total_chars = sum(\n len(le.translated_value or \"\") for le in lang_entries if le.translated_value\n )\n total_tokens = max(1, total_chars // 4) # ~4 chars per token\n cost_per_token = 0.002 / 1000 # $0.002 per 1K tokens\n\n # Update each language stat entry\n for lang_code, lang_stat in language_stats_map.items():\n data = agg.get(lang_code, {\"total\": 0, \"translated\": 0, \"failed\": 0, \"skipped\": 0})\n lang_stat.total_rows = data[\"total\"]\n lang_stat.translated_rows = data[\"translated\"]\n lang_stat.failed_rows = data[\"failed\"]\n lang_stat.skipped_rows = data[\"skipped\"]\n\n # Proportional token split: share tokens across languages\n num_langs = len(language_stats_map)\n if num_langs > 0:\n lang_stat.token_count = total_tokens // num_langs\n lang_stat.estimated_cost = round((lang_stat.token_count / 1000) * cost_per_token, 6)\n\n self.db.flush()\n\n logger.reason(\"Language stats updated\", {\n \"run_id\": run_id,\n \"languages\": list(language_stats_map.keys()),\n \"total_tokens_est\": total_tokens,\n })\n # endregion _update_language_stats\n\n # region _compute_config_hash [TYPE Function]\n # @PURPOSE: Compute a hash of the job's current configuration for snapshot comparison.\n @staticmethod\n def _compute_config_hash(job: TranslationJob) -> str:\n import hashlib\n config_str = json.dumps({\n \"source_dialect\": job.source_dialect,\n \"target_dialect\": job.target_dialect,\n \"source_datasource_id\": job.source_datasource_id,\n \"translation_column\": job.translation_column,\n \"context_columns\": job.context_columns,\n \"target_languages\": sorted(job.target_languages) if job.target_languages else [],\n \"provider_id\": job.provider_id,\n \"batch_size\": job.batch_size,\n \"upsert_strategy\": job.upsert_strategy,\n }, sort_keys=True)\n return hashlib.sha256(config_str.encode()).hexdigest()[:16]\n # endregion _compute_config_hash\n\n # region _compute_dict_snapshot_hash [TYPE Function]\n # @PURPOSE: Compute a hash of dictionary state for snapshot comparison.\n def _compute_dict_snapshot_hash(self, job_id: str) -> str:\n import hashlib\n\n from ...models.translate import TranslationJobDictionary\n dict_links = (\n self.db.query(TranslationJobDictionary)\n .filter(TranslationJobDictionary.job_id == job_id)\n .all()\n )\n dict_ids = sorted([dl.dictionary_id for dl in dict_links])\n hash_input = \",\".join(dict_ids)\n return hashlib.sha256(hash_input.encode()).hexdigest()[:16]\n # endregion _compute_dict_snapshot_hash\n\n# #endregion TranslationOrchestrator\n" }, { "contract_id": "TranslatePlugin", @@ -50071,104 +49410,44 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslatePlugin [C:2] [TYPE Module] [SEMANTICS clickhouse, translate, sql, dashboard, dialect]\n# @BRIEF TranslatePlugin skeleton for cross-dialect SQL and dashboard translation.\n# @LAYER: Domain\n# @RELATION INHERITS -> [PluginBase]\n# @RATIONALE: Separate plugin avoids bloating LLMAnalysisPlugin beyond fractal limit (<400 lines).\n# @REJECTED: Extending LLMAnalysisPlugin would conflate two distinct feature domains.\n\nfrom typing import Any\n\nfrom ...core.plugin_base import PluginBase\n\n\n# #region TranslatePlugin [TYPE Class]\n# @BRIEF Plugin for translating SQL queries and dashboard definitions across database dialects.\n# @RELATION IMPLEMENTS -> backend.src.core.plugin_base.PluginBase\nclass TranslatePlugin(PluginBase):\n @property\n def id(self) -> str:\n return \"translate\"\n\n @property\n def name(self) -> str:\n return \"LLM Table Translation\"\n\n @property\n def description(self) -> str:\n return \"Cross-dialect SQL and dashboard translation using LLMs.\"\n\n @property\n def version(self) -> str:\n return \"1.0.0\"\n\n def get_schema(self) -> dict[str, Any]:\n return {\n \"type\": \"object\",\n \"properties\": {\n \"source_dialect\": {\n \"type\": \"string\",\n \"title\": \"Source Dialect\",\n \"description\": \"Source database dialect (e.g. PostgreSQL, ClickHouse)\",\n },\n \"target_dialect\": {\n \"type\": \"string\",\n \"title\": \"Target Dialect\",\n \"description\": \"Target database dialect (e.g. PostgreSQL, ClickHouse)\",\n },\n \"job_id\": {\n \"type\": \"string\",\n \"title\": \"Translation Job ID\",\n \"description\": \"Existing translation job to execute\",\n },\n },\n \"required\": [\"job_id\"],\n }\n\n async def execute(self, params: dict[str, Any], context: Any | None = None):\n \"\"\"Execute a translation job — implementation deferred to later phases.\"\"\"\n raise NotImplementedError(\"TranslatePlugin.execute not yet implemented\")\n# #endregion TranslatePlugin\n\n# #endregion TranslatePlugin\n" + "body": "# #region TranslatePlugin [C:2] [TYPE Module] [SEMANTICS clickhouse, translate, sql, dashboard, dialect]\n# @BRIEF TranslatePlugin skeleton for cross-dialect SQL and dashboard translation.\n# @LAYER Domain\n# @RELATION INHERITS -> [PluginBase]\n# @RATIONALE Separate plugin avoids bloating LLMAnalysisPlugin beyond fractal limit (<400 lines).\n# @REJECTED Extending LLMAnalysisPlugin would conflate two distinct feature domains.\n\nfrom typing import Any\n\nfrom ...core.plugin_base import PluginBase\n\n\n# #region TranslatePlugin [TYPE Class]\n# @BRIEF Plugin for translating SQL queries and dashboard definitions across database dialects.\n# @RELATION IMPLEMENTS -> backend.src.core.plugin_base.PluginBase\nclass TranslatePlugin(PluginBase):\n @property\n def id(self) -> str:\n return \"translate\"\n\n @property\n def name(self) -> str:\n return \"LLM Table Translation\"\n\n @property\n def description(self) -> str:\n return \"Cross-dialect SQL and dashboard translation using LLMs.\"\n\n @property\n def version(self) -> str:\n return \"1.0.0\"\n\n def get_schema(self) -> dict[str, Any]:\n return {\n \"type\": \"object\",\n \"properties\": {\n \"source_dialect\": {\n \"type\": \"string\",\n \"title\": \"Source Dialect\",\n \"description\": \"Source database dialect (e.g. PostgreSQL, ClickHouse)\",\n },\n \"target_dialect\": {\n \"type\": \"string\",\n \"title\": \"Target Dialect\",\n \"description\": \"Target database dialect (e.g. PostgreSQL, ClickHouse)\",\n },\n \"job_id\": {\n \"type\": \"string\",\n \"title\": \"Translation Job ID\",\n \"description\": \"Existing translation job to execute\",\n },\n },\n \"required\": [\"job_id\"],\n }\n\n async def execute(self, params: dict[str, Any], context: Any | None = None):\n \"\"\"Execute a translation job — implementation deferred to later phases.\"\"\"\n raise NotImplementedError(\"TranslatePlugin.execute not yet implemented\")\n# #endregion TranslatePlugin\n\n# #endregion TranslatePlugin\n" }, { "contract_id": "DEFAULT_EXECUTION_PROMPT_TEMPLATE", "contract_type": "Constant", "file_path": "backend/src/plugins/translate/preview.py", "start_line": 43, - "end_line": 60, + "end_line": 64, "tier": "TIER_1", "complexity": 1, - "metadata": { - "PURPOSE": "Default prompt template for batch LLM translation execution (no context columns — faster)." - }, + "metadata": {}, "relations": [], - "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "PURPOSE", - "message": "@PURPOSE is not allowed for contract type 'Constant'", - "detail": { - "actual_type": "Constant", - "allowed_types": [ - "Module", - "Function", - "Class", - "Component", - "Block", - "ADR", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PURPOSE", - "message": "@PURPOSE is forbidden for contract type 'Constant' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Constant" - } - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region DEFAULT_EXECUTION_PROMPT_TEMPLATE [TYPE Constant]\n# @BRIEF Default prompt template for batch LLM translation execution (no context columns — faster).\n# Supports both single-language and multi-language modes via {target_languages} placeholder.\nDEFAULT_EXECUTION_PROMPT_TEMPLATE: str = (\n \"Translate the following database content from {source_language} to the following language(s): {target_languages}.\\n\\n\"\n \"Source dialect: {source_dialect}\\n\"\n \"Target dialect(s): {target_dialect}\\n\"\n \"Column to translate: {translation_column}\\n\\n\"\n \"{dictionary_section}\"\n \"For each row, provide an accurate translation of the text into each target language.\\n\\n\"\n \"Rows to translate:\\n{rows_json}\\n\\n\"\n \"Respond with a JSON object in this exact format:\\n\"\n '{{\"rows\": [{{\"row_id\": \"\", \"detected_source_language\": \"\", \"\": \"\", \"\": \"\"}}]}}\\n'\n \"For each row, return the detected source language as a BCP-47 tag (e.g. 'en', 'ru', 'fr'), or 'und' if uncertain.\\n\"\n \"Include a separate key for EACH target language code with the translated text in that language.\\n\"\n \"Each row_id must match the index provided. Return exactly {row_count} entries.\"\n)\n# #endregion DEFAULT_EXECUTION_PROMPT_TEMPLATE\n" + "body": "# #region DEFAULT_EXECUTION_PROMPT_TEMPLATE [TYPE Constant]\n\n# Supports both single-language and multi-language modes via {target_languages} placeholder.\nDEFAULT_EXECUTION_PROMPT_TEMPLATE: str = (\n \"Translate the following database content from {source_language} to the following language(s): {target_languages}.\\n\\n\"\n \"Source dialect: {source_dialect}\\n\"\n \"Target dialect(s): {target_dialect}\\n\"\n \"Column to translate: {translation_column}\\n\\n\"\n \"{dictionary_section}\"\n \"IMPORTANT — You MUST use the terminology dictionary above. \"\n \"For any source term listed in the dictionary, you MUST use its exact target translation. \"\n \"Do not translate dictionary terms differently. \"\n \"This is mandatory, not optional.\\n\\n\"\n \"For each row, provide an accurate translation of the text into each target language.\\n\\n\"\n \"Rows to translate:\\n{rows_json}\\n\\n\"\n \"Respond with a JSON object in this exact format:\\n\"\n '{{\"rows\": [{{\"row_id\": \"\", \"detected_source_language\": \"\", \"\": \"\", \"\": \"\"}}]}}\\n'\n \"For each row, return the detected source language as a BCP-47 tag (e.g. 'en', 'ru', 'fr'), or 'und' if uncertain.\\n\"\n \"Include a separate key for EACH target language code with the translated text in that language.\\n\"\n \"Each row_id must match the index provided. Return exactly {row_count} entries.\"\n)\n# #endregion DEFAULT_EXECUTION_PROMPT_TEMPLATE\n" }, { "contract_id": "DEFAULT_PREVIEW_PROMPT_TEMPLATE", "contract_type": "Constant", "file_path": "backend/src/plugins/translate/preview.py", - "start_line": 63, - "end_line": 80, + "start_line": 67, + "end_line": 88, "tier": "TIER_1", "complexity": 1, - "metadata": { - "PURPOSE": "Default prompt template for LLM translation preview." - }, + "metadata": {}, "relations": [], - "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "PURPOSE", - "message": "@PURPOSE is not allowed for contract type 'Constant'", - "detail": { - "actual_type": "Constant", - "allowed_types": [ - "Module", - "Function", - "Class", - "Component", - "Block", - "ADR", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PURPOSE", - "message": "@PURPOSE is forbidden for contract type 'Constant' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Constant" - } - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region DEFAULT_PREVIEW_PROMPT_TEMPLATE [TYPE Constant]\n# @BRIEF Default prompt template for LLM translation preview.\nDEFAULT_PREVIEW_PROMPT_TEMPLATE: str = (\n \"Translate the following database content.\\n\\n\"\n \"Source dialect: {source_dialect}\\n\"\n \"Column to translate: {translation_column}\\n\\n\"\n \"{dictionary_section}\"\n \"Translate to the following languages: {target_languages}\\n\\n\"\n \"For each row, provide an accurate translation of the '{translation_column}' value into each language.\\n\"\n \"Consider the context columns when determining the meaning of the text.\\n\\n\"\n \"Rows to translate:\\n{rows_json}\\n\\n\"\n \"Respond with a JSON object in this exact format:\\n\"\n '{{\"rows\": [{{\"row_id\": \"\", \"detected_source_language\": \"\", \"language_code_1\": \"\", \"language_code_2\": \"\"}}]}}\\n'\n \"For each row, return the detected source language as a BCP-47 tag (e.g. 'en', 'ru', 'fr'), or 'und' if uncertain.\\n\"\n \"Include a separate key for EACH target language code with the translated text in that language.\\n\"\n \"Each row_id must match the index provided. Return exactly {row_count} entries.\"\n)\n# #endregion DEFAULT_PREVIEW_PROMPT_TEMPLATE\n" + "body": "# #region DEFAULT_PREVIEW_PROMPT_TEMPLATE [TYPE Constant]\n\nDEFAULT_PREVIEW_PROMPT_TEMPLATE: str = (\n \"Translate the following database content.\\n\\n\"\n \"Source dialect: {source_dialect}\\n\"\n \"Column to translate: {translation_column}\\n\\n\"\n \"{dictionary_section}\"\n \"IMPORTANT — You MUST use the terminology dictionary above. \"\n \"For any source term listed in the dictionary, you MUST use its exact target translation. \"\n \"Do not translate dictionary terms differently. \"\n \"This is mandatory, not optional.\\n\\n\"\n \"Translate to the following languages: {target_languages}\\n\\n\"\n \"For each row, provide an accurate translation of the '{translation_column}' value into each language.\\n\"\n \"Consider the context columns when determining the meaning of the text.\\n\\n\"\n \"Rows to translate:\\n{rows_json}\\n\\n\"\n \"Respond with a JSON object in this exact format:\\n\"\n '{{\"rows\": [{{\"row_id\": \"\", \"detected_source_language\": \"\", \"language_code_1\": \"\", \"language_code_2\": \"\"}}]}}\\n'\n \"For each row, return the detected source language as a BCP-47 tag (e.g. 'en', 'ru', 'fr'), or 'und' if uncertain.\\n\"\n \"Include a separate key for EACH target language code with the translated text in that language.\\n\"\n \"Each row_id must match the index provided. Return exactly {row_count} entries.\"\n)\n# #endregion DEFAULT_PREVIEW_PROMPT_TEMPLATE\n" }, { "contract_id": "TokenEstimator", "contract_type": "Class", "file_path": "backend/src/plugins/translate/preview.py", - "start_line": 83, - "end_line": 141, + "start_line": 91, + "end_line": 149, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -50180,14 +49459,14 @@ "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TokenEstimator [TYPE Class]\n# @BRIEF Estimate token counts and costs for LLM translation operations.\n# @RATIONALE: Token estimation uses a heuristic (chars/token ratio) since exact tokenization depends on the LLM model.\n# @REJECTED: Using an external tokenizer library would introduce a heavy dependency for estimation only.\nclass TokenEstimator:\n \"\"\"Estimate token counts and costs for LLM operations.\"\"\"\n\n CHARS_PER_TOKEN_ESTIMATE: float = 4.0\n OUTPUT_TOKENS_PER_ROW_ESTIMATE: int = 50\n MULTI_LANG_FACTOR: float = 1.2 # Overhead for multi-language in one call\n TOKEN_COST_PER_1K: float = 0.002 # Default cost per 1K tokens\n COST_WARNING_THRESHOLD: int = 30 # Show warning above this sample size\n\n # region estimate_prompt_tokens [TYPE Function]\n # @PURPOSE: Estimate token count for a prompt string.\n # @PRE: prompt is a non-empty string.\n # @POST: Returns estimated token count (integer).\n @staticmethod\n def estimate_prompt_tokens(prompt: str) -> int:\n if not prompt:\n return 0\n return max(1, int(len(prompt) / TokenEstimator.CHARS_PER_TOKEN_ESTIMATE))\n # endregion estimate_prompt_tokens\n\n # region estimate_output_tokens [TYPE Function]\n # @PURPOSE: Estimate output token count for translating N rows across N languages.\n # @PRE: row_count >= 0, num_languages >= 1.\n # @POST: Returns estimated output token count.\n @staticmethod\n def estimate_output_tokens(row_count: int, num_languages: int = 1) -> int:\n return int(row_count * num_languages * TokenEstimator.OUTPUT_TOKENS_PER_ROW_ESTIMATE * TokenEstimator.MULTI_LANG_FACTOR)\n # endregion estimate_output_tokens\n\n # region estimate_cost [TYPE Function]\n # @PURPOSE: Estimate cost for a given number of tokens.\n # @PRE: total_tokens >= 0.\n # @POST: Returns estimated cost in USD.\n @staticmethod\n def estimate_cost(total_tokens: int, cost_per_1k: float | None = None) -> float:\n rate = cost_per_1k if cost_per_1k is not None else TokenEstimator.TOKEN_COST_PER_1K\n return round((total_tokens / 1000) * rate, 6)\n # endregion estimate_cost\n\n # region check_cost_warning [TYPE Function]\n # @PURPOSE: Generate cost warning for large previews.\n # @PRE: sample_size > 0, num_languages >= 1.\n # @POST: Returns warning string or None.\n @staticmethod\n def check_cost_warning(sample_size: int, num_languages: int, estimated_tokens: int, estimated_cost: float) -> str | None:\n if sample_size > TokenEstimator.COST_WARNING_THRESHOLD:\n return (\n f\"Large preview — estimated {estimated_tokens} tokens, ~${estimated_cost:.4f} cost \"\n f\"(across {num_languages} languages)\"\n )\n return None\n # endregion check_cost_warning\n\n\n# #endregion TokenEstimator\n" + "body": "# #region TokenEstimator [TYPE Class]\n# @BRIEF Estimate token counts and costs for LLM translation operations.\n# @RATIONALE: Token estimation uses a heuristic (chars/token ratio) since exact tokenization depends on the LLM model.\n# @REJECTED: Using an external tokenizer library would introduce a heavy dependency for estimation only.\nclass TokenEstimator:\n \"\"\"Estimate token counts and costs for LLM operations.\"\"\"\n\n CHARS_PER_TOKEN_ESTIMATE: float = 2.2\n OUTPUT_TOKENS_PER_ROW_ESTIMATE: int = 120\n MULTI_LANG_FACTOR: float = 1.2 # Overhead for multi-language in one call\n TOKEN_COST_PER_1K: float = 0.002 # Default cost per 1K tokens\n COST_WARNING_THRESHOLD: int = 30 # Show warning above this sample size\n\n # region estimate_prompt_tokens [TYPE Function]\n # @PURPOSE: Estimate token count for a prompt string.\n # @PRE: prompt is a non-empty string.\n # @POST: Returns estimated token count (integer).\n @staticmethod\n def estimate_prompt_tokens(prompt: str) -> int:\n if not prompt:\n return 0\n return max(1, int(len(prompt) / TokenEstimator.CHARS_PER_TOKEN_ESTIMATE))\n # endregion estimate_prompt_tokens\n\n # region estimate_output_tokens [TYPE Function]\n # @PURPOSE: Estimate output token count for translating N rows across N languages.\n # @PRE: row_count >= 0, num_languages >= 1.\n # @POST: Returns estimated output token count.\n @staticmethod\n def estimate_output_tokens(row_count: int, num_languages: int = 1) -> int:\n return int(row_count * num_languages * TokenEstimator.OUTPUT_TOKENS_PER_ROW_ESTIMATE * TokenEstimator.MULTI_LANG_FACTOR)\n # endregion estimate_output_tokens\n\n # region estimate_cost [TYPE Function]\n # @PURPOSE: Estimate cost for a given number of tokens.\n # @PRE: total_tokens >= 0.\n # @POST: Returns estimated cost in USD.\n @staticmethod\n def estimate_cost(total_tokens: int, cost_per_1k: float | None = None) -> float:\n rate = cost_per_1k if cost_per_1k is not None else TokenEstimator.TOKEN_COST_PER_1K\n return round((total_tokens / 1000) * rate, 6)\n # endregion estimate_cost\n\n # region check_cost_warning [TYPE Function]\n # @PURPOSE: Generate cost warning for large previews.\n # @PRE: sample_size > 0, num_languages >= 1.\n # @POST: Returns warning string or None.\n @staticmethod\n def check_cost_warning(sample_size: int, num_languages: int, estimated_tokens: int, estimated_cost: float) -> str | None:\n if sample_size > TokenEstimator.COST_WARNING_THRESHOLD:\n return (\n f\"Large preview — estimated {estimated_tokens} tokens, ~${estimated_cost:.4f} cost \"\n f\"(across {num_languages} languages)\"\n )\n return None\n # endregion check_cost_warning\n\n\n# #endregion TokenEstimator\n" }, { "contract_id": "ContextAwarePromptBuilder", "contract_type": "Module", "file_path": "backend/src/plugins/translate/prompt_builder.py", "start_line": 1, - "end_line": 152, + "end_line": 153, "tier": "TIER_1", "complexity": 2, "metadata": { @@ -50218,14 +49497,14 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region ContextAwarePromptBuilder [C:2] [TYPE Module] [SEMANTICS translate, prompt, context, dictionary]\n# @BRIEF Pure-function prompt builder that enhances dictionary entries with context annotations.\n# @LAYER: Domain\n# @RELATION DEPENDS_ON -> [DictionaryEntry:Class]\n# @RATIONALE: Pure functions only — no I/O, no DB access. Separated from executor for testability.\n# @REJECTED: Embedding context inline in the executor would make it untestable without mocking DB.\n#\n# Typical workflow:\n# 1. Call build_context_entries(dictionary_entries, row_context) to get annotated, prioritized entries\n# 2. Each entry is rendered via render_entry() with optional priority flag\n# 3. Jaccard similarity >= 0.5 triggers priority flagging\n\nimport json\nfrom typing import Any\n\n# #region ContextAwarePromptBuilder [C:2] [TYPE Class]\n# @BRIEF Build LLM prompts with context-aware dictionary entries and similarity-based priority.\n\nclass ContextAwarePromptBuilder:\n \"\"\"Build LLM prompts with context-aware dictionary entries.\n\n Pure function — no I/O, no DB access.\n \"\"\"\n\n @staticmethod\n def render_entry(entry: Any, priority: bool = False, row_context: dict | None = None) -> str:\n \"\"\"Render a dictionary entry for the LLM prompt.\n\n Args:\n entry: DictionaryEntry-like object (must have source_term, target_term, has_context,\n context_data, usage_notes attrs or dict keys).\n priority: Whether this entry should be flagged as high priority.\n row_context: Optional row context dict (unused in rendering, kept for API symmetry).\n\n Returns:\n Rendered prompt line string.\n \"\"\"\n # Support both object attrs and dict access\n if isinstance(entry, dict):\n source_term = entry.get(\"source_term\", \"\")\n target_term = entry.get(\"target_term\", \"\")\n has_context = entry.get(\"has_context\", False)\n context_data = entry.get(\"context_data\")\n usage_notes = entry.get(\"usage_notes\")\n else:\n source_term = getattr(entry, \"source_term\", \"\")\n target_term = getattr(entry, \"target_term\", \"\")\n has_context = getattr(entry, \"has_context\", False)\n context_data = getattr(entry, \"context_data\", None)\n usage_notes = getattr(entry, \"usage_notes\", None)\n\n # Build base line\n line = f'\"{source_term}\" -> \"{target_term}\"'\n\n # Add context annotation if present\n if has_context and context_data:\n context_items = []\n if isinstance(context_data, dict):\n context_items = [f\"{k}={v}\" for k, v in context_data.items()]\n elif isinstance(context_data, str):\n try:\n parsed = json.loads(context_data)\n if isinstance(parsed, dict):\n context_items = [f\"{k}={v}\" for k, v in parsed.items()]\n else:\n context_items = [str(context_data)]\n except (json.JSONDecodeError, TypeError):\n context_items = [str(context_data)]\n\n context_str = \", \".join(context_items)\n\n # Truncate if too long (500 tokens ≈ 2000 chars)\n if len(context_str) > 2000:\n context_str = context_str[:1997] + \"...[truncated]\"\n\n line = f'\"{source_term}\" (context: {context_str}) -> \"{target_term}\"'\n\n # Add usage notes\n if usage_notes:\n notes = str(usage_notes)[:200] # cap at 200 chars\n line += f\" # Usage: {notes}\"\n\n # Add priority prefix\n if priority:\n line = f\"# PRIORITY (context match) — {line}\"\n\n return line\n\n @staticmethod\n def compute_context_similarity(entry_context: dict | None, row_context: dict | None) -> float:\n \"\"\"Jaccard similarity between entry context and row context. Returns 0.0-1.0.\n\n Compares the sets of lowercased string values from both contexts.\n Returns 1.0 for identical contexts, 0.0 for disjoint or missing.\n \"\"\"\n if not entry_context or not row_context:\n return 0.0\n\n entry_vals = set(str(v).lower() for v in entry_context.values() if v is not None)\n row_vals = set(str(v).lower() for v in row_context.values() if v is not None)\n\n if not entry_vals or not row_vals:\n return 0.0\n\n intersection = entry_vals & row_vals\n union = entry_vals | row_vals\n return len(intersection) / len(union)\n\n @staticmethod\n def build_context_entries(\n dictionary_entries: list[Any],\n row_context: dict | None = None,\n ) -> list[str]:\n \"\"\"Build prioritized dictionary entry list with context annotations.\n\n Args:\n dictionary_entries: List of DictionaryEntry-like objects or dicts.\n row_context: Optional dict of current row's context columns.\n\n Returns:\n List of rendered prompt strings, sorted with priority entries first.\n \"\"\"\n results: list[tuple[Any, bool]] = []\n\n for entry in dictionary_entries:\n priority = False\n if row_context:\n # Extract entry context_data\n if isinstance(entry, dict):\n entry_context = entry.get(\"context_data\")\n else:\n entry_context = getattr(entry, \"context_data\", None)\n\n if entry_context:\n similarity = ContextAwarePromptBuilder.compute_context_similarity(\n entry_context, row_context\n )\n priority = similarity >= 0.5\n\n results.append((entry, priority))\n\n # Sort: priority first, then non-priority\n results.sort(key=lambda x: (not x[1]))\n\n return [\n ContextAwarePromptBuilder.render_entry(entry, priority, row_context)\n for entry, priority in results\n ]\n# #endregion ContextAwarePromptBuilder\n\n\n# #endregion ContextAwarePromptBuilder\n" + "body": "# #region ContextAwarePromptBuilder [C:2] [TYPE Module] [SEMANTICS translate, prompt, context, dictionary]\n# @BRIEF Pure-function prompt builder that enhances dictionary entries with context annotations.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [DictionaryEntry:Class]\n# @RATIONALE Pure functions only — no I/O, no DB access. Separated from executor for testability.\n# @REJECTED Embedding context inline in the executor would make it untestable without mocking DB.\n\n#\n# Typical workflow:\n# 1. Call build_context_entries(dictionary_entries, row_context) to get annotated, prioritized entries\n# 2. Each entry is rendered via render_entry() with optional priority flag\n# 3. Jaccard similarity >= 0.5 triggers priority flagging\n\nimport json\nfrom typing import Any\n\n# #region ContextAwarePromptBuilder [C:2] [TYPE Class]\n# @BRIEF Build LLM prompts with context-aware dictionary entries and similarity-based priority.\n\nclass ContextAwarePromptBuilder:\n \"\"\"Build LLM prompts with context-aware dictionary entries.\n\n Pure function — no I/O, no DB access.\n \"\"\"\n\n @staticmethod\n def render_entry(entry: Any, priority: bool = False, row_context: dict | None = None) -> str:\n \"\"\"Render a dictionary entry for the LLM prompt.\n\n Args:\n entry: DictionaryEntry-like object (must have source_term, target_term, has_context,\n context_data, usage_notes attrs or dict keys).\n priority: Whether this entry should be flagged as high priority.\n row_context: Optional row context dict (unused in rendering, kept for API symmetry).\n\n Returns:\n Rendered prompt line string.\n \"\"\"\n # Support both object attrs and dict access\n if isinstance(entry, dict):\n source_term = entry.get(\"source_term\", \"\")\n target_term = entry.get(\"target_term\", \"\")\n has_context = entry.get(\"has_context\", False)\n context_data = entry.get(\"context_data\")\n usage_notes = entry.get(\"usage_notes\")\n else:\n source_term = getattr(entry, \"source_term\", \"\")\n target_term = getattr(entry, \"target_term\", \"\")\n has_context = getattr(entry, \"has_context\", False)\n context_data = getattr(entry, \"context_data\", None)\n usage_notes = getattr(entry, \"usage_notes\", None)\n\n # Build base line\n line = f'\"{source_term}\" -> \"{target_term}\"'\n\n # Add context annotation if present\n if has_context and context_data:\n context_items = []\n if isinstance(context_data, dict):\n context_items = [f\"{k}={v}\" for k, v in context_data.items()]\n elif isinstance(context_data, str):\n try:\n parsed = json.loads(context_data)\n if isinstance(parsed, dict):\n context_items = [f\"{k}={v}\" for k, v in parsed.items()]\n else:\n context_items = [str(context_data)]\n except (json.JSONDecodeError, TypeError):\n context_items = [str(context_data)]\n\n context_str = \", \".join(context_items)\n\n # Truncate if too long (500 tokens ≈ 2000 chars)\n if len(context_str) > 2000:\n context_str = context_str[:1997] + \"...[truncated]\"\n\n line = f'\"{source_term}\" (context: {context_str}) -> \"{target_term}\"'\n\n # Add usage notes\n if usage_notes:\n notes = str(usage_notes)[:200] # cap at 200 chars\n line += f\" # Usage: {notes}\"\n\n # Add priority prefix\n if priority:\n line = f\"# PRIORITY (context match) — {line}\"\n\n return line\n\n @staticmethod\n def compute_context_similarity(entry_context: dict | None, row_context: dict | None) -> float:\n \"\"\"Jaccard similarity between entry context and row context. Returns 0.0-1.0.\n\n Compares the sets of lowercased string values from both contexts.\n Returns 1.0 for identical contexts, 0.0 for disjoint or missing.\n \"\"\"\n if not entry_context or not row_context:\n return 0.0\n\n entry_vals = set(str(v).lower() for v in entry_context.values() if v is not None)\n row_vals = set(str(v).lower() for v in row_context.values() if v is not None)\n\n if not entry_vals or not row_vals:\n return 0.0\n\n intersection = entry_vals & row_vals\n union = entry_vals | row_vals\n return len(intersection) / len(union)\n\n @staticmethod\n def build_context_entries(\n dictionary_entries: list[Any],\n row_context: dict | None = None,\n ) -> list[str]:\n \"\"\"Build prioritized dictionary entry list with context annotations.\n\n Args:\n dictionary_entries: List of DictionaryEntry-like objects or dicts.\n row_context: Optional dict of current row's context columns.\n\n Returns:\n List of rendered prompt strings, sorted with priority entries first.\n \"\"\"\n results: list[tuple[Any, bool]] = []\n\n for entry in dictionary_entries:\n priority = False\n if row_context:\n # Extract entry context_data\n if isinstance(entry, dict):\n entry_context = entry.get(\"context_data\")\n else:\n entry_context = getattr(entry, \"context_data\", None)\n\n if entry_context:\n similarity = ContextAwarePromptBuilder.compute_context_similarity(\n entry_context, row_context\n )\n priority = similarity >= 0.5\n\n results.append((entry, priority))\n\n # Sort: priority first, then non-priority\n results.sort(key=lambda x: (not x[1]))\n\n return [\n ContextAwarePromptBuilder.render_entry(entry, priority, row_context)\n for entry, priority in results\n ]\n# #endregion ContextAwarePromptBuilder\n\n\n# #endregion ContextAwarePromptBuilder\n" }, { "contract_id": "TranslationScheduler", "contract_type": "Module", "file_path": "backend/src/plugins/translate/scheduler.py", "start_line": 1, - "end_line": 434, + "end_line": 436, "tier": "TIER_2", "complexity": 4, "metadata": { @@ -50267,17 +49546,18 @@ "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslationScheduler [C:4] [TYPE Module] [SEMANTICS sqlalchemy, translate, schedule, cron, job]\n# @BRIEF Manage TranslationSchedule rows and register them with core SchedulerService.\n# @LAYER: Domain\n# @RELATION DEPENDS_ON -> [TranslationSchedule:Class]\n# @RELATION DEPENDS_ON -> [SchedulerService:Class]\n# @RELATION DEPENDS_ON -> [TranslationOrchestrator:Class]\n# @RELATION DEPENDS_ON -> [TranslationEventLog:Class]\n# @PRE: Database session and SchedulerService are available.\n# @POST: TranslationSchedule CRUD persisted; APScheduler jobs registered/updated/removed.\n# @SIDE_EFFECT: Registers APScheduler jobs; runs translations on trigger; creates events.\n# @RATIONALE: Uses existing SchedulerService (APScheduler) to avoid creating a second scheduler instance.\n# @REJECTED: Separate scheduler instance would create resource contention.\n# @REJECTED: Polling-based approach — event-driven APScheduler is more precise.\n\nimport uuid\nfrom datetime import UTC, datetime, timedelta\n\nfrom sqlalchemy.orm import Session\n\nfrom ...core.config_manager import ConfigManager\nfrom ...core.cot_logger import seed_trace_id\nfrom ...core.logger import belief_scope, logger\nfrom ...models.translate import TranslationJob, TranslationRun, TranslationSchedule\nfrom ...services.notifications.service import NotificationService\nfrom .events import TranslationEventLog\n\n\n# #region TranslationScheduler [C:4] [TYPE Class]\n# @BRIEF CRUD for TranslationSchedule rows + APScheduler registration wrappers.\nclass TranslationScheduler:\n\n def __init__(self, db: Session, config_manager: ConfigManager, current_user: str | None = None):\n self.db = db\n self.config_manager = config_manager\n self.current_user = current_user\n self.event_log = TranslationEventLog(db)\n\n # region create_schedule [TYPE Function]\n # @PURPOSE: Create a new schedule for a job.\n # @PRE: job_id exists. cron_expression is valid.\n # @POST: TranslationSchedule row created.\n def create_schedule(\n self,\n job_id: str,\n cron_expression: str,\n timezone: str = \"UTC\",\n is_active: bool = True,\n execution_mode: str = \"full\",\n ) -> TranslationSchedule:\n with belief_scope(\"TranslationScheduler.create_schedule\"):\n # Verify job exists\n job = self.db.query(TranslationJob).filter(TranslationJob.id == job_id).first()\n if not job:\n raise ValueError(f\"Translation job '{job_id}' not found\")\n\n schedule = TranslationSchedule(\n id=str(uuid.uuid4()),\n job_id=job_id,\n cron_expression=cron_expression,\n timezone=timezone,\n is_active=is_active,\n execution_mode=execution_mode,\n created_by=self.current_user,\n )\n self.db.add(schedule)\n self.db.commit()\n self.db.refresh(schedule)\n\n self.event_log.log_event(\n job_id=job_id,\n event_type=\"SCHEDULE_CREATED\",\n payload={\n \"schedule_id\": schedule.id,\n \"cron_expression\": cron_expression,\n \"timezone\": timezone,\n },\n created_by=self.current_user,\n )\n\n logger.reflect(\"Schedule created\", {\"schedule_id\": schedule.id, \"job_id\": job_id})\n return schedule\n # endregion create_schedule\n\n # region update_schedule [TYPE Function]\n # @PURPOSE: Update an existing schedule.\n # @PRE: job_id has an existing schedule.\n # @POST: Schedule updated.\n def update_schedule(\n self,\n job_id: str,\n cron_expression: str | None = None,\n timezone_str: str | None = None,\n is_active: bool | None = None,\n execution_mode: str | None = None,\n ) -> TranslationSchedule:\n with belief_scope(\"TranslationScheduler.update_schedule\"):\n schedule = self.db.query(TranslationSchedule).filter(\n TranslationSchedule.job_id == job_id\n ).first()\n if not schedule:\n raise ValueError(f\"No schedule found for job '{job_id}'\")\n\n if cron_expression is not None:\n schedule.cron_expression = cron_expression\n if timezone_str is not None:\n schedule.timezone = timezone_str\n if is_active is not None:\n schedule.is_active = is_active\n if execution_mode is not None:\n schedule.execution_mode = execution_mode\n schedule.updated_at = datetime.now(UTC)\n self.db.commit()\n self.db.refresh(schedule)\n\n self.event_log.log_event(\n job_id=job_id,\n event_type=\"SCHEDULE_UPDATED\",\n payload={\n \"schedule_id\": schedule.id,\n \"cron_expression\": schedule.cron_expression,\n \"timezone\": schedule.timezone,\n \"is_active\": schedule.is_active,\n },\n created_by=self.current_user,\n )\n\n logger.reflect(\"Schedule updated\", {\"schedule_id\": schedule.id, \"job_id\": job_id})\n return schedule\n # endregion update_schedule\n\n # region delete_schedule [TYPE Function]\n # @PURPOSE: Delete a schedule for a job.\n # @PRE: job_id has an existing schedule.\n # @POST: Schedule deleted.\n def delete_schedule(self, job_id: str) -> None:\n with belief_scope(\"TranslationScheduler.delete_schedule\"):\n schedule = self.db.query(TranslationSchedule).filter(\n TranslationSchedule.job_id == job_id\n ).first()\n if not schedule:\n raise ValueError(f\"No schedule found for job '{job_id}'\")\n\n schedule_id = schedule.id\n self.db.delete(schedule)\n self.db.commit()\n\n self.event_log.log_event(\n job_id=job_id,\n event_type=\"SCHEDULE_DELETED\",\n payload={\"schedule_id\": schedule_id},\n created_by=self.current_user,\n )\n\n logger.reflect(\"Schedule deleted\", {\"schedule_id\": schedule_id, \"job_id\": job_id})\n # endregion delete_schedule\n\n # region enable_disable_schedule [TYPE Function]\n # @PURPOSE: Enable or disable a schedule.\n # @PRE: job_id has an existing schedule.\n # @POST: Schedule is_active updated.\n def set_schedule_active(self, job_id: str, is_active: bool) -> TranslationSchedule:\n with belief_scope(\"TranslationScheduler.set_schedule_active\"):\n schedule = self.db.query(TranslationSchedule).filter(\n TranslationSchedule.job_id == job_id\n ).first()\n if not schedule:\n raise ValueError(f\"No schedule found for job '{job_id}'\")\n\n schedule.is_active = is_active\n schedule.updated_at = datetime.now(UTC)\n self.db.commit()\n self.db.refresh(schedule)\n\n logger.reflect(\"Schedule active state set\", {\n \"schedule_id\": schedule.id,\n \"job_id\": job_id,\n \"is_active\": is_active,\n })\n return schedule\n # endregion enable_disable_schedule\n\n # region get_schedule [TYPE Function]\n # @PURPOSE: Get schedule for a job.\n # @PRE: job_id exists.\n # @POST: Returns TranslationSchedule or raises ValueError.\n def get_schedule(self, job_id: str) -> TranslationSchedule:\n with belief_scope(\"TranslationScheduler.get_schedule\"):\n schedule = self.db.query(TranslationSchedule).filter(\n TranslationSchedule.job_id == job_id\n ).first()\n if not schedule:\n raise ValueError(f\"No schedule found for job '{job_id}'\")\n return schedule\n # endregion get_schedule\n\n # region list_active_schedules [TYPE Function]\n # @PURPOSE: List all active schedules.\n # @POST: Returns list of active TranslationSchedule rows.\n @staticmethod\n def list_active_schedules(db: Session) -> list[TranslationSchedule]:\n return (\n db.query(TranslationSchedule)\n .filter(TranslationSchedule.is_active)\n .all()\n )\n # endregion list_active_schedules\n\n # region get_next_executions [TYPE Function]\n # @PURPOSE: Compute next N execution times from cron expression.\n # @PRE: cron_expression is valid.\n # @POST: Returns list of ISO datetime strings.\n @staticmethod\n def get_next_executions(cron_expression: str, timezone_str: str = \"UTC\", n: int = 3) -> list[str]:\n from zoneinfo import ZoneInfo\n\n from apscheduler.triggers.cron import CronTrigger\n\n try:\n tz = ZoneInfo(timezone_str)\n trigger = CronTrigger.from_crontab(cron_expression, timezone=tz)\n except (ValueError, KeyError) as e:\n logger.warning(f\"[get_next_executions] Invalid cron: {e}\")\n return []\n\n now = datetime.now(tz)\n results = []\n next_time = now\n prev = None\n for _ in range(n):\n ft = trigger.get_next_fire_time(prev, next_time)\n if ft is None:\n break\n results.append(ft.isoformat())\n prev = ft\n next_time = ft\n return results\n # endregion get_next_executions\n\n\n# #endregion TranslationScheduler\n\n\n# #region execute_scheduled_translation [TYPE Function]\n# @BRIEF APScheduler job handler — runs scheduled translation with concurrency check and new-key-only fallback.\n# @PRE: schedule_id is valid.\n# @POST: Translation run created and executed if no concurrent run exists.\n# @SIDE_EFFECT: DB writes; LLM calls; Superset API calls.\n# @RATIONALE: New-key-only mode compares keys against most recent succeeded run; baseline_expired fallback does full.\ndef execute_scheduled_translation(\n schedule_id: str,\n job_id: str,\n db_session_maker,\n config_manager: ConfigManager,\n execution_mode: str = \"full\",\n) -> None:\n \"\"\"APScheduler job callback for scheduled translations.\"\"\"\n seed_trace_id()\n db: Session = db_session_maker()\n try:\n with belief_scope(\"execute_scheduled_translation\"):\n # Load schedule\n schedule = db.query(TranslationSchedule).filter(\n TranslationSchedule.id == schedule_id,\n TranslationSchedule.job_id == job_id,\n ).first()\n if not schedule or not schedule.is_active:\n logger.info(f\"[scheduled_translation] Schedule inactive/missing: {schedule_id}\")\n return\n\n logger.reason(\"Scheduled translation triggered\", {\n \"schedule_id\": schedule_id,\n \"job_id\": job_id,\n })\n\n # Concurrency check: max 1 pending/running run per job\n stale_threshold = timedelta(hours=1)\n now = datetime.now(UTC)\n\n active_run = (\n db.query(TranslationRun)\n .filter(\n TranslationRun.job_id == job_id,\n TranslationRun.status.in_([\"PENDING\", \"RUNNING\"]),\n )\n .order_by(TranslationRun.created_at.asc()) # oldest first\n .first()\n )\n if active_run:\n is_stale = (\n active_run.status == \"PENDING\"\n and active_run.created_at\n and (now - active_run.created_at) > stale_threshold\n )\n if is_stale:\n # Mark ALL stale PENDING runs as FAILED\n stale_runs = (\n db.query(TranslationRun)\n .filter(\n TranslationRun.job_id == job_id,\n TranslationRun.status == \"PENDING\",\n TranslationRun.created_at < (now - stale_threshold),\n )\n .all()\n )\n for sr in stale_runs:\n sr.status = \"FAILED\"\n sr.error_message = \"Stale: concurrency deadlock — marked by scheduled trigger\"\n sr.completed_at = now\n db.commit()\n logger.explore(f\"Cleared {len(stale_runs)} stale PENDING run(s), proceeding with scheduled trigger\", {\n \"job_id\": job_id,\n \"stale_run_ids\": [sr.id for sr in stale_runs],\n })\n # Proceed to execute the scheduled run (do NOT return)\n else:\n logger.explore(\"Skipping scheduled run — concurrent run in progress\", {\n \"job_id\": job_id,\n \"existing_run_id\": active_run.id,\n })\n event_log = TranslationEventLog(db)\n event_log.log_event(\n job_id=job_id,\n event_type=\"RUN_STARTED\",\n payload={\"reason\": \"skipped_concurrent\", \"existing_run_id\": active_run.id},\n )\n return\n\n # Check baseline expiry\n baseline_expired = False\n most_recent = (\n db.query(TranslationRun)\n .filter(\n TranslationRun.job_id == job_id,\n TranslationRun.insert_status == \"succeeded\",\n )\n .order_by(TranslationRun.created_at.desc())\n .first()\n )\n if most_recent:\n age = datetime.now(UTC) - most_recent.created_at\n if age > timedelta(days=90):\n baseline_expired = True\n logger.reason(\"Baseline expired — full translation\", {\n \"job_id\": job_id,\n \"last_run\": most_recent.created_at.isoformat(),\n \"age_days\": age.days,\n })\n\n # Import and execute\n from .orchestrator import TranslationOrchestrator\n\n orch = TranslationOrchestrator(db, config_manager, current_user=\"scheduler\")\n run = orch.start_run(\n job_id=job_id,\n is_scheduled=True,\n )\n\n # Determine trigger type based on execution_mode and baseline expiry\n if execution_mode == \"new_key_only\" and not baseline_expired:\n run.trigger_type = \"new_key_only\"\n elif execution_mode == \"new_key_only\" and baseline_expired:\n logger.reason(\"Baseline expired — falling back to full translation\", {\n \"job_id\": job_id, \"schedule_id\": schedule_id, \"age_days\": age.days,\n })\n run.trigger_type = \"scheduled\"\n else:\n run.trigger_type = \"scheduled\"\n db.flush()\n\n if baseline_expired:\n event_log = TranslationEventLog(db)\n event_log.log_event(\n job_id=job_id,\n run_id=run.id,\n event_type=\"RUN_STARTED\",\n payload={\"reason\": \"baseline_expired\", \"age_days\": age.days},\n )\n\n # Execute in same thread (APScheduler runs in background thread pool)\n try:\n orch.execute_run(run)\n run.insert_status = run.insert_status or \"succeeded\"\n except Exception as exec_err:\n logger.explore(\"Scheduled translation execution failed\", {\n \"run_id\": run.id,\n \"error\": str(exec_err),\n })\n # Send notification on scheduled-run failure (FR-041, FR-048)\n try:\n notify_service = NotificationService(db, config_manager)\n notify_service._initialize_providers()\n subject = f\"Scheduled translation failed: job={job_id}\"\n body = (\n f\"Scheduled translation run failed for job '{job_id}'.\\n\"\n f\"Schedule: {schedule_id}\\n\"\n f\"Error: {exec_err}\\n\"\n f\"Time: {datetime.now(UTC).isoformat()}\"\n )\n import asyncio\n for provider in notify_service._providers.values():\n asyncio.run(provider.send(recipient=\"admin\", subject=subject, body=body))\n except Exception as notify_err:\n logger.warning(f\"Failed to send failure notification: {notify_err}\")\n\n # Leave schedule enabled — schedule continues on failure\n run.status = \"FAILED\"\n run.error_message = str(exec_err)\n run.completed_at = datetime.now(UTC)\n\n # Update schedule tracking\n schedule.last_run_at = datetime.now(UTC)\n db.commit()\n\n logger.reflect(\"Scheduled translation complete\", {\n \"schedule_id\": schedule_id,\n \"run_id\": run.id,\n \"status\": run.status,\n })\n except Exception as e:\n logger.error(f\"[scheduled_translation] Unexpected error: {e}\")\n try:\n notify_service = NotificationService(db, config_manager)\n notify_service._initialize_providers()\n subject = f\"Scheduled translation CRASHED: job={job_id}\"\n body = f\"Scheduled translation for job '{job_id}' crashed unexpectedly.\\nError: {e}\\nTime: {datetime.now(UTC).isoformat()}\"\n import asyncio\n for provider in notify_service._providers.values():\n asyncio.run(provider.send(recipient=\"admin\", subject=subject, body=body))\n except Exception:\n pass\n finally:\n db.close()\n# #endregion execute_scheduled_translation\n# #endregion TranslationScheduler\n" + "body": "# #region TranslationScheduler [C:4] [TYPE Module] [SEMANTICS sqlalchemy, translate, schedule, cron, job]\n# @BRIEF Manage TranslationSchedule rows and register them with core SchedulerService.\n# @LAYER: Domain\n# @RELATION DEPENDS_ON -> [TranslationSchedule:Class]\n# @RELATION DEPENDS_ON -> [SchedulerService:Class]\n# @RELATION DEPENDS_ON -> [TranslationOrchestrator:Class]\n# @RELATION DEPENDS_ON -> [TranslationEventLog:Class]\n# @PRE: Database session and SchedulerService are available.\n# @POST: TranslationSchedule CRUD persisted; APScheduler jobs registered/updated/removed.\n# @SIDE_EFFECT: Registers APScheduler jobs; runs translations on trigger; creates events.\n# @RATIONALE: Uses existing SchedulerService (APScheduler) to avoid creating a second scheduler instance.\n# @REJECTED: Separate scheduler instance would create resource contention.\n# @REJECTED: Polling-based approach — event-driven APScheduler is more precise.\n\nimport uuid\nfrom datetime import UTC, datetime, timedelta\n\nfrom sqlalchemy.orm import Session\n\nfrom ...core.config_manager import ConfigManager\nfrom ...core.cot_logger import seed_trace_id\nfrom ...core.logger import belief_scope, logger\nfrom ...models.translate import TranslationJob, TranslationRun, TranslationSchedule\nfrom ...services.notifications.service import NotificationService\nfrom .events import TranslationEventLog\n\n\n# #region TranslationScheduler [C:4] [TYPE Class]\n# @BRIEF CRUD for TranslationSchedule rows + APScheduler registration wrappers.\nclass TranslationScheduler:\n\n def __init__(self, db: Session, config_manager: ConfigManager, current_user: str | None = None):\n self.db = db\n self.config_manager = config_manager\n self.current_user = current_user\n self.event_log = TranslationEventLog(db)\n\n # region create_schedule [TYPE Function]\n # @PURPOSE: Create a new schedule for a job.\n # @PRE: job_id exists. cron_expression is valid.\n # @POST: TranslationSchedule row created.\n def create_schedule(\n self,\n job_id: str,\n cron_expression: str,\n timezone: str = \"UTC\",\n is_active: bool = True,\n execution_mode: str = \"full\",\n ) -> TranslationSchedule:\n with belief_scope(\"TranslationScheduler.create_schedule\"):\n # Verify job exists\n job = self.db.query(TranslationJob).filter(TranslationJob.id == job_id).first()\n if not job:\n raise ValueError(f\"Translation job '{job_id}' not found\")\n\n schedule = TranslationSchedule(\n id=str(uuid.uuid4()),\n job_id=job_id,\n cron_expression=cron_expression,\n timezone=timezone,\n is_active=is_active,\n execution_mode=execution_mode,\n created_by=self.current_user,\n )\n self.db.add(schedule)\n self.db.commit()\n self.db.refresh(schedule)\n\n self.event_log.log_event(\n job_id=job_id,\n event_type=\"SCHEDULE_CREATED\",\n payload={\n \"schedule_id\": schedule.id,\n \"cron_expression\": cron_expression,\n \"timezone\": timezone,\n },\n created_by=self.current_user,\n )\n\n logger.reflect(\"Schedule created\", {\"schedule_id\": schedule.id, \"job_id\": job_id})\n return schedule\n # endregion create_schedule\n\n # region update_schedule [TYPE Function]\n # @PURPOSE: Update an existing schedule.\n # @PRE: job_id has an existing schedule.\n # @POST: Schedule updated.\n def update_schedule(\n self,\n job_id: str,\n cron_expression: str | None = None,\n timezone_str: str | None = None,\n is_active: bool | None = None,\n execution_mode: str | None = None,\n ) -> TranslationSchedule:\n with belief_scope(\"TranslationScheduler.update_schedule\"):\n schedule = self.db.query(TranslationSchedule).filter(\n TranslationSchedule.job_id == job_id\n ).first()\n if not schedule:\n raise ValueError(f\"No schedule found for job '{job_id}'\")\n\n if cron_expression is not None:\n schedule.cron_expression = cron_expression\n if timezone_str is not None:\n schedule.timezone = timezone_str\n if is_active is not None:\n schedule.is_active = is_active\n if execution_mode is not None:\n schedule.execution_mode = execution_mode\n schedule.updated_at = datetime.now(UTC)\n self.db.commit()\n self.db.refresh(schedule)\n\n self.event_log.log_event(\n job_id=job_id,\n event_type=\"SCHEDULE_UPDATED\",\n payload={\n \"schedule_id\": schedule.id,\n \"cron_expression\": schedule.cron_expression,\n \"timezone\": schedule.timezone,\n \"is_active\": schedule.is_active,\n },\n created_by=self.current_user,\n )\n\n logger.reflect(\"Schedule updated\", {\"schedule_id\": schedule.id, \"job_id\": job_id})\n return schedule\n # endregion update_schedule\n\n # region delete_schedule [TYPE Function]\n # @PURPOSE: Delete a schedule for a job.\n # @PRE: job_id has an existing schedule.\n # @POST: Schedule deleted.\n def delete_schedule(self, job_id: str) -> None:\n with belief_scope(\"TranslationScheduler.delete_schedule\"):\n schedule = self.db.query(TranslationSchedule).filter(\n TranslationSchedule.job_id == job_id\n ).first()\n if not schedule:\n raise ValueError(f\"No schedule found for job '{job_id}'\")\n\n schedule_id = schedule.id\n self.db.delete(schedule)\n self.db.commit()\n\n self.event_log.log_event(\n job_id=job_id,\n event_type=\"SCHEDULE_DELETED\",\n payload={\"schedule_id\": schedule_id},\n created_by=self.current_user,\n )\n\n logger.reflect(\"Schedule deleted\", {\"schedule_id\": schedule_id, \"job_id\": job_id})\n # endregion delete_schedule\n\n # region enable_disable_schedule [TYPE Function]\n # @PURPOSE: Enable or disable a schedule.\n # @PRE: job_id has an existing schedule.\n # @POST: Schedule is_active updated.\n def set_schedule_active(self, job_id: str, is_active: bool) -> TranslationSchedule:\n with belief_scope(\"TranslationScheduler.set_schedule_active\"):\n schedule = self.db.query(TranslationSchedule).filter(\n TranslationSchedule.job_id == job_id\n ).first()\n if not schedule:\n raise ValueError(f\"No schedule found for job '{job_id}'\")\n\n schedule.is_active = is_active\n schedule.updated_at = datetime.now(UTC)\n self.db.commit()\n self.db.refresh(schedule)\n\n logger.reflect(\"Schedule active state set\", {\n \"schedule_id\": schedule.id,\n \"job_id\": job_id,\n \"is_active\": is_active,\n })\n return schedule\n # endregion enable_disable_schedule\n\n # region get_schedule [TYPE Function]\n # @PURPOSE: Get schedule for a job.\n # @PRE: job_id exists.\n # @POST: Returns TranslationSchedule or raises ValueError.\n def get_schedule(self, job_id: str) -> TranslationSchedule:\n with belief_scope(\"TranslationScheduler.get_schedule\"):\n schedule = self.db.query(TranslationSchedule).filter(\n TranslationSchedule.job_id == job_id\n ).first()\n if not schedule:\n raise ValueError(f\"No schedule found for job '{job_id}'\")\n return schedule\n # endregion get_schedule\n\n # region list_active_schedules [TYPE Function]\n # @PURPOSE: List all active schedules.\n # @POST: Returns list of active TranslationSchedule rows.\n @staticmethod\n def list_active_schedules(db: Session) -> list[TranslationSchedule]:\n return (\n db.query(TranslationSchedule)\n .filter(TranslationSchedule.is_active)\n .all()\n )\n # endregion list_active_schedules\n\n # region get_next_executions [TYPE Function]\n # @PURPOSE: Compute next N execution times from cron expression.\n # @PRE: cron_expression is valid.\n # @POST: Returns list of ISO datetime strings.\n @staticmethod\n def get_next_executions(cron_expression: str, timezone_str: str = \"UTC\", n: int = 3) -> list[str]:\n from zoneinfo import ZoneInfo\n\n from apscheduler.triggers.cron import CronTrigger\n\n try:\n tz = ZoneInfo(timezone_str)\n trigger = CronTrigger.from_crontab(cron_expression, timezone=tz)\n except (ValueError, KeyError) as e:\n logger.warning(f\"[get_next_executions] Invalid cron: {e}\")\n return []\n\n now = datetime.now(tz)\n results = []\n next_time = now\n prev = None\n for _ in range(n):\n ft = trigger.get_next_fire_time(prev, next_time)\n if ft is None:\n break\n results.append(ft.isoformat())\n prev = ft\n next_time = ft\n return results\n # endregion get_next_executions\n\n\n# #endregion TranslationScheduler\n\n\n# #region execute_scheduled_translation [C:4] [TYPE Function]\n# @BRIEF APScheduler job handler — runs scheduled translation with concurrency check and new-key-only fallback.\n# @PRE schedule_id is valid.\n# @POST Translation run created and executed if no concurrent run exists.\n# @SIDE_EFFECT DB writes; LLM calls; Superset API calls.\n# @RATIONALE New-key-only mode compares keys against most recent succeeded run; baseline_expired fallback does full.\n# @COMPLEXITY 4\n\ndef execute_scheduled_translation(\n schedule_id: str,\n job_id: str,\n db_session_maker,\n config_manager: ConfigManager,\n execution_mode: str = \"full\",\n) -> None:\n \"\"\"APScheduler job callback for scheduled translations.\"\"\"\n seed_trace_id()\n db: Session = db_session_maker()\n try:\n with belief_scope(\"execute_scheduled_translation\"):\n # Load schedule\n schedule = db.query(TranslationSchedule).filter(\n TranslationSchedule.id == schedule_id,\n TranslationSchedule.job_id == job_id,\n ).first()\n if not schedule or not schedule.is_active:\n logger.info(f\"[scheduled_translation] Schedule inactive/missing: {schedule_id}\")\n return\n\n logger.reason(\"Scheduled translation triggered\", {\n \"schedule_id\": schedule_id,\n \"job_id\": job_id,\n })\n\n # Concurrency check: max 1 pending/running run per job\n stale_threshold = timedelta(hours=1)\n now = datetime.now(UTC)\n\n active_run = (\n db.query(TranslationRun)\n .filter(\n TranslationRun.job_id == job_id,\n TranslationRun.status.in_([\"PENDING\", \"RUNNING\"]),\n )\n .order_by(TranslationRun.created_at.asc()) # oldest first\n .first()\n )\n if active_run:\n is_stale = (\n active_run.status == \"PENDING\"\n and active_run.created_at\n and (now - active_run.created_at) > stale_threshold\n )\n if is_stale:\n # Mark ALL stale PENDING runs as FAILED\n stale_runs = (\n db.query(TranslationRun)\n .filter(\n TranslationRun.job_id == job_id,\n TranslationRun.status == \"PENDING\",\n TranslationRun.created_at < (now - stale_threshold),\n )\n .all()\n )\n for sr in stale_runs:\n sr.status = \"FAILED\"\n sr.error_message = \"Stale: concurrency deadlock — marked by scheduled trigger\"\n sr.completed_at = now\n db.commit()\n logger.explore(f\"Cleared {len(stale_runs)} stale PENDING run(s), proceeding with scheduled trigger\", {\n \"job_id\": job_id,\n \"stale_run_ids\": [sr.id for sr in stale_runs],\n })\n # Proceed to execute the scheduled run (do NOT return)\n else:\n logger.explore(\"Skipping scheduled run — concurrent run in progress\", {\n \"job_id\": job_id,\n \"existing_run_id\": active_run.id,\n })\n event_log = TranslationEventLog(db)\n event_log.log_event(\n job_id=job_id,\n event_type=\"RUN_STARTED\",\n payload={\"reason\": \"skipped_concurrent\", \"existing_run_id\": active_run.id},\n )\n return\n\n # Check baseline expiry\n baseline_expired = False\n most_recent = (\n db.query(TranslationRun)\n .filter(\n TranslationRun.job_id == job_id,\n TranslationRun.insert_status == \"succeeded\",\n )\n .order_by(TranslationRun.created_at.desc())\n .first()\n )\n if most_recent:\n age = datetime.now(UTC) - most_recent.created_at\n if age > timedelta(days=90):\n baseline_expired = True\n logger.reason(\"Baseline expired — full translation\", {\n \"job_id\": job_id,\n \"last_run\": most_recent.created_at.isoformat(),\n \"age_days\": age.days,\n })\n\n # Import and execute\n from .orchestrator import TranslationOrchestrator\n\n orch = TranslationOrchestrator(db, config_manager, current_user=\"scheduler\")\n run = orch.start_run(\n job_id=job_id,\n is_scheduled=True,\n )\n\n # Determine trigger type based on execution_mode and baseline expiry\n if execution_mode == \"new_key_only\" and not baseline_expired:\n run.trigger_type = \"new_key_only\"\n elif execution_mode == \"new_key_only\" and baseline_expired:\n logger.reason(\"Baseline expired — falling back to full translation\", {\n \"job_id\": job_id, \"schedule_id\": schedule_id, \"age_days\": age.days,\n })\n run.trigger_type = \"scheduled\"\n else:\n run.trigger_type = \"scheduled\"\n db.flush()\n\n if baseline_expired:\n event_log = TranslationEventLog(db)\n event_log.log_event(\n job_id=job_id,\n run_id=run.id,\n event_type=\"RUN_STARTED\",\n payload={\"reason\": \"baseline_expired\", \"age_days\": age.days},\n )\n\n # Execute in same thread (APScheduler runs in background thread pool)\n try:\n orch.execute_run(run)\n run.insert_status = run.insert_status or \"succeeded\"\n except Exception as exec_err:\n logger.explore(\"Scheduled translation execution failed\", {\n \"run_id\": run.id,\n \"error\": str(exec_err),\n })\n # Send notification on scheduled-run failure (FR-041, FR-048)\n try:\n notify_service = NotificationService(db, config_manager)\n notify_service._initialize_providers()\n subject = f\"Scheduled translation failed: job={job_id}\"\n body = (\n f\"Scheduled translation run failed for job '{job_id}'.\\n\"\n f\"Schedule: {schedule_id}\\n\"\n f\"Error: {exec_err}\\n\"\n f\"Time: {datetime.now(UTC).isoformat()}\"\n )\n import asyncio\n for provider in notify_service._providers.values():\n asyncio.run(provider.send(recipient=\"admin\", subject=subject, body=body))\n except Exception as notify_err:\n logger.warning(f\"Failed to send failure notification: {notify_err}\")\n\n # Leave schedule enabled — schedule continues on failure\n run.status = \"FAILED\"\n run.error_message = str(exec_err)\n run.completed_at = datetime.now(UTC)\n\n # Update schedule tracking\n schedule.last_run_at = datetime.now(UTC)\n db.commit()\n\n logger.reflect(\"Scheduled translation complete\", {\n \"schedule_id\": schedule_id,\n \"run_id\": run.id,\n \"status\": run.status,\n })\n except Exception as e:\n logger.error(f\"[scheduled_translation] Unexpected error: {e}\")\n try:\n notify_service = NotificationService(db, config_manager)\n notify_service._initialize_providers()\n subject = f\"Scheduled translation CRASHED: job={job_id}\"\n body = f\"Scheduled translation for job '{job_id}' crashed unexpectedly.\\nError: {e}\\nTime: {datetime.now(UTC).isoformat()}\"\n import asyncio\n for provider in notify_service._providers.values():\n asyncio.run(provider.send(recipient=\"admin\", subject=subject, body=body))\n except Exception:\n pass\n finally:\n db.close()\n# #endregion execute_scheduled_translation\n# #endregion TranslationScheduler\n" }, { "contract_id": "execute_scheduled_translation", "contract_type": "Function", "file_path": "backend/src/plugins/translate/scheduler.py", "start_line": 243, - "end_line": 433, - "tier": "TIER_1", - "complexity": 1, + "end_line": 435, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": "4", "POST": "Translation run created and executed if no concurrent run exists.", "PRE": "schedule_id is valid.", "PURPOSE": "APScheduler job handler — runs scheduled translation with concurrency check and new-key-only fallback.", @@ -50287,36 +49567,18 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "SIDE_EFFECT", - "message": "@SIDE_EFFECT is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region execute_scheduled_translation [TYPE Function]\n# @BRIEF APScheduler job handler — runs scheduled translation with concurrency check and new-key-only fallback.\n# @PRE: schedule_id is valid.\n# @POST: Translation run created and executed if no concurrent run exists.\n# @SIDE_EFFECT: DB writes; LLM calls; Superset API calls.\n# @RATIONALE: New-key-only mode compares keys against most recent succeeded run; baseline_expired fallback does full.\ndef execute_scheduled_translation(\n schedule_id: str,\n job_id: str,\n db_session_maker,\n config_manager: ConfigManager,\n execution_mode: str = \"full\",\n) -> None:\n \"\"\"APScheduler job callback for scheduled translations.\"\"\"\n seed_trace_id()\n db: Session = db_session_maker()\n try:\n with belief_scope(\"execute_scheduled_translation\"):\n # Load schedule\n schedule = db.query(TranslationSchedule).filter(\n TranslationSchedule.id == schedule_id,\n TranslationSchedule.job_id == job_id,\n ).first()\n if not schedule or not schedule.is_active:\n logger.info(f\"[scheduled_translation] Schedule inactive/missing: {schedule_id}\")\n return\n\n logger.reason(\"Scheduled translation triggered\", {\n \"schedule_id\": schedule_id,\n \"job_id\": job_id,\n })\n\n # Concurrency check: max 1 pending/running run per job\n stale_threshold = timedelta(hours=1)\n now = datetime.now(UTC)\n\n active_run = (\n db.query(TranslationRun)\n .filter(\n TranslationRun.job_id == job_id,\n TranslationRun.status.in_([\"PENDING\", \"RUNNING\"]),\n )\n .order_by(TranslationRun.created_at.asc()) # oldest first\n .first()\n )\n if active_run:\n is_stale = (\n active_run.status == \"PENDING\"\n and active_run.created_at\n and (now - active_run.created_at) > stale_threshold\n )\n if is_stale:\n # Mark ALL stale PENDING runs as FAILED\n stale_runs = (\n db.query(TranslationRun)\n .filter(\n TranslationRun.job_id == job_id,\n TranslationRun.status == \"PENDING\",\n TranslationRun.created_at < (now - stale_threshold),\n )\n .all()\n )\n for sr in stale_runs:\n sr.status = \"FAILED\"\n sr.error_message = \"Stale: concurrency deadlock — marked by scheduled trigger\"\n sr.completed_at = now\n db.commit()\n logger.explore(f\"Cleared {len(stale_runs)} stale PENDING run(s), proceeding with scheduled trigger\", {\n \"job_id\": job_id,\n \"stale_run_ids\": [sr.id for sr in stale_runs],\n })\n # Proceed to execute the scheduled run (do NOT return)\n else:\n logger.explore(\"Skipping scheduled run — concurrent run in progress\", {\n \"job_id\": job_id,\n \"existing_run_id\": active_run.id,\n })\n event_log = TranslationEventLog(db)\n event_log.log_event(\n job_id=job_id,\n event_type=\"RUN_STARTED\",\n payload={\"reason\": \"skipped_concurrent\", \"existing_run_id\": active_run.id},\n )\n return\n\n # Check baseline expiry\n baseline_expired = False\n most_recent = (\n db.query(TranslationRun)\n .filter(\n TranslationRun.job_id == job_id,\n TranslationRun.insert_status == \"succeeded\",\n )\n .order_by(TranslationRun.created_at.desc())\n .first()\n )\n if most_recent:\n age = datetime.now(UTC) - most_recent.created_at\n if age > timedelta(days=90):\n baseline_expired = True\n logger.reason(\"Baseline expired — full translation\", {\n \"job_id\": job_id,\n \"last_run\": most_recent.created_at.isoformat(),\n \"age_days\": age.days,\n })\n\n # Import and execute\n from .orchestrator import TranslationOrchestrator\n\n orch = TranslationOrchestrator(db, config_manager, current_user=\"scheduler\")\n run = orch.start_run(\n job_id=job_id,\n is_scheduled=True,\n )\n\n # Determine trigger type based on execution_mode and baseline expiry\n if execution_mode == \"new_key_only\" and not baseline_expired:\n run.trigger_type = \"new_key_only\"\n elif execution_mode == \"new_key_only\" and baseline_expired:\n logger.reason(\"Baseline expired — falling back to full translation\", {\n \"job_id\": job_id, \"schedule_id\": schedule_id, \"age_days\": age.days,\n })\n run.trigger_type = \"scheduled\"\n else:\n run.trigger_type = \"scheduled\"\n db.flush()\n\n if baseline_expired:\n event_log = TranslationEventLog(db)\n event_log.log_event(\n job_id=job_id,\n run_id=run.id,\n event_type=\"RUN_STARTED\",\n payload={\"reason\": \"baseline_expired\", \"age_days\": age.days},\n )\n\n # Execute in same thread (APScheduler runs in background thread pool)\n try:\n orch.execute_run(run)\n run.insert_status = run.insert_status or \"succeeded\"\n except Exception as exec_err:\n logger.explore(\"Scheduled translation execution failed\", {\n \"run_id\": run.id,\n \"error\": str(exec_err),\n })\n # Send notification on scheduled-run failure (FR-041, FR-048)\n try:\n notify_service = NotificationService(db, config_manager)\n notify_service._initialize_providers()\n subject = f\"Scheduled translation failed: job={job_id}\"\n body = (\n f\"Scheduled translation run failed for job '{job_id}'.\\n\"\n f\"Schedule: {schedule_id}\\n\"\n f\"Error: {exec_err}\\n\"\n f\"Time: {datetime.now(UTC).isoformat()}\"\n )\n import asyncio\n for provider in notify_service._providers.values():\n asyncio.run(provider.send(recipient=\"admin\", subject=subject, body=body))\n except Exception as notify_err:\n logger.warning(f\"Failed to send failure notification: {notify_err}\")\n\n # Leave schedule enabled — schedule continues on failure\n run.status = \"FAILED\"\n run.error_message = str(exec_err)\n run.completed_at = datetime.now(UTC)\n\n # Update schedule tracking\n schedule.last_run_at = datetime.now(UTC)\n db.commit()\n\n logger.reflect(\"Scheduled translation complete\", {\n \"schedule_id\": schedule_id,\n \"run_id\": run.id,\n \"status\": run.status,\n })\n except Exception as e:\n logger.error(f\"[scheduled_translation] Unexpected error: {e}\")\n try:\n notify_service = NotificationService(db, config_manager)\n notify_service._initialize_providers()\n subject = f\"Scheduled translation CRASHED: job={job_id}\"\n body = f\"Scheduled translation for job '{job_id}' crashed unexpectedly.\\nError: {e}\\nTime: {datetime.now(UTC).isoformat()}\"\n import asyncio\n for provider in notify_service._providers.values():\n asyncio.run(provider.send(recipient=\"admin\", subject=subject, body=body))\n except Exception:\n pass\n finally:\n db.close()\n# #endregion execute_scheduled_translation\n" + "body": "# #region execute_scheduled_translation [C:4] [TYPE Function]\n# @BRIEF APScheduler job handler — runs scheduled translation with concurrency check and new-key-only fallback.\n# @PRE schedule_id is valid.\n# @POST Translation run created and executed if no concurrent run exists.\n# @SIDE_EFFECT DB writes; LLM calls; Superset API calls.\n# @RATIONALE New-key-only mode compares keys against most recent succeeded run; baseline_expired fallback does full.\n# @COMPLEXITY 4\n\ndef execute_scheduled_translation(\n schedule_id: str,\n job_id: str,\n db_session_maker,\n config_manager: ConfigManager,\n execution_mode: str = \"full\",\n) -> None:\n \"\"\"APScheduler job callback for scheduled translations.\"\"\"\n seed_trace_id()\n db: Session = db_session_maker()\n try:\n with belief_scope(\"execute_scheduled_translation\"):\n # Load schedule\n schedule = db.query(TranslationSchedule).filter(\n TranslationSchedule.id == schedule_id,\n TranslationSchedule.job_id == job_id,\n ).first()\n if not schedule or not schedule.is_active:\n logger.info(f\"[scheduled_translation] Schedule inactive/missing: {schedule_id}\")\n return\n\n logger.reason(\"Scheduled translation triggered\", {\n \"schedule_id\": schedule_id,\n \"job_id\": job_id,\n })\n\n # Concurrency check: max 1 pending/running run per job\n stale_threshold = timedelta(hours=1)\n now = datetime.now(UTC)\n\n active_run = (\n db.query(TranslationRun)\n .filter(\n TranslationRun.job_id == job_id,\n TranslationRun.status.in_([\"PENDING\", \"RUNNING\"]),\n )\n .order_by(TranslationRun.created_at.asc()) # oldest first\n .first()\n )\n if active_run:\n is_stale = (\n active_run.status == \"PENDING\"\n and active_run.created_at\n and (now - active_run.created_at) > stale_threshold\n )\n if is_stale:\n # Mark ALL stale PENDING runs as FAILED\n stale_runs = (\n db.query(TranslationRun)\n .filter(\n TranslationRun.job_id == job_id,\n TranslationRun.status == \"PENDING\",\n TranslationRun.created_at < (now - stale_threshold),\n )\n .all()\n )\n for sr in stale_runs:\n sr.status = \"FAILED\"\n sr.error_message = \"Stale: concurrency deadlock — marked by scheduled trigger\"\n sr.completed_at = now\n db.commit()\n logger.explore(f\"Cleared {len(stale_runs)} stale PENDING run(s), proceeding with scheduled trigger\", {\n \"job_id\": job_id,\n \"stale_run_ids\": [sr.id for sr in stale_runs],\n })\n # Proceed to execute the scheduled run (do NOT return)\n else:\n logger.explore(\"Skipping scheduled run — concurrent run in progress\", {\n \"job_id\": job_id,\n \"existing_run_id\": active_run.id,\n })\n event_log = TranslationEventLog(db)\n event_log.log_event(\n job_id=job_id,\n event_type=\"RUN_STARTED\",\n payload={\"reason\": \"skipped_concurrent\", \"existing_run_id\": active_run.id},\n )\n return\n\n # Check baseline expiry\n baseline_expired = False\n most_recent = (\n db.query(TranslationRun)\n .filter(\n TranslationRun.job_id == job_id,\n TranslationRun.insert_status == \"succeeded\",\n )\n .order_by(TranslationRun.created_at.desc())\n .first()\n )\n if most_recent:\n age = datetime.now(UTC) - most_recent.created_at\n if age > timedelta(days=90):\n baseline_expired = True\n logger.reason(\"Baseline expired — full translation\", {\n \"job_id\": job_id,\n \"last_run\": most_recent.created_at.isoformat(),\n \"age_days\": age.days,\n })\n\n # Import and execute\n from .orchestrator import TranslationOrchestrator\n\n orch = TranslationOrchestrator(db, config_manager, current_user=\"scheduler\")\n run = orch.start_run(\n job_id=job_id,\n is_scheduled=True,\n )\n\n # Determine trigger type based on execution_mode and baseline expiry\n if execution_mode == \"new_key_only\" and not baseline_expired:\n run.trigger_type = \"new_key_only\"\n elif execution_mode == \"new_key_only\" and baseline_expired:\n logger.reason(\"Baseline expired — falling back to full translation\", {\n \"job_id\": job_id, \"schedule_id\": schedule_id, \"age_days\": age.days,\n })\n run.trigger_type = \"scheduled\"\n else:\n run.trigger_type = \"scheduled\"\n db.flush()\n\n if baseline_expired:\n event_log = TranslationEventLog(db)\n event_log.log_event(\n job_id=job_id,\n run_id=run.id,\n event_type=\"RUN_STARTED\",\n payload={\"reason\": \"baseline_expired\", \"age_days\": age.days},\n )\n\n # Execute in same thread (APScheduler runs in background thread pool)\n try:\n orch.execute_run(run)\n run.insert_status = run.insert_status or \"succeeded\"\n except Exception as exec_err:\n logger.explore(\"Scheduled translation execution failed\", {\n \"run_id\": run.id,\n \"error\": str(exec_err),\n })\n # Send notification on scheduled-run failure (FR-041, FR-048)\n try:\n notify_service = NotificationService(db, config_manager)\n notify_service._initialize_providers()\n subject = f\"Scheduled translation failed: job={job_id}\"\n body = (\n f\"Scheduled translation run failed for job '{job_id}'.\\n\"\n f\"Schedule: {schedule_id}\\n\"\n f\"Error: {exec_err}\\n\"\n f\"Time: {datetime.now(UTC).isoformat()}\"\n )\n import asyncio\n for provider in notify_service._providers.values():\n asyncio.run(provider.send(recipient=\"admin\", subject=subject, body=body))\n except Exception as notify_err:\n logger.warning(f\"Failed to send failure notification: {notify_err}\")\n\n # Leave schedule enabled — schedule continues on failure\n run.status = \"FAILED\"\n run.error_message = str(exec_err)\n run.completed_at = datetime.now(UTC)\n\n # Update schedule tracking\n schedule.last_run_at = datetime.now(UTC)\n db.commit()\n\n logger.reflect(\"Scheduled translation complete\", {\n \"schedule_id\": schedule_id,\n \"run_id\": run.id,\n \"status\": run.status,\n })\n except Exception as e:\n logger.error(f\"[scheduled_translation] Unexpected error: {e}\")\n try:\n notify_service = NotificationService(db, config_manager)\n notify_service._initialize_providers()\n subject = f\"Scheduled translation CRASHED: job={job_id}\"\n body = f\"Scheduled translation for job '{job_id}' crashed unexpectedly.\\nError: {e}\\nTime: {datetime.now(UTC).isoformat()}\"\n import asyncio\n for provider in notify_service._providers.values():\n asyncio.run(provider.send(recipient=\"admin\", subject=subject, body=body))\n except Exception:\n pass\n finally:\n db.close()\n# #endregion execute_scheduled_translation\n" }, { "contract_id": "get_dialect_from_database", @@ -50324,9 +49586,10 @@ "file_path": "backend/src/plugins/translate/service.py", "start_line": 41, "end_line": 84, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns normalized dialect string or raises ValueError if unsupported.", "PRE": "database_record is a dict from Superset API.", "PURPOSE": "Extract normalized dialect string from a Superset database record." @@ -50334,27 +49597,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region get_dialect_from_database [TYPE Function]\n# @BRIEF Extract normalized dialect string from a Superset database record.\n# @PRE: database_record is a dict from Superset API.\n# @POST: Returns normalized dialect string or raises ValueError if unsupported.\ndef get_dialect_from_database(database_record: dict[str, Any]) -> str:\n \"\"\"Extract and validate dialect from Superset database record.\"\"\"\n backend = (\n database_record.get(\"backend\")\n or database_record.get(\"engine\")\n or \"\"\n ).lower().strip()\n\n if not backend:\n raise ValueError(\"Could not determine database dialect from connection\")\n\n # Map Superset backend names to normalized dialect\n dialect_map = {\n \"postgresql\": \"postgresql\",\n \"greenplum\": \"postgresql\",\n \"mysql\": \"mysql\",\n \"clickhouse\": \"clickhouse\",\n \"clickhousedb\": \"clickhouse\",\n \"sqlite\": \"sqlite\",\n \"mssql\": \"mssql\",\n \"oracle\": \"oracle\",\n \"snowflake\": \"snowflake\",\n \"bigquery\": \"bigquery\",\n \"redshift\": \"redshift\",\n \"presto\": \"presto\",\n \"trino\": \"trino\",\n \"druid\": \"druid\",\n \"hive\": \"hive\",\n \"spark\": \"spark\",\n \"databricks\": \"databricks\",\n }\n\n normalized = dialect_map.get(backend, backend)\n if normalized not in SUPPORTED_DIALECTS:\n raise ValueError(\n f\"Unsupported database dialect: '{backend}'. \"\n f\"Supported dialects: {', '.join(sorted(SUPPORTED_DIALECTS))}\"\n )\n return normalized\n# #endregion get_dialect_from_database\n" + "body": "# #region get_dialect_from_database [C:4] [TYPE Function]\n# @BRIEF Extract normalized dialect string from a Superset database record.\n# @PRE: database_record is a dict from Superset API.\n# @POST: Returns normalized dialect string or raises ValueError if unsupported.\ndef get_dialect_from_database(database_record: dict[str, Any]) -> str:\n \"\"\"Extract and validate dialect from Superset database record.\"\"\"\n backend = (\n database_record.get(\"backend\")\n or database_record.get(\"engine\")\n or \"\"\n ).lower().strip()\n\n if not backend:\n raise ValueError(\"Could not determine database dialect from connection\")\n\n # Map Superset backend names to normalized dialect\n dialect_map = {\n \"postgresql\": \"postgresql\",\n \"greenplum\": \"postgresql\",\n \"mysql\": \"mysql\",\n \"clickhouse\": \"clickhouse\",\n \"clickhousedb\": \"clickhouse\",\n \"sqlite\": \"sqlite\",\n \"mssql\": \"mssql\",\n \"oracle\": \"oracle\",\n \"snowflake\": \"snowflake\",\n \"bigquery\": \"bigquery\",\n \"redshift\": \"redshift\",\n \"presto\": \"presto\",\n \"trino\": \"trino\",\n \"druid\": \"druid\",\n \"hive\": \"hive\",\n \"spark\": \"spark\",\n \"databricks\": \"databricks\",\n }\n\n normalized = dialect_map.get(backend, backend)\n if normalized not in SUPPORTED_DIALECTS:\n raise ValueError(\n f\"Unsupported database dialect: '{backend}'. \"\n f\"Supported dialects: {', '.join(sorted(SUPPORTED_DIALECTS))}\"\n )\n return normalized\n# #endregion get_dialect_from_database\n" }, { "contract_id": "fetch_datasource_metadata", @@ -50362,9 +49625,10 @@ "file_path": "backend/src/plugins/translate/service.py", "start_line": 87, "end_line": 141, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns (columns_list, dialect_string) or raises on failure.", "PRE": "dataset_id is a valid Superset dataset ID and environment has valid credentials.", "PURPOSE": "Fetch datasource columns and database dialect from Superset." @@ -50372,27 +49636,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region fetch_datasource_metadata [TYPE Function]\n# @BRIEF Fetch datasource columns and database dialect from Superset.\n# @PRE: dataset_id is a valid Superset dataset ID and environment has valid credentials.\n# @POST: Returns (columns_list, dialect_string) or raises on failure.\ndef fetch_datasource_metadata(\n dataset_id: int,\n env_id: str,\n config_manager: ConfigManager,\n) -> tuple[list[dict[str, Any]], str]:\n \"\"\"Fetch column metadata and database dialect for a datasource from Superset.\"\"\"\n # Find environment config\n environments = config_manager.get_environments()\n env_config = next((e for e in environments if e.id == env_id), None)\n if not env_config:\n raise ValueError(f\"Superset environment '{env_id}' not found in configuration\")\n\n # Create Superset client and fetch dataset detail\n client = SupersetClient(env_config)\n dataset_detail = client.get_dataset_detail(dataset_id)\n\n # Extract columns\n raw_columns = dataset_detail.get(\"columns\", [])\n columns = []\n for col in raw_columns:\n col_name = col.get(\"name\") or col.get(\"column_name\")\n if not col_name:\n continue\n columns.append({\n \"name\": str(col_name),\n \"type\": col.get(\"type\"),\n \"is_physical\": col.get(\"is_physical\", True),\n \"is_dttm\": col.get(\"is_dttm\", False),\n \"description\": col.get(\"description\", \"\"),\n })\n\n # Extract database dialect from datasource\n database_info = dataset_detail.get(\"database\", {})\n if isinstance(database_info, dict):\n dialect = get_dialect_from_database(database_info)\n else:\n # Fallback: try to fetch database directly\n try:\n db_id = dataset_detail.get(\"database_id\")\n if db_id:\n db_record = client.get_database(int(db_id))\n db_result = db_record.get(\"result\", db_record) if isinstance(db_record, dict) else db_record\n dialect = get_dialect_from_database(db_result)\n else:\n raise ValueError(\"No database information available for this datasource\")\n except Exception as e:\n logger.warning(f\"[translate_service] Could not fetch database dialect: {e}\")\n raise ValueError(f\"Could not determine database dialect: {e}\")\n\n return columns, dialect\n# #endregion fetch_datasource_metadata\n" + "body": "# #region fetch_datasource_metadata [C:4] [TYPE Function]\n# @BRIEF Fetch datasource columns and database dialect from Superset.\n# @PRE: dataset_id is a valid Superset dataset ID and environment has valid credentials.\n# @POST: Returns (columns_list, dialect_string) or raises on failure.\ndef fetch_datasource_metadata(\n dataset_id: int,\n env_id: str,\n config_manager: ConfigManager,\n) -> tuple[list[dict[str, Any]], str]:\n \"\"\"Fetch column metadata and database dialect for a datasource from Superset.\"\"\"\n # Find environment config\n environments = config_manager.get_environments()\n env_config = next((e for e in environments if e.id == env_id), None)\n if not env_config:\n raise ValueError(f\"Superset environment '{env_id}' not found in configuration\")\n\n # Create Superset client and fetch dataset detail\n client = SupersetClient(env_config)\n dataset_detail = client.get_dataset_detail(dataset_id)\n\n # Extract columns\n raw_columns = dataset_detail.get(\"columns\", [])\n columns = []\n for col in raw_columns:\n col_name = col.get(\"name\") or col.get(\"column_name\")\n if not col_name:\n continue\n columns.append({\n \"name\": str(col_name),\n \"type\": col.get(\"type\"),\n \"is_physical\": col.get(\"is_physical\", True),\n \"is_dttm\": col.get(\"is_dttm\", False),\n \"description\": col.get(\"description\", \"\"),\n })\n\n # Extract database dialect from datasource\n database_info = dataset_detail.get(\"database\", {})\n if isinstance(database_info, dict):\n dialect = get_dialect_from_database(database_info)\n else:\n # Fallback: try to fetch database directly\n try:\n db_id = dataset_detail.get(\"database_id\")\n if db_id:\n db_record = client.get_database(int(db_id))\n db_result = db_record.get(\"result\", db_record) if isinstance(db_record, dict) else db_record\n dialect = get_dialect_from_database(db_result)\n else:\n raise ValueError(\"No database information available for this datasource\")\n except Exception as e:\n logger.warning(f\"[translate_service] Could not fetch database dialect: {e}\")\n raise ValueError(f\"Could not determine database dialect: {e}\")\n\n return columns, dialect\n# #endregion fetch_datasource_metadata\n" }, { "contract_id": "detect_virtual_columns", @@ -50400,9 +49664,10 @@ "file_path": "backend/src/plugins/translate/service.py", "start_line": 144, "end_line": 151, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns list of virtual column names.", "PRE": "columns is a list of dicts with 'is_physical' key.", "PURPOSE": "Identify virtual (calculated) columns from column metadata." @@ -50410,27 +49675,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region detect_virtual_columns [TYPE Function]\n# @BRIEF Identify virtual (calculated) columns from column metadata.\n# @PRE: columns is a list of dicts with 'is_physical' key.\n# @POST: Returns list of virtual column names.\ndef detect_virtual_columns(columns: list[dict[str, Any]]) -> list[str]:\n \"\"\"Return names of columns that are virtual (not physical).\"\"\"\n return [col[\"name\"] for col in columns if not col.get(\"is_physical\", True)]\n# #endregion detect_virtual_columns\n" + "body": "# #region detect_virtual_columns [C:4] [TYPE Function]\n# @BRIEF Identify virtual (calculated) columns from column metadata.\n# @PRE: columns is a list of dicts with 'is_physical' key.\n# @POST: Returns list of virtual column names.\ndef detect_virtual_columns(columns: list[dict[str, Any]]) -> list[str]:\n \"\"\"Return names of columns that are virtual (not physical).\"\"\"\n return [col[\"name\"] for col in columns if not col.get(\"is_physical\", True)]\n# #endregion detect_virtual_columns\n" }, { "contract_id": "TranslateJobService", @@ -50471,10 +49736,11 @@ "contract_type": "Function", "file_path": "backend/src/plugins/translate/service.py", "start_line": 522, - "end_line": 584, - "tier": "TIER_1", - "complexity": 1, + "end_line": 586, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": "4", "POST": "Returns DatasourceColumnsResponse with column metadata and database dialect.", "PRE": "datasource_id is a valid Superset dataset ID.", "PURPOSE": "Fetch datasource column metadata from Superset and return structured response.", @@ -50483,43 +49749,25 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "SIDE_EFFECT", - "message": "@SIDE_EFFECT is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region DatasourceColumnsService [TYPE Function]\n# @BRIEF Fetch datasource column metadata from Superset and return structured response.\n# @PRE: datasource_id is a valid Superset dataset ID.\n# @POST: Returns DatasourceColumnsResponse with column metadata and database dialect.\n# @SIDE_EFFECT: Queries Superset API for dataset detail and database info.\ndef get_datasource_columns(\n datasource_id: int,\n env_id: str,\n config_manager: ConfigManager,\n) -> DatasourceColumnsResponse:\n \"\"\"Fetch and return column metadata for a given Superset datasource.\"\"\"\n logger.info(f\"[get_datasource_columns] Fetching columns for datasource {datasource_id}\")\n\n # Find environment config\n environments = config_manager.get_environments()\n env_config = next((e for e in environments if e.id == env_id), None)\n if not env_config:\n raise ValueError(f\"Superset environment '{env_id}' not found\")\n\n # Create Superset client\n client = SupersetClient(env_config)\n dataset_detail = client.get_dataset_detail(datasource_id)\n\n # Extract database dialect\n database_info = dataset_detail.get(\"database\", {})\n dialect = None\n if isinstance(database_info, dict):\n try:\n dialect = get_dialect_from_database(database_info)\n except (ValueError, KeyError):\n dialect = None\n if dialect is None:\n database_id = dataset_detail.get(\"database_id\")\n if database_id:\n db_record = client.get_database(int(database_id))\n db_result = db_record.get(\"result\", db_record) if isinstance(db_record, dict) else db_record\n dialect = get_dialect_from_database(db_result)\n else:\n raise ValueError(\"Could not determine database dialect for this datasource\")\n\n # Extract columns\n raw_columns = dataset_detail.get(\"columns\", [])\n columns = []\n for col in raw_columns:\n col_name = col.get(\"name\") or col.get(\"column_name\")\n if not col_name:\n continue\n columns.append(DatasourceColumnResponse(\n name=str(col_name),\n type=col.get(\"type\"),\n is_physical=col.get(\"is_physical\", True),\n is_dttm=col.get(\"is_dttm\", False),\n description=col.get(\"description\", \"\"),\n ))\n\n return DatasourceColumnsResponse(\n datasource_id=datasource_id,\n datasource_name=dataset_detail.get(\"table_name\"),\n schema_name=dataset_detail.get(\"schema\"),\n database_dialect=dialect,\n columns=columns,\n )\n# #endregion DatasourceColumnsService\n" + "body": "# #region DatasourceColumnsService [C:4] [TYPE Function]\n# @BRIEF Fetch datasource column metadata from Superset and return structured response.\n# @PRE datasource_id is a valid Superset dataset ID.\n# @POST Returns DatasourceColumnsResponse with column metadata and database dialect.\n# @SIDE_EFFECT Queries Superset API for dataset detail and database info.\n# @COMPLEXITY 4\n\ndef get_datasource_columns(\n datasource_id: int,\n env_id: str,\n config_manager: ConfigManager,\n) -> DatasourceColumnsResponse:\n \"\"\"Fetch and return column metadata for a given Superset datasource.\"\"\"\n logger.info(f\"[get_datasource_columns] Fetching columns for datasource {datasource_id}\")\n\n # Find environment config\n environments = config_manager.get_environments()\n env_config = next((e for e in environments if e.id == env_id), None)\n if not env_config:\n raise ValueError(f\"Superset environment '{env_id}' not found\")\n\n # Create Superset client\n client = SupersetClient(env_config)\n dataset_detail = client.get_dataset_detail(datasource_id)\n\n # Extract database dialect\n database_info = dataset_detail.get(\"database\", {})\n dialect = None\n if isinstance(database_info, dict):\n try:\n dialect = get_dialect_from_database(database_info)\n except (ValueError, KeyError):\n dialect = None\n if dialect is None:\n database_id = dataset_detail.get(\"database_id\")\n if database_id:\n db_record = client.get_database(int(database_id))\n db_result = db_record.get(\"result\", db_record) if isinstance(db_record, dict) else db_record\n dialect = get_dialect_from_database(db_result)\n else:\n raise ValueError(\"Could not determine database dialect for this datasource\")\n\n # Extract columns\n raw_columns = dataset_detail.get(\"columns\", [])\n columns = []\n for col in raw_columns:\n col_name = col.get(\"name\") or col.get(\"column_name\")\n if not col_name:\n continue\n columns.append(DatasourceColumnResponse(\n name=str(col_name),\n type=col.get(\"type\"),\n is_physical=col.get(\"is_physical\", True),\n is_dttm=col.get(\"is_dttm\", False),\n description=col.get(\"description\", \"\"),\n ))\n\n return DatasourceColumnsResponse(\n datasource_id=datasource_id,\n datasource_name=dataset_detail.get(\"table_name\"),\n schema_name=dataset_detail.get(\"schema\"),\n database_dialect=dialect,\n columns=columns,\n )\n# #endregion DatasourceColumnsService\n" }, { "contract_id": "InlineCorrectionService", "contract_type": "Class", "file_path": "backend/src/plugins/translate/service.py", - "start_line": 587, - "end_line": 826, + "start_line": 589, + "end_line": 828, "tier": "TIER_2", "complexity": 3, "metadata": { @@ -50546,8 +49794,8 @@ "contract_id": "BulkFindReplaceService", "contract_type": "Class", "file_path": "backend/src/plugins/translate/service.py", - "start_line": 829, - "end_line": 1046, + "start_line": 831, + "end_line": 1048, "tier": "TIER_2", "complexity": 3, "metadata": { @@ -50575,7 +49823,7 @@ "contract_type": "Module", "file_path": "backend/src/plugins/translate/sql_generator.py", "start_line": 1, - "end_line": 376, + "end_line": 378, "tier": "TIER_2", "complexity": 3, "metadata": { @@ -50633,7 +49881,7 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region SQLGenerator [C:3] [TYPE Module] [SEMANTICS clickhouse, translate, sql, insert, generate]\n# @BRIEF Dialect-aware safe SQL generation for INSERT/UPSERT operations.\n# @LAYER: Domain\n# @RELATION DEPENDS_ON -> [TranslationJob]\n# @RELATION DEPENDS_ON -> [TranslationRun]\n# @PRE: Job has target_schema and target_table configured. Dialect is one of supported SUPPORTED_DIALECTS.\n# @POST: Returns safe SQL strings for the target dialect.\n# @SIDE_EFFECT: None — pure code generation.\n# @RATIONALE: Dialect-aware SQL uses ON CONFLICT for PostgreSQL; plain INSERT for ClickHouse with documented limitations.\n# @REJECTED: UPDATE statements — source is append-only; UPSERT covers overwrite case.\n# @REJECTED: ORM-based insert bypasses Superset's SQL Lab audit trail.\n\nfrom datetime import UTC, datetime\nfrom typing import Any\n\nfrom ...core.logger import belief_scope, logger\n\n# PostgreSQL/Greenplum dialects that support ON CONFLICT\nPOSTGRESQL_DIALECTS = {\"postgresql\", \"redshift\", \"greenplum\"}\n# Dialects that use backtick or no quoting\nCLICKHOUSE_DIALECTS = {\"clickhouse\"}\n\n\n# #region _normalize_timestamp_value [C:2] [TYPE Function] [SEMANTICS translate,sql,timestamp]\n# @BRIEF Detect Unix timestamp strings (seconds or millis) and convert to 'YYYY-MM-DD' for Date columns.\ndef _normalize_timestamp_value(value: Any) -> str | None:\n \"\"\"Detect Unix timestamp values and convert to date string.\n\n Handles:\n - Integer/float Unix timestamps (seconds or milliseconds)\n - String representations of Unix timestamps (e.g. '1726358400000.0')\n\n Returns 'YYYY-MM-DD' if conversion succeeds, None if value is not a timestamp.\n \"\"\"\n # Try numeric conversion first\n try:\n ts = float(value)\n except (ValueError, TypeError):\n return None\n\n # Heuristic: Unix timestamps in seconds are ~10 digits (1e9 range for 2001-2033)\n # Unix timestamps in milliseconds are ~13 digits (1e12 range for 2001-2033)\n if 1e9 <= ts < 1e12:\n # Already in seconds\n pass\n elif 1e12 <= ts < 1e15:\n # Milliseconds — convert to seconds\n ts = ts / 1000.0\n else:\n # Not a plausible Unix timestamp\n return None\n\n try:\n dt = datetime.fromtimestamp(ts, tz=UTC)\n return dt.strftime(\"%Y-%m-%d\")\n except (OSError, OverflowError, ValueError):\n return None\n# #endregion _normalize_timestamp_value\n\n\n# #region _quote_identifier [TYPE Function]\n# @BRIEF Quote an identifier per dialect rules. PostgreSQL uses double quotes; ClickHouse uses backticks.\n# @PRE: identifier is a non-empty string.\n# @POST: Returns safely quoted identifier.\ndef _quote_identifier(identifier: str, dialect: str) -> str:\n \"\"\"Quote a SQL identifier per dialect rules.\"\"\"\n if not identifier:\n return identifier\n # Remove any existing quotes to avoid double-quoting\n cleaned = identifier.strip().strip('\"').strip('`').strip('[]')\n if dialect in POSTGRESQL_DIALECTS:\n return f'\"{cleaned}\"'\n elif dialect in CLICKHOUSE_DIALECTS:\n return f\"`{cleaned}`\"\n else:\n # Generic ANSI double-quote\n return f'\"{cleaned}\"'\n# #endregion _quote_identifier\n\n\n# #region _encode_sql_value [C:2] [TYPE Function] [SEMANTICS translate,sql,encoding]\n# @BRIEF Encode a Python value into a SQL-safe literal for INSERT VALUES, with ClickHouse timestamp normalization.\ndef _encode_sql_value(value: Any, dialect: str | None = None) -> str:\n \"\"\"Encode a Python value into a SQL-safe literal.\n\n For ClickHouse dialect, attempts to detect Unix timestamp strings\n and convert them to 'YYYY-MM-DD' format for Date column compatibility.\n \"\"\"\n if value is None:\n return \"NULL\"\n if isinstance(value, bool):\n return \"TRUE\" if value else \"FALSE\"\n\n # For ClickHouse: try to normalize timestamp-like values (both string and numeric)\n if dialect in CLICKHOUSE_DIALECTS:\n if (isinstance(value, str) and value) or isinstance(value, (int, float)):\n normalized = _normalize_timestamp_value(value)\n if normalized:\n return f\"'{normalized}'\"\n\n if isinstance(value, (int, float)):\n return str(value)\n # String — escape single quotes by doubling them\n escaped = str(value).replace(\"'\", \"''\")\n return f\"'{escaped}'\"\n# #endregion _encode_sql_value\n\n\n# #region _build_values_clause [C:2] [TYPE Function] [SEMANTICS translate,sql,values]\n# @BRIEF Build a VALUES clause for multiple rows with per-column value encoding and dialect-aware quoting.\ndef _build_values_clause(columns: list[str], rows: list[dict[str, Any]], dialect: str | None = None) -> str:\n \"\"\"Build VALUES (...) clause for multiple rows.\n\n NOTE: columns may be quoted (e.g. '\"col\"' or '`col`') for the SQL column list,\n but row dicts have UNQUOTED keys. Strip quotes before value lookup.\n \"\"\"\n value_groups = []\n for row in rows:\n values = []\n for col in columns:\n # Strip quoting for value lookup — row keys are unquoted\n lookup_key = col.strip('\"').strip('`').strip('[]')\n val = row.get(lookup_key)\n values.append(_encode_sql_value(val, dialect=dialect))\n value_groups.append(f\"({', '.join(values)})\")\n return \",\\n\".join(value_groups)\n# #endregion _build_values_clause\n\n\n# #region generate_insert_sql [C:3] [TYPE Function] [SEMANTICS translate,sql,insert]\n# @BRIEF Generate a dialect-aware plain INSERT SQL statement for the given table, columns, and rows.\n# @RELATION DEPENDS_ON -> [_quote_identifier]\n# @RELATION DEPENDS_ON -> [_build_values_clause]\ndef generate_insert_sql(\n target_schema: str | None,\n target_table: str,\n columns: list[str],\n rows: list[dict[str, Any]],\n dialect: str | None = None,\n) -> str:\n \"\"\"Generate a plain INSERT SQL.\"\"\"\n with belief_scope(\"generate_insert_sql\"):\n if not target_table:\n raise ValueError(\"target_table is required for INSERT SQL generation\")\n if not columns:\n raise ValueError(\"At least one column is required for INSERT SQL generation\")\n if not rows:\n raise ValueError(\"At least one row is required for INSERT SQL generation\")\n\n col_list = \", \".join(columns)\n values = _build_values_clause(columns, rows, dialect=dialect)\n\n table_ref = target_table\n if target_schema:\n table_ref = f\"{target_schema}.{target_table}\"\n\n sql = f\"INSERT INTO {table_ref} ({col_list})\\nVALUES\\n{values};\"\n return sql\n# #endregion generate_insert_sql\n\n\n# #region generate_upsert_sql [TYPE Function]\n# @BRIEF Generate PostgreSQL dialect UPSERT SQL with ON CONFLICT DO UPDATE.\n# @PRE: dialect is postgresql-compatible. target_table, columns, key_columns are non-empty.\n# @POST: Returns UPSERT SQL string or raises ValueError.\ndef generate_upsert_sql(\n target_schema: str | None,\n target_table: str,\n columns: list[str],\n key_columns: list[str],\n rows: list[dict[str, Any]],\n) -> str:\n \"\"\"Generate INSERT ... ON CONFLICT (key_cols) DO UPDATE SET ... SQL.\"\"\"\n with belief_scope(\"generate_upsert_sql\"):\n if not target_table:\n raise ValueError(\"target_table is required for UPSERT SQL generation\")\n if not columns:\n raise ValueError(\"At least one column is required for UPSERT SQL generation\")\n if not key_columns:\n raise ValueError(\"key_columns are required for UPSERT SQL generation\")\n if not rows:\n raise ValueError(\"At least one row is required for UPSERT SQL generation\")\n\n col_list = \", \".join(columns)\n key_list = \", \".join(key_columns)\n values = _build_values_clause(columns, rows)\n\n table_ref = target_table\n if target_schema:\n table_ref = f\"{target_schema}.{target_table}\"\n\n # Build SET clause: exclude key columns from update\n update_cols = [c for c in columns if c not in key_columns]\n if not update_cols:\n # If only key columns, use DO NOTHING\n conflict_action = \"DO NOTHING\"\n else:\n set_parts = [f\"{col} = EXCLUDED.{col}\" for col in update_cols]\n conflict_action = \"DO UPDATE SET\\n\" + \",\\n\".join(set_parts)\n\n sql = (\n f\"INSERT INTO {table_ref} ({col_list})\\n\"\n f\"VALUES\\n\"\n f\"{values}\\n\"\n f\"ON CONFLICT ({key_list}) {conflict_action};\"\n )\n return sql\n# #endregion generate_upsert_sql\n\n\n# #region SQLGenerator [C:3] [TYPE Class]\n# @BRIEF Generate safe, dialect-appropriate SQL INSERT/UPSERT statements.\n# @PRE: Job has target_schema, target_table, key columns configured.\n# @POST: Returns generated SQL string for the target dialect.\nclass SQLGenerator:\n\n # region SQLGenerator.generate [TYPE Function]\n # @PURPOSE: Generate SQL for a set of rows, detecting dialect from the job configuration.\n # @PRE: dialect is a supported database dialect. columns list is non-empty. rows is non-empty.\n # @POST: Returns tuple of (sql_string, statement_count).\n # @SIDE_EFFECT: None — pure SQL generation.\n @staticmethod\n def generate(\n dialect: str,\n target_schema: str | None,\n target_table: str,\n columns: list[str],\n rows: list[dict[str, Any]],\n key_columns: list[str] | None = None,\n upsert_strategy: str = \"MERGE\",\n ) -> tuple[str, int]:\n \"\"\"Generate dialect-appropriate INSERT/UPSERT SQL.\n\n Args:\n dialect: Target database dialect (e.g. 'postgresql', 'clickhouse').\n target_schema: Optional schema name.\n target_table: Target table name.\n columns: List of column names to insert.\n rows: List of row dicts with column values.\n key_columns: Key columns for conflict resolution (UPSERT).\n upsert_strategy: 'MERGE' (UPSERT), 'INSERT' (plain INSERT).\n\n Returns:\n Tuple of (sql_string, row_count).\n \"\"\"\n with belief_scope(\"SQLGenerator.generate\"):\n logger.reason(\"Generating SQL\", {\n \"dialect\": dialect,\n \"schema\": target_schema,\n \"table\": target_table,\n \"columns\": len(columns),\n \"rows\": len(rows),\n \"strategy\": upsert_strategy,\n })\n\n # Validate inputs\n if not target_table:\n raise ValueError(\"target_table is required\")\n if not columns:\n raise ValueError(\"At least one column is required\")\n if not rows:\n raise ValueError(\"At least one row is required\")\n\n # Build fully qualified table reference\n table_ref = target_table\n if target_schema:\n quoted_schema = _quote_identifier(target_schema, dialect)\n quoted_table = _quote_identifier(target_table, dialect)\n table_ref = f\"{quoted_schema}.{quoted_table}\"\n else:\n table_ref = _quote_identifier(target_table, dialect)\n\n # Quote columns per dialect\n quoted_columns = [_quote_identifier(c, dialect) for c in columns]\n quoted_key_columns = (\n [_quote_identifier(k, dialect) for k in key_columns]\n if key_columns\n else []\n )\n\n # Generate SQL per dialect and strategy\n use_upsert = upsert_strategy.upper() == \"MERGE\" and key_columns\n\n if dialect in POSTGRESQL_DIALECTS or dialect not in CLICKHOUSE_DIALECTS:\n # PostgreSQL and other ANSI dialects: support UPSERT via ON CONFLICT\n if use_upsert:\n sql = generate_upsert_sql(\n target_schema=None,\n target_table=table_ref,\n columns=quoted_columns,\n key_columns=quoted_key_columns,\n rows=rows,\n )\n else:\n sql = generate_insert_sql(\n target_schema=None,\n target_table=table_ref,\n columns=quoted_columns,\n rows=rows,\n dialect=dialect,\n )\n elif dialect in CLICKHOUSE_DIALECTS:\n # ClickHouse: plain INSERT, no ON CONFLICT support\n sql = generate_insert_sql(\n target_schema=None,\n target_table=table_ref,\n columns=quoted_columns,\n rows=rows,\n dialect=dialect,\n )\n if use_upsert:\n logger.reason(\"ClickHouse UPSERT not supported; using plain INSERT\", {\n \"note\": \"ClickHouse does not support ON CONFLICT. Use ReplacingMergeTree for dedup.\",\n })\n else:\n # Fallback: plain INSERT\n sql = generate_insert_sql(\n target_schema=None,\n target_table=table_ref,\n columns=quoted_columns,\n rows=rows,\n dialect=dialect,\n )\n\n logger.reflect(\"SQL generated\", {\n \"dialect\": dialect,\n \"row_count\": len(rows),\n \"sql_length\": len(sql),\n })\n return sql, len(rows)\n # endregion SQLGenerator.generate\n\n # region SQLGenerator.generate_batch [TYPE Function]\n # @PURPOSE: Generate separate INSERT statements for each row (batch-safe version).\n # @PRE: Same as generate().\n # @POST: Returns list of (sql_string, row_index) tuples.\n @staticmethod\n def generate_batch(\n dialect: str,\n target_schema: str | None,\n target_table: str,\n columns: list[str],\n rows: list[dict[str, Any]],\n key_columns: list[str] | None = None,\n upsert_strategy: str = \"MERGE\",\n max_rows_per_statement: int = 500,\n ) -> list[tuple[str, int]]:\n \"\"\"Generate SQL in batches, splitting large row sets into multiple statements.\n\n Returns:\n List of (sql_string, row_count) tuples.\n \"\"\"\n with belief_scope(\"SQLGenerator.generate_batch\"):\n if not rows:\n return []\n\n statements = []\n for i in range(0, len(rows), max_rows_per_statement):\n chunk = rows[i:i + max_rows_per_statement]\n sql, count = SQLGenerator.generate(\n dialect=dialect,\n target_schema=target_schema,\n target_table=target_table,\n columns=columns,\n rows=chunk,\n key_columns=key_columns,\n upsert_strategy=upsert_strategy,\n )\n statements.append((sql, count))\n\n return statements\n # endregion SQLGenerator.generate_batch\n\n\n# #endregion SQLGenerator\n# #endregion SQLGenerator\n" + "body": "# #region SQLGenerator [C:3] [TYPE Module] [SEMANTICS clickhouse, translate, sql, insert, generate]\n# @BRIEF Dialect-aware safe SQL generation for INSERT/UPSERT operations.\n# @LAYER: Domain\n# @RELATION DEPENDS_ON -> [TranslationJob]\n# @RELATION DEPENDS_ON -> [TranslationRun]\n# @PRE: Job has target_schema and target_table configured. Dialect is one of supported SUPPORTED_DIALECTS.\n# @POST: Returns safe SQL strings for the target dialect.\n# @SIDE_EFFECT: None — pure code generation.\n# @RATIONALE: Dialect-aware SQL uses ON CONFLICT for PostgreSQL; plain INSERT for ClickHouse with documented limitations.\n# @REJECTED: UPDATE statements — source is append-only; UPSERT covers overwrite case.\n# @REJECTED: ORM-based insert bypasses Superset's SQL Lab audit trail.\n\nfrom datetime import UTC, datetime\nfrom typing import Any\n\nfrom ...core.logger import belief_scope, logger\n\n# PostgreSQL/Greenplum dialects that support ON CONFLICT\nPOSTGRESQL_DIALECTS = {\"postgresql\", \"redshift\", \"greenplum\"}\n# Dialects that use backtick or no quoting\nCLICKHOUSE_DIALECTS = {\"clickhouse\"}\n\n\n# #region _normalize_timestamp_value [C:2] [TYPE Function] [SEMANTICS translate,sql,timestamp]\n# @BRIEF Detect Unix timestamp strings (seconds or millis) and convert to 'YYYY-MM-DD' for Date columns.\ndef _normalize_timestamp_value(value: Any) -> str | None:\n \"\"\"Detect Unix timestamp values and convert to date string.\n\n Handles:\n - Integer/float Unix timestamps (seconds or milliseconds)\n - String representations of Unix timestamps (e.g. '1726358400000.0')\n\n Returns 'YYYY-MM-DD' if conversion succeeds, None if value is not a timestamp.\n \"\"\"\n # Try numeric conversion first\n try:\n ts = float(value)\n except (ValueError, TypeError):\n return None\n\n # Heuristic: Unix timestamps in seconds are ~10 digits (1e9 range for 2001-2033)\n # Unix timestamps in milliseconds are ~13 digits (1e12 range for 2001-2033)\n if 1e9 <= ts < 1e12:\n # Already in seconds\n pass\n elif 1e12 <= ts < 1e15:\n # Milliseconds — convert to seconds\n ts = ts / 1000.0\n else:\n # Not a plausible Unix timestamp\n return None\n\n try:\n dt = datetime.fromtimestamp(ts, tz=UTC)\n return dt.strftime(\"%Y-%m-%d\")\n except (OSError, OverflowError, ValueError):\n return None\n# #endregion _normalize_timestamp_value\n\n\n# #region _quote_identifier [C:4] [TYPE Function]\n# @BRIEF Quote an identifier per dialect rules. PostgreSQL uses double quotes; ClickHouse uses backticks.\n# @PRE: identifier is a non-empty string.\n# @POST: Returns safely quoted identifier.\ndef _quote_identifier(identifier: str, dialect: str) -> str:\n \"\"\"Quote a SQL identifier per dialect rules.\"\"\"\n if not identifier:\n return identifier\n # Remove any existing quotes to avoid double-quoting\n cleaned = identifier.strip().strip('\"').strip('`').strip('[]')\n if dialect in POSTGRESQL_DIALECTS:\n return f'\"{cleaned}\"'\n elif dialect in CLICKHOUSE_DIALECTS:\n return f\"`{cleaned}`\"\n else:\n # Generic ANSI double-quote\n return f'\"{cleaned}\"'\n# #endregion _quote_identifier\n\n\n# #region _encode_sql_value [C:2] [TYPE Function] [SEMANTICS translate,sql,encoding]\n# @BRIEF Encode a Python value into a SQL-safe literal for INSERT VALUES, with ClickHouse timestamp normalization.\ndef _encode_sql_value(value: Any, dialect: str | None = None) -> str:\n \"\"\"Encode a Python value into a SQL-safe literal.\n\n For ClickHouse dialect, attempts to detect Unix timestamp strings\n and convert them to 'YYYY-MM-DD' format for Date column compatibility.\n \"\"\"\n if value is None:\n return \"NULL\"\n if isinstance(value, bool):\n return \"TRUE\" if value else \"FALSE\"\n\n # For ClickHouse: try to normalize timestamp-like values (both string and numeric)\n if dialect in CLICKHOUSE_DIALECTS:\n if (isinstance(value, str) and value) or isinstance(value, (int, float)):\n normalized = _normalize_timestamp_value(value)\n if normalized:\n return f\"'{normalized}'\"\n\n if isinstance(value, (int, float)):\n return str(value)\n # String — escape single quotes by doubling them\n escaped = str(value).replace(\"'\", \"''\")\n return f\"'{escaped}'\"\n# #endregion _encode_sql_value\n\n\n# #region _build_values_clause [C:2] [TYPE Function] [SEMANTICS translate,sql,values]\n# @BRIEF Build a VALUES clause for multiple rows with per-column value encoding and dialect-aware quoting.\ndef _build_values_clause(columns: list[str], rows: list[dict[str, Any]], dialect: str | None = None) -> str:\n \"\"\"Build VALUES (...) clause for multiple rows.\n\n NOTE: columns may be quoted (e.g. '\"col\"' or '`col`') for the SQL column list,\n but row dicts have UNQUOTED keys. Strip quotes before value lookup.\n \"\"\"\n value_groups = []\n for row in rows:\n values = []\n for col in columns:\n # Strip quoting for value lookup — row keys are unquoted\n lookup_key = col.strip('\"').strip('`').strip('[]')\n val = row.get(lookup_key)\n values.append(_encode_sql_value(val, dialect=dialect))\n value_groups.append(f\"({', '.join(values)})\")\n return \",\\n\".join(value_groups)\n# #endregion _build_values_clause\n\n\n# #region generate_insert_sql [C:3] [TYPE Function] [SEMANTICS translate,sql,insert]\n# @BRIEF Generate a dialect-aware plain INSERT SQL statement for the given table, columns, and rows.\n# @RELATION DEPENDS_ON -> [_quote_identifier]\n# @RELATION DEPENDS_ON -> [_build_values_clause]\ndef generate_insert_sql(\n target_schema: str | None,\n target_table: str,\n columns: list[str],\n rows: list[dict[str, Any]],\n dialect: str | None = None,\n) -> str:\n \"\"\"Generate a plain INSERT SQL.\"\"\"\n with belief_scope(\"generate_insert_sql\"):\n if not target_table:\n raise ValueError(\"target_table is required for INSERT SQL generation\")\n if not columns:\n raise ValueError(\"At least one column is required for INSERT SQL generation\")\n if not rows:\n raise ValueError(\"At least one row is required for INSERT SQL generation\")\n\n col_list = \", \".join(columns)\n values = _build_values_clause(columns, rows, dialect=dialect)\n\n table_ref = target_table\n if target_schema:\n table_ref = f\"{target_schema}.{target_table}\"\n\n sql = f\"INSERT INTO {table_ref} ({col_list})\\nVALUES\\n{values};\"\n return sql\n# #endregion generate_insert_sql\n\n\n# #region generate_upsert_sql [C:4] [TYPE Function]\n# @BRIEF Generate PostgreSQL dialect UPSERT SQL with ON CONFLICT DO UPDATE.\n# @PRE dialect is postgresql-compatible. target_table, columns, key_columns are non-empty.\n# @POST Returns UPSERT SQL string or raises ValueError.\n# @COMPLEXITY 4\n\ndef generate_upsert_sql(\n target_schema: str | None,\n target_table: str,\n columns: list[str],\n key_columns: list[str],\n rows: list[dict[str, Any]],\n) -> str:\n \"\"\"Generate INSERT ... ON CONFLICT (key_cols) DO UPDATE SET ... SQL.\"\"\"\n with belief_scope(\"generate_upsert_sql\"):\n if not target_table:\n raise ValueError(\"target_table is required for UPSERT SQL generation\")\n if not columns:\n raise ValueError(\"At least one column is required for UPSERT SQL generation\")\n if not key_columns:\n raise ValueError(\"key_columns are required for UPSERT SQL generation\")\n if not rows:\n raise ValueError(\"At least one row is required for UPSERT SQL generation\")\n\n col_list = \", \".join(columns)\n key_list = \", \".join(key_columns)\n values = _build_values_clause(columns, rows)\n\n table_ref = target_table\n if target_schema:\n table_ref = f\"{target_schema}.{target_table}\"\n\n # Build SET clause: exclude key columns from update\n update_cols = [c for c in columns if c not in key_columns]\n if not update_cols:\n # If only key columns, use DO NOTHING\n conflict_action = \"DO NOTHING\"\n else:\n set_parts = [f\"{col} = EXCLUDED.{col}\" for col in update_cols]\n conflict_action = \"DO UPDATE SET\\n\" + \",\\n\".join(set_parts)\n\n sql = (\n f\"INSERT INTO {table_ref} ({col_list})\\n\"\n f\"VALUES\\n\"\n f\"{values}\\n\"\n f\"ON CONFLICT ({key_list}) {conflict_action};\"\n )\n return sql\n# #endregion generate_upsert_sql\n\n\n# #region SQLGenerator [C:3] [TYPE Class]\n# @BRIEF Generate safe, dialect-appropriate SQL INSERT/UPSERT statements.\n# @PRE: Job has target_schema, target_table, key columns configured.\n# @POST: Returns generated SQL string for the target dialect.\nclass SQLGenerator:\n\n # region SQLGenerator.generate [TYPE Function]\n # @PURPOSE: Generate SQL for a set of rows, detecting dialect from the job configuration.\n # @PRE: dialect is a supported database dialect. columns list is non-empty. rows is non-empty.\n # @POST: Returns tuple of (sql_string, statement_count).\n # @SIDE_EFFECT: None — pure SQL generation.\n @staticmethod\n def generate(\n dialect: str,\n target_schema: str | None,\n target_table: str,\n columns: list[str],\n rows: list[dict[str, Any]],\n key_columns: list[str] | None = None,\n upsert_strategy: str = \"MERGE\",\n ) -> tuple[str, int]:\n \"\"\"Generate dialect-appropriate INSERT/UPSERT SQL.\n\n Args:\n dialect: Target database dialect (e.g. 'postgresql', 'clickhouse').\n target_schema: Optional schema name.\n target_table: Target table name.\n columns: List of column names to insert.\n rows: List of row dicts with column values.\n key_columns: Key columns for conflict resolution (UPSERT).\n upsert_strategy: 'MERGE' (UPSERT), 'INSERT' (plain INSERT).\n\n Returns:\n Tuple of (sql_string, row_count).\n \"\"\"\n with belief_scope(\"SQLGenerator.generate\"):\n logger.reason(\"Generating SQL\", {\n \"dialect\": dialect,\n \"schema\": target_schema,\n \"table\": target_table,\n \"columns\": len(columns),\n \"rows\": len(rows),\n \"strategy\": upsert_strategy,\n })\n\n # Validate inputs\n if not target_table:\n raise ValueError(\"target_table is required\")\n if not columns:\n raise ValueError(\"At least one column is required\")\n if not rows:\n raise ValueError(\"At least one row is required\")\n\n # Build fully qualified table reference\n table_ref = target_table\n if target_schema:\n quoted_schema = _quote_identifier(target_schema, dialect)\n quoted_table = _quote_identifier(target_table, dialect)\n table_ref = f\"{quoted_schema}.{quoted_table}\"\n else:\n table_ref = _quote_identifier(target_table, dialect)\n\n # Quote columns per dialect\n quoted_columns = [_quote_identifier(c, dialect) for c in columns]\n quoted_key_columns = (\n [_quote_identifier(k, dialect) for k in key_columns]\n if key_columns\n else []\n )\n\n # Generate SQL per dialect and strategy\n use_upsert = upsert_strategy.upper() == \"MERGE\" and key_columns\n\n if dialect in POSTGRESQL_DIALECTS or dialect not in CLICKHOUSE_DIALECTS:\n # PostgreSQL and other ANSI dialects: support UPSERT via ON CONFLICT\n if use_upsert:\n sql = generate_upsert_sql(\n target_schema=None,\n target_table=table_ref,\n columns=quoted_columns,\n key_columns=quoted_key_columns,\n rows=rows,\n )\n else:\n sql = generate_insert_sql(\n target_schema=None,\n target_table=table_ref,\n columns=quoted_columns,\n rows=rows,\n dialect=dialect,\n )\n elif dialect in CLICKHOUSE_DIALECTS:\n # ClickHouse: plain INSERT, no ON CONFLICT support\n sql = generate_insert_sql(\n target_schema=None,\n target_table=table_ref,\n columns=quoted_columns,\n rows=rows,\n dialect=dialect,\n )\n if use_upsert:\n logger.reason(\"ClickHouse UPSERT not supported; using plain INSERT\", {\n \"note\": \"ClickHouse does not support ON CONFLICT. Use ReplacingMergeTree for dedup.\",\n })\n else:\n # Fallback: plain INSERT\n sql = generate_insert_sql(\n target_schema=None,\n target_table=table_ref,\n columns=quoted_columns,\n rows=rows,\n dialect=dialect,\n )\n\n logger.reflect(\"SQL generated\", {\n \"dialect\": dialect,\n \"row_count\": len(rows),\n \"sql_length\": len(sql),\n })\n return sql, len(rows)\n # endregion SQLGenerator.generate\n\n # region SQLGenerator.generate_batch [TYPE Function]\n # @PURPOSE: Generate separate INSERT statements for each row (batch-safe version).\n # @PRE: Same as generate().\n # @POST: Returns list of (sql_string, row_index) tuples.\n @staticmethod\n def generate_batch(\n dialect: str,\n target_schema: str | None,\n target_table: str,\n columns: list[str],\n rows: list[dict[str, Any]],\n key_columns: list[str] | None = None,\n upsert_strategy: str = \"MERGE\",\n max_rows_per_statement: int = 500,\n ) -> list[tuple[str, int]]:\n \"\"\"Generate SQL in batches, splitting large row sets into multiple statements.\n\n Returns:\n List of (sql_string, row_count) tuples.\n \"\"\"\n with belief_scope(\"SQLGenerator.generate_batch\"):\n if not rows:\n return []\n\n statements = []\n for i in range(0, len(rows), max_rows_per_statement):\n chunk = rows[i:i + max_rows_per_statement]\n sql, count = SQLGenerator.generate(\n dialect=dialect,\n target_schema=target_schema,\n target_table=target_table,\n columns=columns,\n rows=chunk,\n key_columns=key_columns,\n upsert_strategy=upsert_strategy,\n )\n statements.append((sql, count))\n\n return statements\n # endregion SQLGenerator.generate_batch\n\n\n# #endregion SQLGenerator\n# #endregion SQLGenerator\n" }, { "contract_id": "_normalize_timestamp_value", @@ -50659,9 +49907,10 @@ "file_path": "backend/src/plugins/translate/sql_generator.py", "start_line": 61, "end_line": 78, - "tier": "TIER_1", - "complexity": 1, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": 4, "POST": "Returns safely quoted identifier.", "PRE": "identifier is a non-empty string.", "PURPOSE": "Quote an identifier per dialect rules. PostgreSQL uses double quotes; ClickHouse uses backticks." @@ -50669,27 +49918,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region _quote_identifier [TYPE Function]\n# @BRIEF Quote an identifier per dialect rules. PostgreSQL uses double quotes; ClickHouse uses backticks.\n# @PRE: identifier is a non-empty string.\n# @POST: Returns safely quoted identifier.\ndef _quote_identifier(identifier: str, dialect: str) -> str:\n \"\"\"Quote a SQL identifier per dialect rules.\"\"\"\n if not identifier:\n return identifier\n # Remove any existing quotes to avoid double-quoting\n cleaned = identifier.strip().strip('\"').strip('`').strip('[]')\n if dialect in POSTGRESQL_DIALECTS:\n return f'\"{cleaned}\"'\n elif dialect in CLICKHOUSE_DIALECTS:\n return f\"`{cleaned}`\"\n else:\n # Generic ANSI double-quote\n return f'\"{cleaned}\"'\n# #endregion _quote_identifier\n" + "body": "# #region _quote_identifier [C:4] [TYPE Function]\n# @BRIEF Quote an identifier per dialect rules. PostgreSQL uses double quotes; ClickHouse uses backticks.\n# @PRE: identifier is a non-empty string.\n# @POST: Returns safely quoted identifier.\ndef _quote_identifier(identifier: str, dialect: str) -> str:\n \"\"\"Quote a SQL identifier per dialect rules.\"\"\"\n if not identifier:\n return identifier\n # Remove any existing quotes to avoid double-quoting\n cleaned = identifier.strip().strip('\"').strip('`').strip('[]')\n if dialect in POSTGRESQL_DIALECTS:\n return f'\"{cleaned}\"'\n elif dialect in CLICKHOUSE_DIALECTS:\n return f\"`{cleaned}`\"\n else:\n # Generic ANSI double-quote\n return f'\"{cleaned}\"'\n# #endregion _quote_identifier\n" }, { "contract_id": "_encode_sql_value", @@ -50763,10 +50012,11 @@ "contract_type": "Function", "file_path": "backend/src/plugins/translate/sql_generator.py", "start_line": 162, - "end_line": 208, - "tier": "TIER_1", - "complexity": 1, + "end_line": 210, + "tier": "TIER_2", + "complexity": 4, "metadata": { + "COMPLEXITY": "4", "POST": "Returns UPSERT SQL string or raises ValueError.", "PRE": "dialect is postgresql-compatible. target_table, columns, key_columns are non-empty.", "PURPOSE": "Generate PostgreSQL dialect UPSERT SQL with ON CONFLICT DO UPDATE." @@ -50774,27 +50024,27 @@ "relations": [], "schema_warnings": [ { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "RELATION", + "message": "@RELATION is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } }, { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Function' at C1", + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Function' at C4", "detail": { - "actual_complexity": 1, + "actual_complexity": 4, "contract_type": "Function" } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region generate_upsert_sql [TYPE Function]\n# @BRIEF Generate PostgreSQL dialect UPSERT SQL with ON CONFLICT DO UPDATE.\n# @PRE: dialect is postgresql-compatible. target_table, columns, key_columns are non-empty.\n# @POST: Returns UPSERT SQL string or raises ValueError.\ndef generate_upsert_sql(\n target_schema: str | None,\n target_table: str,\n columns: list[str],\n key_columns: list[str],\n rows: list[dict[str, Any]],\n) -> str:\n \"\"\"Generate INSERT ... ON CONFLICT (key_cols) DO UPDATE SET ... SQL.\"\"\"\n with belief_scope(\"generate_upsert_sql\"):\n if not target_table:\n raise ValueError(\"target_table is required for UPSERT SQL generation\")\n if not columns:\n raise ValueError(\"At least one column is required for UPSERT SQL generation\")\n if not key_columns:\n raise ValueError(\"key_columns are required for UPSERT SQL generation\")\n if not rows:\n raise ValueError(\"At least one row is required for UPSERT SQL generation\")\n\n col_list = \", \".join(columns)\n key_list = \", \".join(key_columns)\n values = _build_values_clause(columns, rows)\n\n table_ref = target_table\n if target_schema:\n table_ref = f\"{target_schema}.{target_table}\"\n\n # Build SET clause: exclude key columns from update\n update_cols = [c for c in columns if c not in key_columns]\n if not update_cols:\n # If only key columns, use DO NOTHING\n conflict_action = \"DO NOTHING\"\n else:\n set_parts = [f\"{col} = EXCLUDED.{col}\" for col in update_cols]\n conflict_action = \"DO UPDATE SET\\n\" + \",\\n\".join(set_parts)\n\n sql = (\n f\"INSERT INTO {table_ref} ({col_list})\\n\"\n f\"VALUES\\n\"\n f\"{values}\\n\"\n f\"ON CONFLICT ({key_list}) {conflict_action};\"\n )\n return sql\n# #endregion generate_upsert_sql\n" + "body": "# #region generate_upsert_sql [C:4] [TYPE Function]\n# @BRIEF Generate PostgreSQL dialect UPSERT SQL with ON CONFLICT DO UPDATE.\n# @PRE dialect is postgresql-compatible. target_table, columns, key_columns are non-empty.\n# @POST Returns UPSERT SQL string or raises ValueError.\n# @COMPLEXITY 4\n\ndef generate_upsert_sql(\n target_schema: str | None,\n target_table: str,\n columns: list[str],\n key_columns: list[str],\n rows: list[dict[str, Any]],\n) -> str:\n \"\"\"Generate INSERT ... ON CONFLICT (key_cols) DO UPDATE SET ... SQL.\"\"\"\n with belief_scope(\"generate_upsert_sql\"):\n if not target_table:\n raise ValueError(\"target_table is required for UPSERT SQL generation\")\n if not columns:\n raise ValueError(\"At least one column is required for UPSERT SQL generation\")\n if not key_columns:\n raise ValueError(\"key_columns are required for UPSERT SQL generation\")\n if not rows:\n raise ValueError(\"At least one row is required for UPSERT SQL generation\")\n\n col_list = \", \".join(columns)\n key_list = \", \".join(key_columns)\n values = _build_values_clause(columns, rows)\n\n table_ref = target_table\n if target_schema:\n table_ref = f\"{target_schema}.{target_table}\"\n\n # Build SET clause: exclude key columns from update\n update_cols = [c for c in columns if c not in key_columns]\n if not update_cols:\n # If only key columns, use DO NOTHING\n conflict_action = \"DO NOTHING\"\n else:\n set_parts = [f\"{col} = EXCLUDED.{col}\" for col in update_cols]\n conflict_action = \"DO UPDATE SET\\n\" + \",\\n\".join(set_parts)\n\n sql = (\n f\"INSERT INTO {table_ref} ({col_list})\\n\"\n f\"VALUES\\n\"\n f\"{values}\\n\"\n f\"ON CONFLICT ({key_list}) {conflict_action};\"\n )\n return sql\n# #endregion generate_upsert_sql\n" }, { "contract_id": "SupersetSqlLabExecutor", @@ -50806,7 +50056,7 @@ "complexity": 4, "metadata": { "COMPLEXITY": 4, - "LAYER": "Infra", + "LAYER": "Infrastructure", "POST": "SQL is submitted to Superset SQL Lab; execution reference is returned.", "PRE": "Valid Superset environment configuration and authenticated client.", "PURPOSE": "Submit SQL to Superset SQL Lab API and poll execution status.", @@ -50818,8 +50068,8 @@ { "source_id": "SupersetSqlLabExecutor", "relation_type": "DEPENDS_ON", - "target_id": "SupersetClient", - "target_ref": "[SupersetClient]" + "target_id": "ConfigManager", + "target_ref": "[ConfigManager]" }, { "source_id": "SupersetSqlLabExecutor", @@ -50828,28 +50078,10 @@ "target_ref": "[ConfigManager]" } ], - "schema_warnings": [ - { - "code": "invalid_enum_value", - "tag": "LAYER", - "message": "@LAYER value 'Infra' is not in allowed enum", - "detail": { - "allowed": [ - "Core", - "Domain", - "API", - "UI", - "Service", - "Infrastructure", - "Plugin" - ], - "value": "Infra" - } - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region SupersetSqlLabExecutor [C:4] [TYPE Module] [SEMANTICS translate, superset, sqllab, execute, query]\n# @BRIEF Submit SQL to Superset SQL Lab API and poll execution status.\n# @LAYER: Infra\n# @RELATION DEPENDS_ON -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [ConfigManager]\n# @PRE: Valid Superset environment configuration and authenticated client.\n# @POST: SQL is submitted to Superset SQL Lab; execution reference is returned.\n# @SIDE_EFFECT: Makes HTTP calls to Superset /api/v1/sqllab/execute/; polls status.\n# @RATIONALE: Direct SQL Lab API submission provides audit trail and execution monitoring within Superset.\n# @REJECTED: Direct database connection bypass — would skip Superset's SQL Lab audit and RBAC.\n\nimport json\nimport time\nimport uuid\nfrom typing import Any\n\nfrom ...core.config_manager import ConfigManager\nfrom ...core.logger import belief_scope, logger\nfrom ...core.superset_client import SupersetClient\n\n\n# #region SupersetSqlLabExecutor [C:4] [TYPE Class]\n# @BRIEF Submit SQL to Superset SQL Lab API with polling and status tracking.\n# @PRE: Valid environment ID and ConfigManager.\n# @POST: SQL submitted to Superset; execution reference recorded.\n# @SIDE_EFFECT: Makes HTTP POST to /api/v1/sqllab/execute/; polls GET for status.\nclass SupersetSqlLabExecutor:\n\n def __init__(self, config_manager: ConfigManager, env_id: str):\n self.config_manager = config_manager\n self.env_id = env_id\n self._client: SupersetClient | None = None\n self._database_id: int | None = None\n self._database_backend: str | None = None\n\n # region _get_client [TYPE Function]\n # @PURPOSE: Lazy-initialize SupersetClient for the configured environment.\n # @PRE: env_id must correspond to a valid environment config.\n # @POST: Returns authenticated SupersetClient.\n # @SIDE_EFFECT: Authenticates against Superset API.\n def _get_client(self) -> SupersetClient:\n with belief_scope(\"SupersetSqlLabExecutor._get_client\"):\n if self._client is not None:\n return self._client\n\n environments = self.config_manager.get_environments()\n env_config = next((e for e in environments if e.id == self.env_id), None)\n if not env_config:\n raise ValueError(f\"Superset environment '{self.env_id}' not found\")\n\n self._client = SupersetClient(env_config)\n return self._client\n # endregion _get_client\n\n # region resolve_database_id [TYPE Function]\n # @PURPOSE: Resolve the target database ID from the environment and fetch its backend engine.\n # @PRE: database_name or database_id should be known.\n # @POST: Returns database_id integer or raises ValueError. Also sets self._database_backend.\n # @SIDE_EFFECT: Fetches databases list from Superset; optionally fetches single DB for backend.\n def resolve_database_id(\n self,\n database_name: str | None = None,\n target_database_id: str | None = None,\n ) -> int:\n with belief_scope(\"SupersetSqlLabExecutor.resolve_database_id\"):\n client = self._get_client()\n\n # If a specific target_database_id is provided, use it directly\n if target_database_id:\n try:\n db_id = int(target_database_id)\n # Fetch full DB info to get backend\n db_info = client.get_database(db_id)\n result = db_info.get(\"result\", db_info)\n self._database_id = result.get(\"id\", db_id)\n self._database_backend = result.get(\"backend\") or result.get(\"engine\")\n logger.reason(\"Resolved database ID by target_database_id\", {\n \"target_database_id\": target_database_id,\n \"database_id\": self._database_id,\n \"backend\": self._database_backend,\n })\n return self._database_id\n except Exception as e:\n logger.explore(\"Failed to resolve by target_database_id, falling back\", {\n \"target_database_id\": target_database_id,\n \"error\": str(e),\n })\n # Fall through to default resolution\n\n # Fetch full database list with backend info\n _, databases = client.get_databases(\n query={\"columns\": [\"id\", \"database_name\", \"backend\"]}\n )\n if not databases:\n raise ValueError(\"No databases found in Superset environment\")\n\n if database_name:\n for db in databases:\n if db.get(\"database_name\", \"\").lower() == database_name.lower():\n self._database_id = db[\"id\"]\n self._database_backend = db.get(\"backend\")\n logger.reason(\"Resolved database ID by name\", {\n \"database_name\": database_name,\n \"database_id\": self._database_id,\n \"backend\": self._database_backend,\n })\n return self._database_id\n raise ValueError(\n f\"Database '{database_name}' not found in Superset environment\"\n )\n\n # Default: use first database\n self._database_id = databases[0][\"id\"]\n self._database_backend = databases[0].get(\"backend\")\n logger.reason(\"Using default database\", {\n \"database_name\": databases[0].get(\"database_name\"),\n \"database_id\": self._database_id,\n \"backend\": self._database_backend,\n })\n return self._database_id\n # endregion resolve_database_id\n\n # region get_database_backend [TYPE Function]\n # @PURPOSE: Return the cached database backend/engine string.\n # @POST: Returns backend string or None if not yet resolved.\n def get_database_backend(self) -> str | None:\n return self._database_backend\n # endregion get_database_backend\n\n # region execute_sql [TYPE Function]\n # @PURPOSE: Submit SQL to Superset SQL Lab and return execution tracking info.\n # @PRE: sql is valid SQL string. database_id is a valid Superset DB ID.\n # @POST: Returns execution result dict with query_id and status.\n # @SIDE_EFFECT: Makes HTTP POST to /api/v1/sqllab/execute/.\n def execute_sql(\n self,\n sql: str,\n database_id: int | None = None,\n run_async: bool = True,\n ) -> dict[str, Any]:\n with belief_scope(\"SupersetSqlLabExecutor.execute_sql\"):\n client = self._get_client()\n db_id = database_id or self._database_id\n if not db_id:\n db_id = self.resolve_database_id()\n\n logger.reason(\"Submitting SQL to Superset SQL Lab\", {\n \"database_id\": db_id,\n \"sql_length\": len(sql),\n \"run_async\": run_async,\n })\n\n payload = {\n \"database_id\": db_id,\n \"sql\": sql,\n \"runAsync\": run_async,\n \"schema\": None,\n \"tab\": \"translation-insert\",\n \"client_id\": f\"trl-{uuid.uuid4().hex[:7]}\", # max 11 chars for Superset varchar(11)\n }\n\n # Try multiple SQL Lab endpoints — some Superset versions use /sqllab/execute/,\n # others use /sql_lab/execute/ (with underscore)\n candidate_endpoints = [\"/api/v1/sqllab/execute/\", \"/api/v1/sql_lab/execute/\"]\n response = None\n last_error = None\n for endpoint in candidate_endpoints:\n try:\n response = client.network.request(\n method=\"POST\",\n endpoint=endpoint,\n data=json.dumps(payload),\n headers={\"Content-Type\": \"application/json\"},\n )\n if isinstance(response, dict) and response:\n logger.reason(\"SQL Lab endpoint succeeded\", extra={\n \"endpoint\": endpoint,\n })\n break\n except Exception as ep_err:\n last_error = ep_err\n logger.explore(\"SQL Lab endpoint failed, trying next\", extra={\n \"error\": str(ep_err),\n \"endpoint\": endpoint,\n })\n response = None\n\n if response is None:\n error_msg = f\"All SQL Lab endpoints failed. Last error: {last_error}\"\n logger.explore(\"SQL Lab execute failed\", extra={\"error\": error_msg})\n raise ValueError(f\"Superset SQL Lab execute failed: {error_msg}\")\n\n # Parse response — try multiple known Superset response formats\n result = response if isinstance(response, dict) else {}\n\n # Superset may return query_id at top level, nested in \"result\", as \"id\", or in \"query\" block\n query_id = (\n result.get(\"query_id\")\n or result.get(\"id\")\n or (result.get(\"result\") or {}).get(\"query_id\")\n or (result.get(\"result\") or {}).get(\"id\")\n or (result.get(\"query\") or {}).get(\"query_id\")\n or (result.get(\"query\") or {}).get(\"id\")\n )\n status = result.get(\"status\", \"unknown\")\n\n # Log full response for debugging if query_id is missing\n if not query_id:\n logger.explore(\"No query_id from SQL Lab execute\", extra={\n \"database_id\": db_id,\n \"status\": status,\n \"raw_response_keys\": list(result.keys()),\n \"raw_response_preview\": json.dumps(result)[:2000],\n })\n logger.reason(\"SQL Lab execute response (no query_id)\", extra={\n \"database_id\": db_id,\n \"status\": status,\n \"response_keys\": list(result.keys()),\n \"has_result\": \"result\" in result,\n \"has_query\": \"query\" in result,\n \"raw_preview\": json.dumps(result)[:2000],\n })\n\n logger.reason(\"SQL Lab execute response\", {\n \"query_id\": query_id,\n \"status\": status,\n \"response_keys\": list(result.keys()),\n })\n\n return {\n \"query_id\": query_id,\n \"status\": status,\n \"raw_response\": result,\n \"database_id\": db_id,\n }\n # endregion execute_sql\n\n # region poll_execution_status [TYPE Function]\n # @PURPOSE: Poll Superset for SQL execution status until completion or timeout.\n # @PRE: query_id is a valid Superset query ID.\n # @POST: Returns final execution status dict.\n # @SIDE_EFFECT: Makes HTTP GET requests to Superset.\n def poll_execution_status(\n self,\n query_id: str,\n max_polls: int = 60,\n poll_interval_seconds: float = 2.0,\n ) -> dict[str, Any]:\n with belief_scope(\"SupersetSqlLabExecutor.poll_execution_status\"):\n client = self._get_client()\n\n logger.reason(\"Polling SQL execution status\", {\n \"query_id\": query_id,\n \"max_polls\": max_polls,\n \"interval\": poll_interval_seconds,\n })\n\n for attempt in range(max_polls):\n try:\n response = client.network.request(\n method=\"GET\",\n endpoint=f\"/api/v1/query/{query_id}\",\n )\n raw = response if isinstance(response, dict) else {}\n # Superset wraps query data in a nested \"result\" field\n result = raw.get(\"result\", raw)\n status = result.get(\"status\", \"unknown\")\n state = result.get(\"state\", result.get(\"status\", \"\"))\n\n # Terminal states\n if state in (\"success\", \"finished\", \"completed\"):\n logger.reason(\"SQL execution completed\", {\n \"query_id\": query_id,\n \"attempt\": attempt + 1,\n \"rows_affected\": result.get(\"rows\"),\n })\n return {\n \"query_id\": query_id,\n \"status\": \"success\",\n \"state\": state,\n \"rows_affected\": result.get(\"rows\"),\n \"error_message\": result.get(\"error_message\"),\n \"results\": result.get(\"results\"),\n \"completed_on\": result.get(\"completed_on\"),\n }\n\n if state in (\"failed\", \"error\", \"stopped\"):\n error_msg = result.get(\"error_message\", \"Unknown error\")\n logger.explore(\"SQL execution failed\", {\n \"query_id\": query_id,\n \"state\": state,\n \"error\": error_msg,\n })\n return {\n \"query_id\": query_id,\n \"status\": \"failed\",\n \"state\": state,\n \"error_message\": error_msg,\n \"results\": None,\n }\n\n if state in (\"pending\", \"running\", \"started\"):\n time.sleep(poll_interval_seconds)\n continue\n\n # Unknown state — treat as still running\n time.sleep(poll_interval_seconds)\n\n except Exception as e:\n logger.explore(\"Polling error, retrying\", {\n \"query_id\": query_id,\n \"attempt\": attempt + 1,\n \"error\": str(e),\n })\n time.sleep(poll_interval_seconds)\n continue\n\n # Timeout\n logger.explore(\"SQL execution polling timed out\", {\n \"query_id\": query_id,\n \"max_polls\": max_polls,\n })\n return {\n \"query_id\": query_id,\n \"status\": \"timeout\",\n \"error_message\": f\"Polling timed out after {max_polls} attempts\",\n \"results\": None,\n }\n # endregion poll_execution_status\n\n # region execute_and_poll [TYPE Function]\n # @PURPOSE: Execute SQL and wait for completion. One-shot convenience method.\n # @PRE: sql is valid SQL.\n # @POST: Returns final execution result.\n # @SIDE_EFFECT: Makes HTTP calls to Superset API.\n def execute_and_poll(\n self,\n sql: str,\n database_id: int | None = None,\n max_polls: int = 60,\n poll_interval_seconds: float = 2.0,\n ) -> dict[str, Any]:\n with belief_scope(\"SupersetSqlLabExecutor.execute_and_poll\"):\n exec_result = self.execute_sql(\n sql=sql,\n database_id=database_id,\n run_async=False, # Sync mode — Superset returns result directly\n )\n\n status = exec_result.get(\"status\", \"unknown\")\n\n # Sync mode: response already has the final status and data\n if status == \"success\":\n logger.reason(\"SQL execution completed (sync)\", {\n \"query_id\": exec_result.get(\"query_id\"),\n })\n return {\n \"query_id\": exec_result.get(\"query_id\"),\n \"status\": \"success\",\n \"state\": \"success\",\n \"rows_affected\": exec_result.get(\"raw_response\", {}).get(\"query\", {}).get(\"rows\"),\n \"error_message\": None,\n \"results\": exec_result.get(\"raw_response\", {}).get(\"data\"),\n \"completed_on\": exec_result.get(\"raw_response\", {}).get(\"query\", {}).get(\"endDttm\"),\n }\n\n # For async mode (fallback): poll for completion\n query_id = exec_result.get(\"query_id\")\n if not query_id:\n logger.explore(\"No query_id from SQL Lab execute\", {\n \"raw_response\": exec_result.get(\"raw_response\"),\n })\n return {\n \"status\": \"failed\",\n \"error_message\": \"No query_id returned from SQL Lab\",\n \"query_id\": None,\n }\n\n return self.poll_execution_status(\n query_id=str(query_id),\n max_polls=max_polls,\n poll_interval_seconds=poll_interval_seconds,\n )\n # endregion execute_and_poll\n\n # region get_query_results [TYPE Function]\n # @PURPOSE: Fetch the results of a completed query.\n # @PRE: query_id is a valid Superset query ID.\n # @POST: Returns query results if available.\n # @SIDE_EFFECT: Makes HTTP GET to Superset.\n def get_query_results(self, query_id: str) -> dict[str, Any]:\n with belief_scope(\"SupersetSqlLabExecutor.get_query_results\"):\n client = self._get_client()\n try:\n response = client.network.request(\n method=\"GET\",\n endpoint=f\"/api/v1/query/{query_id}/results\",\n )\n result = response if isinstance(response, dict) else {}\n return {\n \"query_id\": query_id,\n \"status\": \"success\" if result.get(\"results\") else \"no_results\",\n \"results\": result.get(\"results\"),\n }\n except Exception as e:\n logger.explore(\"Failed to fetch query results\", {\n \"query_id\": query_id,\n \"error\": str(e),\n })\n return {\n \"query_id\": query_id,\n \"status\": \"failed\",\n \"error_message\": str(e),\n \"results\": None,\n }\n # endregion get_query_results\n\n\n# #endregion SupersetSqlLabExecutor\n# #endregion SupersetSqlLabExecutor\n" + "body": "# #region SupersetSqlLabExecutor [C:4] [TYPE Module] [SEMANTICS translate, superset, sqllab, execute, query]\n# @BRIEF Submit SQL to Superset SQL Lab API and poll execution status.\n# @LAYER Infrastructure\n# @RELATION DEPENDS_ON -> [ConfigManager]\n# @RELATION DEPENDS_ON -> [ConfigManager]\n# @PRE Valid Superset environment configuration and authenticated client.\n# @POST SQL is submitted to Superset SQL Lab; execution reference is returned.\n# @SIDE_EFFECT Makes HTTP calls to Superset /api/v1/sqllab/execute/; polls status.\n# @RATIONALE Direct SQL Lab API submission provides audit trail and execution monitoring within Superset.\n# @REJECTED Direct database connection bypass — would skip Superset's SQL Lab audit and RBAC.\n\nimport json\nimport time\nimport uuid\nfrom typing import Any\n\nfrom ...core.config_manager import ConfigManager\nfrom ...core.logger import belief_scope, logger\nfrom ...core.superset_client import SupersetClient\n\n\n# #region SupersetSqlLabExecutor [C:4] [TYPE Class]\n# @BRIEF Submit SQL to Superset SQL Lab API with polling and status tracking.\n# @PRE Valid environment ID and ConfigManager.\n# @POST SQL submitted to Superset; execution reference recorded.\n# @SIDE_EFFECT Makes HTTP POST to /api/v1/sqllab/execute/; polls GET for status.\nclass SupersetSqlLabExecutor:\n\n def __init__(self, config_manager: ConfigManager, env_id: str):\n self.config_manager = config_manager\n self.env_id = env_id\n self._client: SupersetClient | None = None\n self._database_id: int | None = None\n self._database_backend: str | None = None\n\n # region _get_client [TYPE Function]\n # @PURPOSE Lazy-initialize SupersetClient for the configured environment.\n # @PRE env_id must correspond to a valid environment config.\n # @POST Returns authenticated SupersetClient.\n # @SIDE_EFFECT Authenticates against Superset API.\n def _get_client(self) -> SupersetClient:\n with belief_scope(\"SupersetSqlLabExecutor._get_client\"):\n if self._client is not None:\n return self._client\n\n environments = self.config_manager.get_environments()\n env_config = next((e for e in environments if e.id == self.env_id), None)\n if not env_config:\n raise ValueError(f\"Superset environment '{self.env_id}' not found\")\n\n self._client = SupersetClient(env_config)\n return self._client\n # endregion _get_client\n\n # region resolve_database_id [TYPE Function]\n # @PURPOSE Resolve the target database ID from the environment and fetch its backend engine.\n # @PRE database_name or database_id should be known.\n # @POST Returns database_id integer or raises ValueError. Also sets self._database_backend.\n # @SIDE_EFFECT Fetches databases list from Superset; optionally fetches single DB for backend.\n def resolve_database_id(\n self,\n database_name: str | None = None,\n target_database_id: str | None = None,\n ) -> int:\n with belief_scope(\"SupersetSqlLabExecutor.resolve_database_id\"):\n client = self._get_client()\n\n # If a specific target_database_id is provided, use it directly\n if target_database_id:\n try:\n db_id = int(target_database_id)\n # Fetch full DB info to get backend\n db_info = client.get_database(db_id)\n result = db_info.get(\"result\", db_info)\n self._database_id = result.get(\"id\", db_id)\n self._database_backend = result.get(\"backend\") or result.get(\"engine\")\n logger.reason(\"Resolved database ID by target_database_id\", {\n \"target_database_id\": target_database_id,\n \"database_id\": self._database_id,\n \"backend\": self._database_backend,\n })\n return self._database_id\n except Exception as e:\n logger.explore(\"Failed to resolve by target_database_id, falling back\", {\n \"target_database_id\": target_database_id,\n \"error\": str(e),\n })\n # Fall through to default resolution\n\n # Fetch full database list with backend info\n _, databases = client.get_databases(\n query={\"columns\": [\"id\", \"database_name\", \"backend\"]}\n )\n if not databases:\n raise ValueError(\"No databases found in Superset environment\")\n\n if database_name:\n for db in databases:\n if db.get(\"database_name\", \"\").lower() == database_name.lower():\n self._database_id = db[\"id\"]\n self._database_backend = db.get(\"backend\")\n logger.reason(\"Resolved database ID by name\", {\n \"database_name\": database_name,\n \"database_id\": self._database_id,\n \"backend\": self._database_backend,\n })\n return self._database_id\n raise ValueError(\n f\"Database '{database_name}' not found in Superset environment\"\n )\n\n # Default: use first database\n self._database_id = databases[0][\"id\"]\n self._database_backend = databases[0].get(\"backend\")\n logger.reason(\"Using default database\", {\n \"database_name\": databases[0].get(\"database_name\"),\n \"database_id\": self._database_id,\n \"backend\": self._database_backend,\n })\n return self._database_id\n # endregion resolve_database_id\n\n # region get_database_backend [TYPE Function]\n # @PURPOSE Return the cached database backend/engine string.\n # @POST Returns backend string or None if not yet resolved.\n def get_database_backend(self) -> str | None:\n return self._database_backend\n # endregion get_database_backend\n\n # region execute_sql [TYPE Function]\n # @PURPOSE Submit SQL to Superset SQL Lab and return execution tracking info.\n # @PRE sql is valid SQL string. database_id is a valid Superset DB ID.\n # @POST Returns execution result dict with query_id and status.\n # @SIDE_EFFECT Makes HTTP POST to /api/v1/sqllab/execute/.\n def execute_sql(\n self,\n sql: str,\n database_id: int | None = None,\n run_async: bool = True,\n ) -> dict[str, Any]:\n with belief_scope(\"SupersetSqlLabExecutor.execute_sql\"):\n client = self._get_client()\n db_id = database_id or self._database_id\n if not db_id:\n db_id = self.resolve_database_id()\n\n logger.reason(\"Submitting SQL to Superset SQL Lab\", {\n \"database_id\": db_id,\n \"sql_length\": len(sql),\n \"run_async\": run_async,\n })\n\n payload = {\n \"database_id\": db_id,\n \"sql\": sql,\n \"runAsync\": run_async,\n \"schema\": None,\n \"tab\": \"translation-insert\",\n \"client_id\": f\"trl-{uuid.uuid4().hex[:7]}\", # max 11 chars for Superset varchar(11)\n }\n\n # Try multiple SQL Lab endpoints — some Superset versions use /sqllab/execute/,\n # others use /sql_lab/execute/ (with underscore)\n candidate_endpoints = [\"/api/v1/sqllab/execute/\", \"/api/v1/sql_lab/execute/\"]\n response = None\n last_error = None\n for endpoint in candidate_endpoints:\n try:\n response = client.network.request(\n method=\"POST\",\n endpoint=endpoint,\n data=json.dumps(payload),\n headers={\"Content-Type\": \"application/json\"},\n )\n if isinstance(response, dict) and response:\n logger.reason(\"SQL Lab endpoint succeeded\", extra={\n \"endpoint\": endpoint,\n })\n break\n except Exception as ep_err:\n last_error = ep_err\n logger.explore(\"SQL Lab endpoint failed, trying next\", extra={\n \"error\": str(ep_err),\n \"endpoint\": endpoint,\n })\n response = None\n\n if response is None:\n error_msg = f\"All SQL Lab endpoints failed. Last error: {last_error}\"\n logger.explore(\"SQL Lab execute failed\", extra={\"error\": error_msg})\n raise ValueError(f\"Superset SQL Lab execute failed: {error_msg}\")\n\n # Parse response — try multiple known Superset response formats\n result = response if isinstance(response, dict) else {}\n\n # Superset may return query_id at top level, nested in \"result\", as \"id\", or in \"query\" block\n query_id = (\n result.get(\"query_id\")\n or result.get(\"id\")\n or (result.get(\"result\") or {}).get(\"query_id\")\n or (result.get(\"result\") or {}).get(\"id\")\n or (result.get(\"query\") or {}).get(\"query_id\")\n or (result.get(\"query\") or {}).get(\"id\")\n )\n status = result.get(\"status\", \"unknown\")\n\n # Log full response for debugging if query_id is missing\n if not query_id:\n logger.explore(\"No query_id from SQL Lab execute\", extra={\n \"database_id\": db_id,\n \"status\": status,\n \"raw_response_keys\": list(result.keys()),\n \"raw_response_preview\": json.dumps(result)[:2000],\n })\n logger.reason(\"SQL Lab execute response (no query_id)\", extra={\n \"database_id\": db_id,\n \"status\": status,\n \"response_keys\": list(result.keys()),\n \"has_result\": \"result\" in result,\n \"has_query\": \"query\" in result,\n \"raw_preview\": json.dumps(result)[:2000],\n })\n\n logger.reason(\"SQL Lab execute response\", {\n \"query_id\": query_id,\n \"status\": status,\n \"response_keys\": list(result.keys()),\n })\n\n return {\n \"query_id\": query_id,\n \"status\": status,\n \"raw_response\": result,\n \"database_id\": db_id,\n }\n # endregion execute_sql\n\n # region poll_execution_status [TYPE Function]\n # @PURPOSE Poll Superset for SQL execution status until completion or timeout.\n # @PRE query_id is a valid Superset query ID.\n # @POST Returns final execution status dict.\n # @SIDE_EFFECT Makes HTTP GET requests to Superset.\n def poll_execution_status(\n self,\n query_id: str,\n max_polls: int = 60,\n poll_interval_seconds: float = 2.0,\n ) -> dict[str, Any]:\n with belief_scope(\"SupersetSqlLabExecutor.poll_execution_status\"):\n client = self._get_client()\n\n logger.reason(\"Polling SQL execution status\", {\n \"query_id\": query_id,\n \"max_polls\": max_polls,\n \"interval\": poll_interval_seconds,\n })\n\n for attempt in range(max_polls):\n try:\n response = client.network.request(\n method=\"GET\",\n endpoint=f\"/api/v1/query/{query_id}\",\n )\n raw = response if isinstance(response, dict) else {}\n # Superset wraps query data in a nested \"result\" field\n result = raw.get(\"result\", raw)\n status = result.get(\"status\", \"unknown\")\n state = result.get(\"state\", result.get(\"status\", \"\"))\n\n # Terminal states\n if state in (\"success\", \"finished\", \"completed\"):\n logger.reason(\"SQL execution completed\", {\n \"query_id\": query_id,\n \"attempt\": attempt + 1,\n \"rows_affected\": result.get(\"rows\"),\n })\n return {\n \"query_id\": query_id,\n \"status\": \"success\",\n \"state\": state,\n \"rows_affected\": result.get(\"rows\"),\n \"error_message\": result.get(\"error_message\"),\n \"results\": result.get(\"results\"),\n \"completed_on\": result.get(\"completed_on\"),\n }\n\n if state in (\"failed\", \"error\", \"stopped\"):\n error_msg = result.get(\"error_message\", \"Unknown error\")\n logger.explore(\"SQL execution failed\", {\n \"query_id\": query_id,\n \"state\": state,\n \"error\": error_msg,\n })\n return {\n \"query_id\": query_id,\n \"status\": \"failed\",\n \"state\": state,\n \"error_message\": error_msg,\n \"results\": None,\n }\n\n if state in (\"pending\", \"running\", \"started\"):\n time.sleep(poll_interval_seconds)\n continue\n\n # Unknown state — treat as still running\n time.sleep(poll_interval_seconds)\n\n except Exception as e:\n logger.explore(\"Polling error, retrying\", {\n \"query_id\": query_id,\n \"attempt\": attempt + 1,\n \"error\": str(e),\n })\n time.sleep(poll_interval_seconds)\n continue\n\n # Timeout\n logger.explore(\"SQL execution polling timed out\", {\n \"query_id\": query_id,\n \"max_polls\": max_polls,\n })\n return {\n \"query_id\": query_id,\n \"status\": \"timeout\",\n \"error_message\": f\"Polling timed out after {max_polls} attempts\",\n \"results\": None,\n }\n # endregion poll_execution_status\n\n # region execute_and_poll [TYPE Function]\n # @PURPOSE Execute SQL and wait for completion. One-shot convenience method.\n # @PRE sql is valid SQL.\n # @POST Returns final execution result.\n # @SIDE_EFFECT Makes HTTP calls to Superset API.\n def execute_and_poll(\n self,\n sql: str,\n database_id: int | None = None,\n max_polls: int = 60,\n poll_interval_seconds: float = 2.0,\n ) -> dict[str, Any]:\n with belief_scope(\"SupersetSqlLabExecutor.execute_and_poll\"):\n exec_result = self.execute_sql(\n sql=sql,\n database_id=database_id,\n run_async=False, # Sync mode — Superset returns result directly\n )\n\n status = exec_result.get(\"status\", \"unknown\")\n\n # Sync mode: response already has the final status and data\n if status == \"success\":\n logger.reason(\"SQL execution completed (sync)\", {\n \"query_id\": exec_result.get(\"query_id\"),\n })\n return {\n \"query_id\": exec_result.get(\"query_id\"),\n \"status\": \"success\",\n \"state\": \"success\",\n \"rows_affected\": exec_result.get(\"raw_response\", {}).get(\"query\", {}).get(\"rows\"),\n \"error_message\": None,\n \"results\": exec_result.get(\"raw_response\", {}).get(\"data\"),\n \"completed_on\": exec_result.get(\"raw_response\", {}).get(\"query\", {}).get(\"endDttm\"),\n }\n\n # For async mode (fallback): poll for completion\n query_id = exec_result.get(\"query_id\")\n if not query_id:\n logger.explore(\"No query_id from SQL Lab execute\", {\n \"raw_response\": exec_result.get(\"raw_response\"),\n })\n return {\n \"status\": \"failed\",\n \"error_message\": \"No query_id returned from SQL Lab\",\n \"query_id\": None,\n }\n\n return self.poll_execution_status(\n query_id=str(query_id),\n max_polls=max_polls,\n poll_interval_seconds=poll_interval_seconds,\n )\n # endregion execute_and_poll\n\n # region get_query_results [TYPE Function]\n # @PURPOSE Fetch the results of a completed query.\n # @PRE query_id is a valid Superset query ID.\n # @POST Returns query results if available.\n # @SIDE_EFFECT Makes HTTP GET to Superset.\n def get_query_results(self, query_id: str) -> dict[str, Any]:\n with belief_scope(\"SupersetSqlLabExecutor.get_query_results\"):\n client = self._get_client()\n try:\n response = client.network.request(\n method=\"GET\",\n endpoint=f\"/api/v1/query/{query_id}/results\",\n )\n result = response if isinstance(response, dict) else {}\n return {\n \"query_id\": query_id,\n \"status\": \"success\" if result.get(\"results\") else \"no_results\",\n \"results\": result.get(\"results\"),\n }\n except Exception as e:\n logger.explore(\"Failed to fetch query results\", {\n \"query_id\": query_id,\n \"error\": str(e),\n })\n return {\n \"query_id\": query_id,\n \"status\": \"failed\",\n \"error_message\": str(e),\n \"results\": None,\n }\n # endregion get_query_results\n\n\n# #endregion SupersetSqlLabExecutor\n# #endregion SupersetSqlLabExecutor\n" }, { "contract_id": "SchemasPackage", @@ -52090,10 +51322,10 @@ "file_path": "backend/src/schemas/translate.py", "start_line": 1, "end_line": 688, - "tier": "TIER_1", - "complexity": 2, + "tier": "TIER_2", + "complexity": 3, "metadata": { - "COMPLEXITY": 2, + "COMPLEXITY": 3, "LAYER": "API", "PURPOSE": "Pydantic v2 schemas for translation API request/response serialization." }, @@ -52105,20 +51337,10 @@ "target_ref": "pydantic" } ], - "schema_warnings": [ - { - "code": "tag_forbidden_by_complexity", - "tag": "RELATION", - "message": "@RELATION is forbidden for contract type 'Module' at C2", - "detail": { - "actual_complexity": 2, - "contract_type": "Module" - } - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region TranslateSchemas [C:2] [TYPE Module] [SEMANTICS pydantic, translate, schema, translate-job-create]\n# @BRIEF Pydantic v2 schemas for translation API request/response serialization.\n# @LAYER: API\n# @RELATION DEPENDS_ON -> pydantic\n\nfrom datetime import datetime\nfrom typing import Any\n\nimport re\n\nfrom pydantic import BaseModel, Field, field_validator\n\n\ndef _validate_bcp47_list(v: list[str] | None) -> list[str] | None:\n \"\"\"Validate that each item in target_languages is a valid BCP-47 tag.\"\"\"\n if not v:\n return v\n for tag in v:\n if not tag or not tag.strip():\n raise ValueError(f\"Invalid BCP-47 tag: '{tag}' — must be a non-empty string\")\n if not re.match(r'^[a-zA-Z]{2,8}(-[a-zA-Z0-9]{1,8})*$', tag.strip()):\n raise ValueError(\n f\"Invalid BCP-47 tag: '{tag}'. \"\n \"Expected format like 'en', 'ru', 'zh-CN', 'pt-BR'.\"\n )\n return v\n\n\n# #region TranslateJobCreate [TYPE Class]\n# @BRIEF Schema for creating a new translation job.\nclass TranslateJobCreate(BaseModel):\n name: str\n description: str | None = None\n source_dialect: str = Field(..., description=\"Source database dialect (e.g. postgresql, clickhouse)\")\n target_dialect: str = Field(..., description=\"Target database dialect (e.g. postgresql, clickhouse)\")\n database_dialect: str | None = Field(None, description=\"Detected dialect from Superset connection at save time\")\n source_datasource_id: str | None = Field(None, description=\"Superset datasource ID\")\n source_table: str | None = Field(None, description=\"Source table name\")\n target_schema: str | None = Field(None, description=\"Target table schema\")\n target_table: str | None = Field(None, description=\"Target table name\")\n source_key_cols: list[str] | None = Field(default_factory=list, description=\"Source key column names\")\n target_key_cols: list[str] | None = Field(default_factory=list, description=\"Target key column names\")\n translation_column: str | None = Field(None, description=\"Source column to translate\")\n target_column: str | None = Field(None, description=\"Target column for translated output (defaults to translation_column)\")\n target_language_column: str | None = Field(None, description=\"Target column for language code (e.g. 'ru', 'en')\")\n target_source_column: str | None = Field(None, description=\"Target column for source/original text\")\n target_source_language_column: str | None = Field(None, description=\"Target column for detected source language (BCP-47)\")\n context_columns: list[str] | None = Field(default_factory=list, description=\"Context column names\")\n target_language: str | None = Field(None, description=\"Target language code [DEPRECATED: use target_languages]\")\n target_languages: list[str] | None = Field(default_factory=list, description=\"List of BCP-47 target language codes\")\n provider_id: str | None = Field(None, description=\"LLM provider ID\")\n\n _validate_target_languages = field_validator(\"target_languages\")(_validate_bcp47_list)\n batch_size: int = Field(50, description=\"Records per batch\")\n disable_reasoning: bool = Field(False, description=\"If true, pass reasoning_effort:none to LLM to save output tokens\")\n upsert_strategy: str = Field(\"MERGE\", description=\"UPSERT strategy: MERGE, INSERT, UPDATE\")\n dictionary_ids: list[str] | None = Field(default_factory=list, description=\"Associated terminology dictionary IDs\")\n environment_id: str | None = Field(None, description=\"Superset environment ID\")\n target_database_id: str | None = Field(None, description=\"Superset database ID for SQL Lab insert target\")\n# #endregion TranslateJobCreate\n\n\n# #region TranslateJobUpdate [TYPE Class]\n# @BRIEF Schema for updating an existing translation job.\nclass TranslateJobUpdate(BaseModel):\n name: str | None = None\n description: str | None = None\n source_dialect: str | None = None\n target_dialect: str | None = None\n database_dialect: str | None = None\n source_datasource_id: str | None = None\n source_table: str | None = None\n target_schema: str | None = None\n target_table: str | None = None\n source_key_cols: list[str] | None = None\n target_key_cols: list[str] | None = None\n translation_column: str | None = None\n target_column: str | None = None\n target_language_column: str | None = None\n target_source_column: str | None = None\n target_source_language_column: str | None = None\n context_columns: list[str] | None = None\n target_language: str | None = None\n target_languages: list[str] | None = None\n provider_id: str | None = None\n\n _validate_target_languages = field_validator(\"target_languages\")(_validate_bcp47_list)\n batch_size: int | None = None\n disable_reasoning: bool | None = None\n upsert_strategy: str | None = None\n status: str | None = None\n dictionary_ids: list[str] | None = None\n environment_id: str | None = None\n target_database_id: str | None = None\n# #endregion TranslateJobUpdate\n\n\n# #region TranslateJobResponse [TYPE Class]\n# @BRIEF Schema for translation job API responses.\nclass TranslateJobResponse(BaseModel):\n id: str\n name: str\n description: str | None = None\n source_dialect: str\n target_dialect: str\n database_dialect: str | None = None\n source_datasource_id: str | None = None\n source_table: str | None = None\n target_schema: str | None = None\n target_table: str | None = None\n source_key_cols: list[str] | None = None\n target_key_cols: list[str] | None = None\n translation_column: str | None = None\n target_column: str | None = None\n target_language_column: str | None = None\n target_source_column: str | None = None\n target_source_language_column: str | None = None\n context_columns: list[str] | None = None\n # source_language removed — deprecated, per-row auto-detected\n target_languages: list[str] | None = None\n provider_id: str | None = None\n batch_size: int = 50\n disable_reasoning: bool = False\n upsert_strategy: str = \"MERGE\"\n status: str\n created_by: str | None = None\n created_at: datetime\n updated_at: datetime | None = None\n dictionary_ids: list[str] | None = None\n environment_id: str | None = None\n target_database_id: str | None = None\n\n class Config:\n from_attributes = True\n# #endregion TranslateJobResponse\n\n\n# #region DatasourceColumnResponse [TYPE Class]\n# @BRIEF Schema for datasource column metadata response.\nclass DatasourceColumnResponse(BaseModel):\n name: str\n type: str | None = None\n is_physical: bool = True\n is_dttm: bool = False\n description: str | None = None\n\n# #endregion DatasourceColumnResponse\n\n# #region DatasourceColumnsResponse [TYPE Class]\n# @BRIEF Schema for datasource columns endpoint response.\nclass DatasourceColumnsResponse(BaseModel):\n datasource_id: int\n datasource_name: str | None = None\n schema_name: str | None = None\n database_dialect: str\n columns: list[DatasourceColumnResponse] = []\n\n class Config:\n from_attributes = True\n# #endregion DatasourceColumnsResponse\n\n\n# #region DuplicateJobResponse [TYPE Class]\n# @BRIEF Schema for duplicate job response.\nclass DuplicateJobResponse(BaseModel):\n id: str\n name: str\n message: str = \"Job duplicated successfully\"\n\n class Config:\n from_attributes = True\n# #endregion DuplicateJobResponse\n\n\n# #region DictionaryCreate [TYPE Class]\n# @BRIEF Schema for creating a new terminology dictionary.\nclass DictionaryCreate(BaseModel):\n name: str\n description: str | None = None\n source_dialect: str\n target_dialect: str\n is_active: bool = True\n# #endregion DictionaryCreate\n\n\n# #region DictionaryImport [TYPE Class]\n# @BRIEF Schema for importing entries into a terminology dictionary.\nclass DictionaryImport(BaseModel):\n content: str = Field(..., description=\"CSV or TSV content as raw string\")\n delimiter: str | None = Field(None, description=\"Detected or forced delimiter: ',' or '\\\\t'. Auto-detect if omitted.\")\n on_conflict: str = Field(\"overwrite\", description=\"'overwrite' or 'keep_existing' or 'cancel'\")\n preview_only: bool = Field(False, description=\"If true, return preview without applying\")\n default_source_language: str | None = Field(None, description=\"Default BCP-47 source language when column missing in data\")\n default_target_language: str | None = Field(None, description=\"Default BCP-47 target language when column missing in data\")\n# #endregion DictionaryImport\n\n\n# #region DictionaryResponse [TYPE Class]\n# @BRIEF Schema for terminology dictionary API responses.\nclass DictionaryResponse(BaseModel):\n id: str\n name: str\n description: str | None = None\n source_dialect: str\n target_dialect: str\n is_active: bool\n created_by: str | None = None\n created_at: datetime\n updated_at: datetime | None = None\n entry_count: int | None = None\n\n class Config:\n from_attributes = True\n# #endregion DictionaryResponse\n\n\n# #region DictionaryEntryCreate [TYPE Class]\n# @BRIEF Schema for adding/editing a dictionary entry with language pair support.\nclass DictionaryEntryCreate(BaseModel):\n source_term: str = Field(..., description=\"Source term to translate\")\n target_term: str = Field(..., description=\"Target/translated term\")\n context_notes: str | None = Field(None, description=\"Optional context notes\")\n source_language: str = Field(\"und\", description=\"BCP-47 source language code (default: und)\")\n target_language: str = Field(\"und\", description=\"BCP-47 target language code (default: und)\")\n\n class Config:\n from_attributes = True\n# #endregion DictionaryEntryCreate\n\n\n# #region DictionaryEntryResponse [TYPE Class]\n# @BRIEF Schema for dictionary entry API responses.\nclass DictionaryEntryResponse(BaseModel):\n id: str\n dictionary_id: str\n source_term: str\n source_term_normalized: str\n target_term: str\n source_language: str | None = None\n target_language: str | None = None\n context_notes: str | None = None\n context_data: dict[str, Any] | None = None\n usage_notes: str | None = None\n has_context: bool = False\n context_source: str | None = None\n origin_source_language: str | None = None\n created_at: datetime\n updated_at: datetime | None = None\n\n class Config:\n from_attributes = True\n# #endregion DictionaryEntryResponse\n\n\n# #region DictionaryImportResult [TYPE Class]\n# @BRIEF Schema for dictionary import result.\nclass DictionaryImportResult(BaseModel):\n total: int = 0\n created: int = 0\n updated: int = 0\n skipped: int = 0\n errors: list[dict[str, Any]] = Field(default_factory=list)\n preview: list[dict[str, Any]] = Field(default_factory=list, description=\"Preview rows with conflict flags\")\n# #endregion DictionaryImportResult\n\n\n# #region PreviewRequest [TYPE Class]\n# @BRIEF Schema for triggering a translation preview.\nclass PreviewRequest(BaseModel):\n sample_size: int = Field(10, ge=1, le=100, description=\"Number of sample rows to preview\")\n prompt_template: str | None = Field(None, description=\"Optional custom prompt template\")\n env_id: str | None = Field(None, description=\"Superset environment ID for preview data fetch\")\n# #endregion PreviewRequest\n\n\n# #region PreviewRowUpdate [TYPE Class]\n# @BRIEF Schema for approving/editing/rejecting a preview row.\nclass PreviewRowUpdate(BaseModel):\n action: str = Field(..., description=\"'approve', 'reject', or 'edit'\")\n translation: str | None = Field(None, description=\"Edited translation (required for 'edit' action)\")\n feedback: str | None = Field(None, description=\"Optional feedback/comment\")\n language_code: str | None = Field(None, description=\"BCP-47 language code for per-language actions (optional, applies to all if omitted)\")\n# #endregion PreviewRowUpdate\n\n\n# #region PreviewAcceptResponse [TYPE Class]\n# @BRIEF Schema for preview accept response.\nclass PreviewAcceptResponse(BaseModel):\n id: str\n job_id: str\n status: str\n created_by: str | None = None\n created_at: datetime\n expires_at: datetime | None = None\n records: list['PreviewRow'] = []\n target_languages: list[str] = Field(default_factory=list, description=\"Target languages for this preview\")\n\n class Config:\n from_attributes = True\n# #endregion PreviewAcceptResponse\n\n\n# #region CostEstimate [TYPE Class]\n# @BRIEF Schema for cost estimation in preview response.\nclass CostEstimate(BaseModel):\n sample_size: int = 0\n num_languages: int = 1\n sample_prompt_tokens: int = 0\n sample_output_tokens: int = 0\n sample_total_tokens: int = 0\n sample_cost: float = 0.0\n estimated_total_rows: int = 0\n estimated_tokens: int = 0\n estimated_cost: float = 0.0\n warning: str | None = None\n# #endregion CostEstimate\n\n\n# #region TermCorrectionSubmit [TYPE Class]\n# @BRIEF Schema for submitting a term correction in a translation preview.\nclass TermCorrectionSubmit(BaseModel):\n source_term: str\n incorrect_target_term: str\n corrected_target_term: str\n dictionary_id: str | None = Field(None, description=\"Target dictionary ID (language-filtered)\")\n origin_run_id: str | None = Field(None, description=\"Run ID from which this correction originated\")\n origin_row_key: str | None = Field(None, description=\"Row key within the run\")\n context_data: dict[str, Any] | None = Field(None, description=\"Context data for the dictionary entry\")\n usage_notes: str | None = Field(None, description=\"Usage notes for the dictionary entry\")\n keep_context: bool = Field(True, description=\"If false, clear context_data and set has_context=False on dictionary entry\")\n# #endregion TermCorrectionSubmit\n\n\n# #region TermCorrectionBulkSubmit [TYPE Class]\n# @BRIEF Schema for submitting multiple term corrections atomically.\nclass TermCorrectionBulkSubmit(BaseModel):\n corrections: list[TermCorrectionSubmit]\n dictionary_id: str = Field(..., description=\"Target dictionary ID for all corrections\")\n# #endregion TermCorrectionBulkSubmit\n\n\n# #region CorrectionConflictResult [TYPE Class]\n# @BRIEF Schema for reporting conflicts in correction submission.\nclass CorrectionConflictResult(BaseModel):\n source_term: str\n existing_target_term: str\n submitted_target_term: str\n action: str = \"keep_existing\"\n# #endregion CorrectionConflictResult\n\n\n# #region CorrectionSubmitResponse [TYPE Class]\n# @BRIEF Schema for correction submission response.\nclass CorrectionSubmitResponse(BaseModel):\n entry_id: str | None = None\n action: str # \"created\", \"updated\", \"conflict_detected\", \"skipped\"\n source_term: str\n target_term: str\n conflict: CorrectionConflictResult | None = None\n message: str | None = None\n# #endregion CorrectionSubmitResponse\n\n\n# #region ScheduleConfig [TYPE Class]\n# @BRIEF Schema for configuring a recurring translation schedule.\nclass ScheduleConfig(BaseModel):\n cron_expression: str = Field(..., description=\"Cron expression for scheduling (e.g. '0 2 * * *')\")\n timezone: str = Field(\"UTC\", description=\"Timezone for the cron schedule (e.g. 'UTC', 'Europe/Moscow')\")\n is_active: bool = True\n execution_mode: str = Field(\"full\", description=\"Translation execution mode: 'full' or 'new_key_only'\")\n# #endregion ScheduleConfig\n\n\n# #region ScheduleResponse [TYPE Class]\n# @BRIEF Schema for schedule API responses.\nclass ScheduleResponse(BaseModel):\n id: str\n job_id: str\n cron_expression: str\n timezone: str\n is_active: bool\n execution_mode: str = \"full\"\n last_run_at: datetime | None = None\n next_run_at: datetime | None = None\n created_by: str | None = None\n created_at: datetime\n updated_at: datetime | None = None\n\n class Config:\n from_attributes = True\n# #endregion ScheduleResponse\n\n\n# #region NextExecutionResponse [TYPE Class]\n# @BRIEF Schema for next execution preview.\nclass NextExecutionResponse(BaseModel):\n job_id: str\n cron_expression: str\n timezone: str\n next_executions: list[str] = []\n# #endregion NextExecutionResponse\n\n\n# #region TranslationRunResponse [TYPE Class]\n# @BRIEF Schema for translation run API responses.\nclass TranslationRunResponse(BaseModel):\n id: str\n job_id: str\n status: str\n trigger_type: str | None = None\n started_at: datetime | None = None\n completed_at: datetime | None = None\n error_message: str | None = None\n total_records: int = 0\n successful_records: int = 0\n failed_records: int = 0\n skipped_records: int = 0\n insert_status: str | None = None\n superset_execution_id: str | None = None\n config_snapshot: dict[str, Any] | None = None\n key_hash: str | None = None\n config_hash: str | None = None\n dict_snapshot_hash: str | None = None\n created_by: str | None = None\n created_at: datetime\n language_stats: list['TranslationRunLanguageStatsResponse'] | None = None\n\n class Config:\n from_attributes = True\n# #endregion TranslationRunResponse\n\n\n# #region RunDetailResponse [TYPE Class]\n# @BRIEF Schema for detailed run response including records, events, and config snapshot.\nclass RunDetailResponse(BaseModel):\n run: TranslationRunResponse\n records: list[dict[str, Any]] = Field(default_factory=list, description=\"Paginated translation records\")\n events: list[dict[str, Any]] = Field(default_factory=list, description=\"Run events\")\n event_invariants: dict[str, Any] | None = None\n batch_count: int = 0\n# #endregion RunDetailResponse\n\n\n# #region RunHistoryFilter [TYPE Class]\n# @BRIEF Schema for filtering run history.\nclass RunHistoryFilter(BaseModel):\n job_id: str | None = None\n status: str | None = None\n trigger_type: str | None = None\n created_by: str | None = None\n date_from: datetime | None = None\n date_to: datetime | None = None\n page: int = 1\n page_size: int = 20\n# #endregion RunHistoryFilter\n\n\n# #region RunListResponse [TYPE Class]\n# @BRIEF Schema for paginated run list response.\nclass RunListResponse(BaseModel):\n items: list[TranslationRunResponse] = []\n total: int = 0\n page: int = 1\n page_size: int = 20\n# #endregion RunListResponse\n\n\n# #region AggregatedMetricsResponse [TYPE Class]\n# @BRIEF Schema for aggregated per-job metrics.\nclass AggregatedMetricsResponse(BaseModel):\n job_id: str\n total_runs: int = 0\n successful_runs: int = 0\n failed_runs: int = 0\n cancelled_runs: int = 0\n total_records: int = 0\n successful_records: int = 0\n failed_records: int = 0\n skipped_records: int = 0\n cumulative_tokens: int | None = None\n cumulative_cost: float | None = None\n avg_duration_ms: float | None = None\n last_run_at: datetime | None = None\n next_scheduled_run: datetime | None = None\n# #endregion AggregatedMetricsResponse\n\n\n# #region TranslationPreviewLanguageResponse [C:1] [TYPE Class]\n# @BRIEF Schema for per-language preview data in API responses.\nclass TranslationPreviewLanguageResponse(BaseModel):\n language_code: str\n source_language_detected: str | None = None\n translated_value: str | None = None\n user_edit: str | None = None\n final_value: str | None = None\n status: str = \"pending\"\n needs_review: bool = False\n\n class Config:\n from_attributes = True\n# #endregion TranslationPreviewLanguageResponse\n\n\n# #region PreviewRow [TYPE Class]\n# @BRIEF A single row in a translation preview showing original and translated content side by side.\nclass PreviewRow(BaseModel):\n id: str\n source_sql: str | None = None\n target_sql: str | None = None\n source_object_type: str | None = None\n source_object_id: str | None = None\n source_object_name: str | None = None\n status: str = \"PENDING\"\n feedback: str | None = None\n source_language_detected: str | None = None\n needs_review: bool = False\n languages: list[TranslationPreviewLanguageResponse] = Field(default_factory=list, description=\"Per-language translation data\")\n# #endregion PreviewRow\n\n\n# #region TranslationPreviewResponse [TYPE Class]\n# @BRIEF Schema for translation preview session API responses.\nclass TranslationPreviewResponse(BaseModel):\n id: str\n job_id: str\n run_id: str | None = None\n status: str\n created_by: str | None = None\n created_at: datetime\n expires_at: datetime | None = None\n records: list[PreviewRow] = []\n target_languages: list[str] = Field(default_factory=list, description=\"Target languages for this preview\")\n cost_estimate: CostEstimate | None = None\n\n class Config:\n from_attributes = True\n# #endregion TranslationPreviewResponse\n\n\n# #region TranslationBatchResponse [TYPE Class]\n# @BRIEF Schema for translation batch API responses.\nclass TranslationBatchResponse(BaseModel):\n id: str\n run_id: str\n batch_index: int\n status: str\n total_records: int = 0\n successful_records: int = 0\n failed_records: int = 0\n started_at: datetime | None = None\n completed_at: datetime | None = None\n created_at: datetime\n\n class Config:\n from_attributes = True\n# #endregion TranslationBatchResponse\n\n\n# #region MetricsResponse [TYPE Class]\n# @BRIEF Schema for translation metrics API responses.\nclass MetricsResponse(BaseModel):\n job_id: str\n snapshot_date: datetime\n total_jobs: int = 0\n total_runs: int = 0\n total_records: int = 0\n successful_records: int = 0\n failed_records: int = 0\n skipped_records: int = 0\n avg_duration_ms: int | None = None\n p50_duration_ms: int | None = None\n p95_duration_ms: int | None = None\n p99_duration_ms: int | None = None\n\n class Config:\n from_attributes = True\n# #endregion MetricsResponse\n\n\n# #region TranslationLanguageResponse [C:1] [TYPE Class]\n# @BRIEF Schema for per-language translation data in API responses.\nclass TranslationLanguageResponse(BaseModel):\n language_code: str\n source_language_detected: str | None = None\n translated_value: str | None = None\n user_edit: str | None = None\n final_value: str | None = None\n status: str = \"pending\"\n needs_review: bool = False\n language_overridden: bool = False\n\n class Config:\n from_attributes = True\n# #endregion TranslationLanguageResponse\n\n\n# #region TranslationRunLanguageStatsResponse [C:1] [TYPE Class]\n# @BRIEF Schema for per-language statistics in run API responses.\nclass TranslationRunLanguageStatsResponse(BaseModel):\n language_code: str\n total_rows: int = 0\n translated_rows: int = 0\n failed_rows: int = 0\n skipped_rows: int = 0\n token_count: int = 0\n estimated_cost: float = 0.0\n\n class Config:\n from_attributes = True\n# #endregion TranslationRunLanguageStatsResponse\n\n\n# #region OverrideLanguageRequest [C:1] [TYPE Class]\n# @BRIEF Schema for manually overriding the detected source language of a translation.\nclass OverrideLanguageRequest(BaseModel):\n source_language: str = Field(..., description=\"BCP-47 language code to override with\")\n# #endregion OverrideLanguageRequest\n\n\n# #region BulkFindReplaceRequest [C:1] [TYPE Class]\n# @BRIEF Schema for bulk find-and-replace within translations for a target language.\nclass BulkFindReplaceRequest(BaseModel):\n find_pattern: str = Field(..., description=\"Text or regex pattern to find\", max_length=500)\n is_regex: bool = Field(False, description=\"Whether find_pattern is a regular expression\")\n replacement_text: str = Field(..., description=\"Replacement text\")\n target_language: str = Field(..., description=\"BCP-47 language code to target\")\n preview: bool = Field(True, description=\"If true, return matches without applying replacements\")\n submit_to_dictionary: bool = Field(False, description=\"If true, also submit corrections to dictionary\")\n dictionary_id: str | None = Field(None, description=\"Target dictionary ID for submitting corrections\")\n usage_notes: str | None = Field(None, description=\"Usage notes for dictionary entries\")\n submit_to_dictionary_with_context: bool = Field(False, description=\"If true, auto-capture source row context when submitting to dictionary\")\n\n @field_validator(\"find_pattern\")\n @classmethod\n def validate_pattern_length(cls, v: str) -> str:\n \"\"\"Reject patterns longer than 500 characters to prevent ReDoS.\"\"\"\n if len(v) > 500:\n raise ValueError(\"Pattern too long (max 500 characters)\")\n return v\n# #endregion BulkFindReplaceRequest\n\n\n# #region InlineEditRequest [C:1] [TYPE Class]\n# @BRIEF Schema for inline editing a translated value on a completed run result.\nclass InlineEditRequest(BaseModel):\n final_value: str = Field(..., description=\"Corrected/edited translation text\")\n submit_to_dictionary: bool = Field(False, description=\"If true, also save correction to dictionary\")\n dictionary_id: str | None = Field(None, description=\"Target dictionary ID for saving correction\")\n context_data_override: dict[str, Any] | None = Field(None, description=\"Override auto-captured context data for dictionary entry\")\n usage_notes: str | None = Field(None, description=\"Usage notes for the dictionary entry\")\n keep_context: bool = Field(True, description=\"If false, clear context_data and set has_context=False on dictionary entry\")\n# #endregion InlineEditRequest\n\n\n# #region BulkReplacePreviewItem [C:1] [TYPE Class]\n# @BRIEF A single item in a bulk replace preview list.\nclass BulkReplacePreviewItem(BaseModel):\n record_id: str\n language_code: str\n source_term: str\n current_value: str\n new_value: str\n source_language_detected: str | None = None\n# #endregion BulkReplacePreviewItem\n\n\n# #region BulkReplaceResponse [C:1] [TYPE Class]\n# @BRIEF Response for bulk find-and-replace operation.\nclass BulkReplaceResponse(BaseModel):\n rows_affected: int = 0\n corrections_submitted: int = 0\n preview: list[BulkReplacePreviewItem] = Field(default_factory=list)\n# #endregion BulkReplaceResponse\n\n\n# #region InlineCorrectionSubmit [C:1] [TYPE Class]\n# @BRIEF Schema for submitting an inline correction for a specific translated record.\nclass InlineCorrectionSubmit(BaseModel):\n record_id: str = Field(..., description=\"Translation record ID\")\n language_code: str = Field(..., description=\"BCP-47 language code of the translated value\")\n source_term: str = Field(..., description=\"Original source term that was incorrectly translated\")\n corrected_term: str = Field(..., description=\"Corrected translation\")\n dictionary_id: str = Field(..., description=\"Target dictionary ID to also save the correction\")\n source_language: str = Field(..., description=\"BCP-47 source language code\")\n# #endregion InlineCorrectionSubmit\n\n\n# #endregion TranslateSchemas\n" + "body": "# #region TranslateSchemas [C:3] [TYPE Module] [SEMANTICS pydantic, translate, schema, translate-job-create]\n# @BRIEF Pydantic v2 schemas for translation API request/response serialization.\n# @LAYER API\n# @RELATION DEPENDS_ON -> pydantic\n\nfrom datetime import datetime\nfrom typing import Any\n\nimport re\n\nfrom pydantic import BaseModel, Field, field_validator\n\n\ndef _validate_bcp47_list(v: list[str] | None) -> list[str] | None:\n \"\"\"Validate that each item in target_languages is a valid BCP-47 tag.\"\"\"\n if not v:\n return v\n for tag in v:\n if not tag or not tag.strip():\n raise ValueError(f\"Invalid BCP-47 tag: '{tag}' — must be a non-empty string\")\n if not re.match(r'^[a-zA-Z]{2,8}(-[a-zA-Z0-9]{1,8})*$', tag.strip()):\n raise ValueError(\n f\"Invalid BCP-47 tag: '{tag}'. \"\n \"Expected format like 'en', 'ru', 'zh-CN', 'pt-BR'.\"\n )\n return v\n\n\n# #region TranslateJobCreate [TYPE Class]\n# @BRIEF Schema for creating a new translation job.\nclass TranslateJobCreate(BaseModel):\n name: str\n description: str | None = None\n source_dialect: str = Field(..., description=\"Source database dialect (e.g. postgresql, clickhouse)\")\n target_dialect: str = Field(..., description=\"Target database dialect (e.g. postgresql, clickhouse)\")\n database_dialect: str | None = Field(None, description=\"Detected dialect from Superset connection at save time\")\n source_datasource_id: str | None = Field(None, description=\"Superset datasource ID\")\n source_table: str | None = Field(None, description=\"Source table name\")\n target_schema: str | None = Field(None, description=\"Target table schema\")\n target_table: str | None = Field(None, description=\"Target table name\")\n source_key_cols: list[str] | None = Field(default_factory=list, description=\"Source key column names\")\n target_key_cols: list[str] | None = Field(default_factory=list, description=\"Target key column names\")\n translation_column: str | None = Field(None, description=\"Source column to translate\")\n target_column: str | None = Field(None, description=\"Target column for translated output (defaults to translation_column)\")\n target_language_column: str | None = Field(None, description=\"Target column for language code (e.g. 'ru', 'en')\")\n target_source_column: str | None = Field(None, description=\"Target column for source/original text\")\n target_source_language_column: str | None = Field(None, description=\"Target column for detected source language (BCP-47)\")\n context_columns: list[str] | None = Field(default_factory=list, description=\"Context column names\")\n target_language: str | None = Field(None, description=\"Target language code [DEPRECATED: use target_languages]\")\n target_languages: list[str] | None = Field(default_factory=list, description=\"List of BCP-47 target language codes\")\n provider_id: str | None = Field(None, description=\"LLM provider ID\")\n\n _validate_target_languages = field_validator(\"target_languages\")(_validate_bcp47_list)\n batch_size: int = Field(50, description=\"Records per batch\")\n disable_reasoning: bool = Field(False, description=\"If true, pass reasoning_effort:none to LLM to save output tokens\")\n upsert_strategy: str = Field(\"MERGE\", description=\"UPSERT strategy: MERGE, INSERT, UPDATE\")\n dictionary_ids: list[str] | None = Field(default_factory=list, description=\"Associated terminology dictionary IDs\")\n environment_id: str | None = Field(None, description=\"Superset environment ID\")\n target_database_id: str | None = Field(None, description=\"Superset database ID for SQL Lab insert target\")\n# #endregion TranslateJobCreate\n\n\n# #region TranslateJobUpdate [TYPE Class]\n# @BRIEF Schema for updating an existing translation job.\nclass TranslateJobUpdate(BaseModel):\n name: str | None = None\n description: str | None = None\n source_dialect: str | None = None\n target_dialect: str | None = None\n database_dialect: str | None = None\n source_datasource_id: str | None = None\n source_table: str | None = None\n target_schema: str | None = None\n target_table: str | None = None\n source_key_cols: list[str] | None = None\n target_key_cols: list[str] | None = None\n translation_column: str | None = None\n target_column: str | None = None\n target_language_column: str | None = None\n target_source_column: str | None = None\n target_source_language_column: str | None = None\n context_columns: list[str] | None = None\n target_language: str | None = None\n target_languages: list[str] | None = None\n provider_id: str | None = None\n\n _validate_target_languages = field_validator(\"target_languages\")(_validate_bcp47_list)\n batch_size: int | None = None\n disable_reasoning: bool | None = None\n upsert_strategy: str | None = None\n status: str | None = None\n dictionary_ids: list[str] | None = None\n environment_id: str | None = None\n target_database_id: str | None = None\n# #endregion TranslateJobUpdate\n\n\n# #region TranslateJobResponse [TYPE Class]\n# @BRIEF Schema for translation job API responses.\nclass TranslateJobResponse(BaseModel):\n id: str\n name: str\n description: str | None = None\n source_dialect: str\n target_dialect: str\n database_dialect: str | None = None\n source_datasource_id: str | None = None\n source_table: str | None = None\n target_schema: str | None = None\n target_table: str | None = None\n source_key_cols: list[str] | None = None\n target_key_cols: list[str] | None = None\n translation_column: str | None = None\n target_column: str | None = None\n target_language_column: str | None = None\n target_source_column: str | None = None\n target_source_language_column: str | None = None\n context_columns: list[str] | None = None\n # source_language removed — deprecated, per-row auto-detected\n target_languages: list[str] | None = None\n provider_id: str | None = None\n batch_size: int = 50\n disable_reasoning: bool = False\n upsert_strategy: str = \"MERGE\"\n status: str\n created_by: str | None = None\n created_at: datetime\n updated_at: datetime | None = None\n dictionary_ids: list[str] | None = None\n environment_id: str | None = None\n target_database_id: str | None = None\n\n class Config:\n from_attributes = True\n# #endregion TranslateJobResponse\n\n\n# #region DatasourceColumnResponse [TYPE Class]\n# @BRIEF Schema for datasource column metadata response.\nclass DatasourceColumnResponse(BaseModel):\n name: str\n type: str | None = None\n is_physical: bool = True\n is_dttm: bool = False\n description: str | None = None\n\n# #endregion DatasourceColumnResponse\n\n# #region DatasourceColumnsResponse [TYPE Class]\n# @BRIEF Schema for datasource columns endpoint response.\nclass DatasourceColumnsResponse(BaseModel):\n datasource_id: int\n datasource_name: str | None = None\n schema_name: str | None = None\n database_dialect: str\n columns: list[DatasourceColumnResponse] = []\n\n class Config:\n from_attributes = True\n# #endregion DatasourceColumnsResponse\n\n\n# #region DuplicateJobResponse [TYPE Class]\n# @BRIEF Schema for duplicate job response.\nclass DuplicateJobResponse(BaseModel):\n id: str\n name: str\n message: str = \"Job duplicated successfully\"\n\n class Config:\n from_attributes = True\n# #endregion DuplicateJobResponse\n\n\n# #region DictionaryCreate [TYPE Class]\n# @BRIEF Schema for creating a new terminology dictionary.\nclass DictionaryCreate(BaseModel):\n name: str\n description: str | None = None\n source_dialect: str\n target_dialect: str\n is_active: bool = True\n# #endregion DictionaryCreate\n\n\n# #region DictionaryImport [TYPE Class]\n# @BRIEF Schema for importing entries into a terminology dictionary.\nclass DictionaryImport(BaseModel):\n content: str = Field(..., description=\"CSV or TSV content as raw string\")\n delimiter: str | None = Field(None, description=\"Detected or forced delimiter: ',' or '\\\\t'. Auto-detect if omitted.\")\n on_conflict: str = Field(\"overwrite\", description=\"'overwrite' or 'keep_existing' or 'cancel'\")\n preview_only: bool = Field(False, description=\"If true, return preview without applying\")\n default_source_language: str | None = Field(None, description=\"Default BCP-47 source language when column missing in data\")\n default_target_language: str | None = Field(None, description=\"Default BCP-47 target language when column missing in data\")\n# #endregion DictionaryImport\n\n\n# #region DictionaryResponse [TYPE Class]\n# @BRIEF Schema for terminology dictionary API responses.\nclass DictionaryResponse(BaseModel):\n id: str\n name: str\n description: str | None = None\n source_dialect: str\n target_dialect: str\n is_active: bool\n created_by: str | None = None\n created_at: datetime\n updated_at: datetime | None = None\n entry_count: int | None = None\n\n class Config:\n from_attributes = True\n# #endregion DictionaryResponse\n\n\n# #region DictionaryEntryCreate [TYPE Class]\n# @BRIEF Schema for adding/editing a dictionary entry with language pair support.\nclass DictionaryEntryCreate(BaseModel):\n source_term: str = Field(..., description=\"Source term to translate\")\n target_term: str = Field(..., description=\"Target/translated term\")\n context_notes: str | None = Field(None, description=\"Optional context notes\")\n source_language: str = Field(\"und\", description=\"BCP-47 source language code (default: und)\")\n target_language: str = Field(\"und\", description=\"BCP-47 target language code (default: und)\")\n\n class Config:\n from_attributes = True\n# #endregion DictionaryEntryCreate\n\n\n# #region DictionaryEntryResponse [TYPE Class]\n# @BRIEF Schema for dictionary entry API responses.\nclass DictionaryEntryResponse(BaseModel):\n id: str\n dictionary_id: str\n source_term: str\n source_term_normalized: str\n target_term: str\n source_language: str | None = None\n target_language: str | None = None\n context_notes: str | None = None\n context_data: dict[str, Any] | None = None\n usage_notes: str | None = None\n has_context: bool = False\n context_source: str | None = None\n origin_source_language: str | None = None\n created_at: datetime\n updated_at: datetime | None = None\n\n class Config:\n from_attributes = True\n# #endregion DictionaryEntryResponse\n\n\n# #region DictionaryImportResult [TYPE Class]\n# @BRIEF Schema for dictionary import result.\nclass DictionaryImportResult(BaseModel):\n total: int = 0\n created: int = 0\n updated: int = 0\n skipped: int = 0\n errors: list[dict[str, Any]] = Field(default_factory=list)\n preview: list[dict[str, Any]] = Field(default_factory=list, description=\"Preview rows with conflict flags\")\n# #endregion DictionaryImportResult\n\n\n# #region PreviewRequest [TYPE Class]\n# @BRIEF Schema for triggering a translation preview.\nclass PreviewRequest(BaseModel):\n sample_size: int = Field(10, ge=1, le=100, description=\"Number of sample rows to preview\")\n prompt_template: str | None = Field(None, description=\"Optional custom prompt template\")\n env_id: str | None = Field(None, description=\"Superset environment ID for preview data fetch\")\n# #endregion PreviewRequest\n\n\n# #region PreviewRowUpdate [TYPE Class]\n# @BRIEF Schema for approving/editing/rejecting a preview row.\nclass PreviewRowUpdate(BaseModel):\n action: str = Field(..., description=\"'approve', 'reject', or 'edit'\")\n translation: str | None = Field(None, description=\"Edited translation (required for 'edit' action)\")\n feedback: str | None = Field(None, description=\"Optional feedback/comment\")\n language_code: str | None = Field(None, description=\"BCP-47 language code for per-language actions (optional, applies to all if omitted)\")\n# #endregion PreviewRowUpdate\n\n\n# #region PreviewAcceptResponse [TYPE Class]\n# @BRIEF Schema for preview accept response.\nclass PreviewAcceptResponse(BaseModel):\n id: str\n job_id: str\n status: str\n created_by: str | None = None\n created_at: datetime\n expires_at: datetime | None = None\n records: list['PreviewRow'] = []\n target_languages: list[str] = Field(default_factory=list, description=\"Target languages for this preview\")\n\n class Config:\n from_attributes = True\n# #endregion PreviewAcceptResponse\n\n\n# #region CostEstimate [TYPE Class]\n# @BRIEF Schema for cost estimation in preview response.\nclass CostEstimate(BaseModel):\n sample_size: int = 0\n num_languages: int = 1\n sample_prompt_tokens: int = 0\n sample_output_tokens: int = 0\n sample_total_tokens: int = 0\n sample_cost: float = 0.0\n estimated_total_rows: int = 0\n estimated_tokens: int = 0\n estimated_cost: float = 0.0\n warning: str | None = None\n# #endregion CostEstimate\n\n\n# #region TermCorrectionSubmit [TYPE Class]\n# @BRIEF Schema for submitting a term correction in a translation preview.\nclass TermCorrectionSubmit(BaseModel):\n source_term: str\n incorrect_target_term: str\n corrected_target_term: str\n dictionary_id: str | None = Field(None, description=\"Target dictionary ID (language-filtered)\")\n origin_run_id: str | None = Field(None, description=\"Run ID from which this correction originated\")\n origin_row_key: str | None = Field(None, description=\"Row key within the run\")\n context_data: dict[str, Any] | None = Field(None, description=\"Context data for the dictionary entry\")\n usage_notes: str | None = Field(None, description=\"Usage notes for the dictionary entry\")\n keep_context: bool = Field(True, description=\"If false, clear context_data and set has_context=False on dictionary entry\")\n# #endregion TermCorrectionSubmit\n\n\n# #region TermCorrectionBulkSubmit [TYPE Class]\n# @BRIEF Schema for submitting multiple term corrections atomically.\nclass TermCorrectionBulkSubmit(BaseModel):\n corrections: list[TermCorrectionSubmit]\n dictionary_id: str = Field(..., description=\"Target dictionary ID for all corrections\")\n# #endregion TermCorrectionBulkSubmit\n\n\n# #region CorrectionConflictResult [TYPE Class]\n# @BRIEF Schema for reporting conflicts in correction submission.\nclass CorrectionConflictResult(BaseModel):\n source_term: str\n existing_target_term: str\n submitted_target_term: str\n action: str = \"keep_existing\"\n# #endregion CorrectionConflictResult\n\n\n# #region CorrectionSubmitResponse [TYPE Class]\n# @BRIEF Schema for correction submission response.\nclass CorrectionSubmitResponse(BaseModel):\n entry_id: str | None = None\n action: str # \"created\", \"updated\", \"conflict_detected\", \"skipped\"\n source_term: str\n target_term: str\n conflict: CorrectionConflictResult | None = None\n message: str | None = None\n# #endregion CorrectionSubmitResponse\n\n\n# #region ScheduleConfig [TYPE Class]\n# @BRIEF Schema for configuring a recurring translation schedule.\nclass ScheduleConfig(BaseModel):\n cron_expression: str = Field(..., description=\"Cron expression for scheduling (e.g. '0 2 * * *')\")\n timezone: str = Field(\"UTC\", description=\"Timezone for the cron schedule (e.g. 'UTC', 'Europe/Moscow')\")\n is_active: bool = True\n execution_mode: str = Field(\"full\", description=\"Translation execution mode: 'full' or 'new_key_only'\")\n# #endregion ScheduleConfig\n\n\n# #region ScheduleResponse [TYPE Class]\n# @BRIEF Schema for schedule API responses.\nclass ScheduleResponse(BaseModel):\n id: str\n job_id: str\n cron_expression: str\n timezone: str\n is_active: bool\n execution_mode: str = \"full\"\n last_run_at: datetime | None = None\n next_run_at: datetime | None = None\n created_by: str | None = None\n created_at: datetime\n updated_at: datetime | None = None\n\n class Config:\n from_attributes = True\n# #endregion ScheduleResponse\n\n\n# #region NextExecutionResponse [TYPE Class]\n# @BRIEF Schema for next execution preview.\nclass NextExecutionResponse(BaseModel):\n job_id: str\n cron_expression: str\n timezone: str\n next_executions: list[str] = []\n# #endregion NextExecutionResponse\n\n\n# #region TranslationRunResponse [TYPE Class]\n# @BRIEF Schema for translation run API responses.\nclass TranslationRunResponse(BaseModel):\n id: str\n job_id: str\n status: str\n trigger_type: str | None = None\n started_at: datetime | None = None\n completed_at: datetime | None = None\n error_message: str | None = None\n total_records: int = 0\n successful_records: int = 0\n failed_records: int = 0\n skipped_records: int = 0\n insert_status: str | None = None\n superset_execution_id: str | None = None\n config_snapshot: dict[str, Any] | None = None\n key_hash: str | None = None\n config_hash: str | None = None\n dict_snapshot_hash: str | None = None\n created_by: str | None = None\n created_at: datetime\n language_stats: list['TranslationRunLanguageStatsResponse'] | None = None\n\n class Config:\n from_attributes = True\n# #endregion TranslationRunResponse\n\n\n# #region RunDetailResponse [TYPE Class]\n# @BRIEF Schema for detailed run response including records, events, and config snapshot.\nclass RunDetailResponse(BaseModel):\n run: TranslationRunResponse\n records: list[dict[str, Any]] = Field(default_factory=list, description=\"Paginated translation records\")\n events: list[dict[str, Any]] = Field(default_factory=list, description=\"Run events\")\n event_invariants: dict[str, Any] | None = None\n batch_count: int = 0\n# #endregion RunDetailResponse\n\n\n# #region RunHistoryFilter [TYPE Class]\n# @BRIEF Schema for filtering run history.\nclass RunHistoryFilter(BaseModel):\n job_id: str | None = None\n status: str | None = None\n trigger_type: str | None = None\n created_by: str | None = None\n date_from: datetime | None = None\n date_to: datetime | None = None\n page: int = 1\n page_size: int = 20\n# #endregion RunHistoryFilter\n\n\n# #region RunListResponse [TYPE Class]\n# @BRIEF Schema for paginated run list response.\nclass RunListResponse(BaseModel):\n items: list[TranslationRunResponse] = []\n total: int = 0\n page: int = 1\n page_size: int = 20\n# #endregion RunListResponse\n\n\n# #region AggregatedMetricsResponse [TYPE Class]\n# @BRIEF Schema for aggregated per-job metrics.\nclass AggregatedMetricsResponse(BaseModel):\n job_id: str\n total_runs: int = 0\n successful_runs: int = 0\n failed_runs: int = 0\n cancelled_runs: int = 0\n total_records: int = 0\n successful_records: int = 0\n failed_records: int = 0\n skipped_records: int = 0\n cumulative_tokens: int | None = None\n cumulative_cost: float | None = None\n avg_duration_ms: float | None = None\n last_run_at: datetime | None = None\n next_scheduled_run: datetime | None = None\n# #endregion AggregatedMetricsResponse\n\n\n# #region TranslationPreviewLanguageResponse [C:1] [TYPE Class]\n# @BRIEF Schema for per-language preview data in API responses.\nclass TranslationPreviewLanguageResponse(BaseModel):\n language_code: str\n source_language_detected: str | None = None\n translated_value: str | None = None\n user_edit: str | None = None\n final_value: str | None = None\n status: str = \"pending\"\n needs_review: bool = False\n\n class Config:\n from_attributes = True\n# #endregion TranslationPreviewLanguageResponse\n\n\n# #region PreviewRow [TYPE Class]\n# @BRIEF A single row in a translation preview showing original and translated content side by side.\nclass PreviewRow(BaseModel):\n id: str\n source_sql: str | None = None\n target_sql: str | None = None\n source_object_type: str | None = None\n source_object_id: str | None = None\n source_object_name: str | None = None\n status: str = \"PENDING\"\n feedback: str | None = None\n source_language_detected: str | None = None\n needs_review: bool = False\n languages: list[TranslationPreviewLanguageResponse] = Field(default_factory=list, description=\"Per-language translation data\")\n# #endregion PreviewRow\n\n\n# #region TranslationPreviewResponse [TYPE Class]\n# @BRIEF Schema for translation preview session API responses.\nclass TranslationPreviewResponse(BaseModel):\n id: str\n job_id: str\n run_id: str | None = None\n status: str\n created_by: str | None = None\n created_at: datetime\n expires_at: datetime | None = None\n records: list[PreviewRow] = []\n target_languages: list[str] = Field(default_factory=list, description=\"Target languages for this preview\")\n cost_estimate: CostEstimate | None = None\n\n class Config:\n from_attributes = True\n# #endregion TranslationPreviewResponse\n\n\n# #region TranslationBatchResponse [TYPE Class]\n# @BRIEF Schema for translation batch API responses.\nclass TranslationBatchResponse(BaseModel):\n id: str\n run_id: str\n batch_index: int\n status: str\n total_records: int = 0\n successful_records: int = 0\n failed_records: int = 0\n started_at: datetime | None = None\n completed_at: datetime | None = None\n created_at: datetime\n\n class Config:\n from_attributes = True\n# #endregion TranslationBatchResponse\n\n\n# #region MetricsResponse [TYPE Class]\n# @BRIEF Schema for translation metrics API responses.\nclass MetricsResponse(BaseModel):\n job_id: str\n snapshot_date: datetime\n total_jobs: int = 0\n total_runs: int = 0\n total_records: int = 0\n successful_records: int = 0\n failed_records: int = 0\n skipped_records: int = 0\n avg_duration_ms: int | None = None\n p50_duration_ms: int | None = None\n p95_duration_ms: int | None = None\n p99_duration_ms: int | None = None\n\n class Config:\n from_attributes = True\n# #endregion MetricsResponse\n\n\n# #region TranslationLanguageResponse [C:1] [TYPE Class]\n# @BRIEF Schema for per-language translation data in API responses.\nclass TranslationLanguageResponse(BaseModel):\n language_code: str\n source_language_detected: str | None = None\n translated_value: str | None = None\n user_edit: str | None = None\n final_value: str | None = None\n status: str = \"pending\"\n needs_review: bool = False\n language_overridden: bool = False\n\n class Config:\n from_attributes = True\n# #endregion TranslationLanguageResponse\n\n\n# #region TranslationRunLanguageStatsResponse [C:1] [TYPE Class]\n# @BRIEF Schema for per-language statistics in run API responses.\nclass TranslationRunLanguageStatsResponse(BaseModel):\n language_code: str\n total_rows: int = 0\n translated_rows: int = 0\n failed_rows: int = 0\n skipped_rows: int = 0\n token_count: int = 0\n estimated_cost: float = 0.0\n\n class Config:\n from_attributes = True\n# #endregion TranslationRunLanguageStatsResponse\n\n\n# #region OverrideLanguageRequest [C:1] [TYPE Class]\n# @BRIEF Schema for manually overriding the detected source language of a translation.\nclass OverrideLanguageRequest(BaseModel):\n source_language: str = Field(..., description=\"BCP-47 language code to override with\")\n# #endregion OverrideLanguageRequest\n\n\n# #region BulkFindReplaceRequest [C:1] [TYPE Class]\n# @BRIEF Schema for bulk find-and-replace within translations for a target language.\nclass BulkFindReplaceRequest(BaseModel):\n find_pattern: str = Field(..., description=\"Text or regex pattern to find\", max_length=500)\n is_regex: bool = Field(False, description=\"Whether find_pattern is a regular expression\")\n replacement_text: str = Field(..., description=\"Replacement text\")\n target_language: str = Field(..., description=\"BCP-47 language code to target\")\n preview: bool = Field(True, description=\"If true, return matches without applying replacements\")\n submit_to_dictionary: bool = Field(False, description=\"If true, also submit corrections to dictionary\")\n dictionary_id: str | None = Field(None, description=\"Target dictionary ID for submitting corrections\")\n usage_notes: str | None = Field(None, description=\"Usage notes for dictionary entries\")\n submit_to_dictionary_with_context: bool = Field(False, description=\"If true, auto-capture source row context when submitting to dictionary\")\n\n @field_validator(\"find_pattern\")\n @classmethod\n def validate_pattern_length(cls, v: str) -> str:\n \"\"\"Reject patterns longer than 500 characters to prevent ReDoS.\"\"\"\n if len(v) > 500:\n raise ValueError(\"Pattern too long (max 500 characters)\")\n return v\n# #endregion BulkFindReplaceRequest\n\n\n# #region InlineEditRequest [C:1] [TYPE Class]\n# @BRIEF Schema for inline editing a translated value on a completed run result.\nclass InlineEditRequest(BaseModel):\n final_value: str = Field(..., description=\"Corrected/edited translation text\")\n submit_to_dictionary: bool = Field(False, description=\"If true, also save correction to dictionary\")\n dictionary_id: str | None = Field(None, description=\"Target dictionary ID for saving correction\")\n context_data_override: dict[str, Any] | None = Field(None, description=\"Override auto-captured context data for dictionary entry\")\n usage_notes: str | None = Field(None, description=\"Usage notes for the dictionary entry\")\n keep_context: bool = Field(True, description=\"If false, clear context_data and set has_context=False on dictionary entry\")\n# #endregion InlineEditRequest\n\n\n# #region BulkReplacePreviewItem [C:1] [TYPE Class]\n# @BRIEF A single item in a bulk replace preview list.\nclass BulkReplacePreviewItem(BaseModel):\n record_id: str\n language_code: str\n source_term: str\n current_value: str\n new_value: str\n source_language_detected: str | None = None\n# #endregion BulkReplacePreviewItem\n\n\n# #region BulkReplaceResponse [C:1] [TYPE Class]\n# @BRIEF Response for bulk find-and-replace operation.\nclass BulkReplaceResponse(BaseModel):\n rows_affected: int = 0\n corrections_submitted: int = 0\n preview: list[BulkReplacePreviewItem] = Field(default_factory=list)\n# #endregion BulkReplaceResponse\n\n\n# #region InlineCorrectionSubmit [C:1] [TYPE Class]\n# @BRIEF Schema for submitting an inline correction for a specific translated record.\nclass InlineCorrectionSubmit(BaseModel):\n record_id: str = Field(..., description=\"Translation record ID\")\n language_code: str = Field(..., description=\"BCP-47 language code of the translated value\")\n source_term: str = Field(..., description=\"Original source term that was incorrectly translated\")\n corrected_term: str = Field(..., description=\"Corrected translation\")\n dictionary_id: str = Field(..., description=\"Target dictionary ID to also save the correction\")\n source_language: str = Field(..., description=\"BCP-47 source language code\")\n# #endregion InlineCorrectionSubmit\n\n\n# #endregion TranslateSchemas\n" }, { "contract_id": "TranslateJobCreate", @@ -59084,13 +58306,13 @@ "contract_type": "Module", "file_path": "backend/src/services/git/_base.py", "start_line": 1, - "end_line": 317, + "end_line": 383, "tier": "TIER_2", - "complexity": 3, + "complexity": 4, "metadata": { - "COMPLEXITY": 3, + "COMPLEXITY": 4, "LAYER": "Infra", - "PURPOSE": "Core GitService base class — initialization, path resolution, repo lifecycle (init/delete/get), and identity configuration." + "PURPOSE": "Core GitService base class — initialization, path resolution, repo lifecycle (init/delete/get), identity configuration, concurrent locking, and shared HTTP client pool." }, "relations": [ { @@ -59136,6 +58358,33 @@ "value": "Infra" } }, + { + "code": "missing_required_tag", + "tag": "POST", + "message": "@POST is required for contract type 'Module' at C4", + "detail": { + "actual_complexity": 4, + "contract_type": "Module" + } + }, + { + "code": "missing_required_tag", + "tag": "PRE", + "message": "@PRE is required for contract type 'Module' at C4", + "detail": { + "actual_complexity": 4, + "contract_type": "Module" + } + }, + { + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Module' at C4", + "detail": { + "actual_complexity": 4, + "contract_type": "Module" + } + }, { "code": "invalid_relation_predicate", "tag": "RELATION", @@ -59157,7 +58406,7 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region GitServiceBase [C:3] [TYPE Module] [SEMANTICS git, repository, clone, base, mixin]\n# @LAYER: Infra\n# @BRIEF Core GitService base class — initialization, path resolution, repo lifecycle (init/delete/get), and identity configuration.\n# @RELATION INHERITED_BY -> [GitService]\n# @RELATION DEPENDS_ON -> [SessionLocal]\n# @RELATION DEPENDS_ON -> [AppConfigRecord]\n# @RELATION DEPENDS_ON -> [GitRepository]\n\nimport os\nimport re\nimport shutil\nfrom pathlib import Path\n\nfrom fastapi import HTTPException\nfrom git import Repo\nfrom git.exc import InvalidGitRepositoryError, NoSuchPathError\n\nfrom src.core.database import SessionLocal\nfrom src.core.logger import belief_scope, logger\nfrom src.models.config import AppConfigRecord\nfrom src.models.git import GitRepository\n\n\n# #region GitServiceBase [C:3] [TYPE Class]\n# @BRIEF Base class for GitService providing initialization, path resolution, repository lifecycle, and identity.\nclass GitServiceBase:\n # region GitService_init [TYPE Function]\n # @PURPOSE: Initializes the GitService with a base path for repositories.\n # @PARAM: base_path (str) - Root directory for all Git clones.\n # @PRE: base_path is a valid string path.\n # @POST: GitService is initialized; base_path directory exists.\n def __init__(self, base_path: str = \"git_repos\"):\n with belief_scope(\"GitService.__init__\"):\n backend_root = Path(__file__).parents[3]\n self.legacy_base_path = str((backend_root / \"git_repos\").resolve())\n self._uses_default_base_path = base_path == \"git_repos\"\n self.base_path = self._resolve_base_path(base_path)\n self._ensure_base_path_exists()\n # endregion GitService_init\n\n # region _ensure_base_path_exists [TYPE Function]\n # @PURPOSE: Ensure the repositories root directory exists and is a directory.\n # @PRE: self.base_path is resolved to filesystem path.\n # @POST: self.base_path exists as directory or raises ValueError.\n def _ensure_base_path_exists(self) -> None:\n base = Path(self.base_path)\n if base.exists() and not base.is_dir():\n raise ValueError(f\"Git repositories base path is not a directory: {self.base_path}\")\n try:\n base.mkdir(parents=True, exist_ok=True)\n except (PermissionError, OSError) as e:\n logger.warning(\n f\"[_ensure_base_path_exists][Coherence:Failed] Cannot create Git repositories base path: {self.base_path}. Error: {e}\"\n )\n raise ValueError(f\"Cannot create Git repositories base path: {self.base_path}. {e}\")\n # endregion _ensure_base_path_exists\n\n # region _resolve_base_path [TYPE Function]\n # @PURPOSE: Resolve base repository directory from explicit argument or global storage settings.\n # @PRE: base_path is a string path.\n # @POST: Returns absolute path for Git repositories root.\n # @RETURN: str\n def _resolve_base_path(self, base_path: str) -> str:\n backend_root = Path(__file__).parents[3]\n fallback_path = str((backend_root / base_path).resolve())\n if base_path != \"git_repos\":\n return fallback_path\n try:\n session = SessionLocal()\n try:\n config_row = session.query(AppConfigRecord).filter(AppConfigRecord.id == \"global\").first()\n finally:\n session.close()\n payload = (config_row.payload if config_row and config_row.payload else {}) if config_row else {}\n storage_cfg = payload.get(\"settings\", {}).get(\"storage\", {}) if isinstance(payload, dict) else {}\n root_path = str(storage_cfg.get(\"root_path\", \"\")).strip()\n repo_path = str(storage_cfg.get(\"repo_path\", \"\")).strip()\n if not root_path:\n return fallback_path\n project_root = Path(__file__).parents[4]\n root = Path(root_path)\n if not root.is_absolute():\n root = (project_root / root).resolve()\n repo_root = Path(repo_path) if repo_path else Path(\"repositorys\")\n if repo_root.is_absolute():\n return str(repo_root.resolve())\n return str((root / repo_root).resolve())\n except Exception as e:\n logger.warning(f\"[_resolve_base_path][Coherence:Failed] Falling back to default path: {e}\")\n return fallback_path\n # endregion _resolve_base_path\n\n # region _normalize_repo_key [TYPE Function]\n # @PURPOSE: Convert user/dashboard-provided key to safe filesystem directory name.\n # @PRE: repo_key can be None/empty.\n # @POST: Returns normalized non-empty key.\n # @RETURN: str\n def _normalize_repo_key(self, repo_key: str | None) -> str:\n raw_key = str(repo_key or \"\").strip().lower()\n normalized = re.sub(r\"[^a-z0-9._-]+\", \"-\", raw_key).strip(\"._-\")\n return normalized or \"dashboard\"\n # endregion _normalize_repo_key\n\n # region _update_repo_local_path [TYPE Function]\n # @PURPOSE: Persist repository local_path in GitRepository table when record exists.\n # @PRE: dashboard_id is valid integer.\n # @POST: local_path is updated for existing record.\n def _update_repo_local_path(self, dashboard_id: int, local_path: str) -> None:\n try:\n session = SessionLocal()\n try:\n db_repo = (\n session.query(GitRepository)\n .filter(GitRepository.dashboard_id == int(dashboard_id))\n .first()\n )\n if db_repo:\n db_repo.local_path = local_path\n session.commit()\n finally:\n session.close()\n except Exception as e:\n logger.warning(f\"[_update_repo_local_path][Coherence:Failed] {e}\")\n # endregion _update_repo_local_path\n\n # region _migrate_repo_directory [TYPE Function]\n # @PURPOSE: Move legacy repository directory to target path and sync DB metadata.\n # @PRE: source_path exists.\n # @POST: Repository content available at target_path.\n # @RETURN: str\n def _migrate_repo_directory(self, dashboard_id: int, source_path: str, target_path: str) -> str:\n source_abs = os.path.abspath(source_path)\n target_abs = os.path.abspath(target_path)\n if source_abs == target_abs:\n return source_abs\n if os.path.exists(target_abs):\n logger.reason(f\"Target already exists, keeping source path: {target_abs}\", extra={\"src\": \"_migrate_repo_directory\"})\n return source_abs\n Path(target_abs).parent.mkdir(parents=True, exist_ok=True)\n try:\n os.replace(source_abs, target_abs)\n except OSError:\n shutil.move(source_abs, target_abs)\n self._update_repo_local_path(dashboard_id, target_abs)\n logger.info(\n f\"[_migrate_repo_directory][Coherence:OK] Repository migrated for dashboard {dashboard_id}: {source_abs} -> {target_abs}\"\n )\n return target_abs\n # endregion _migrate_repo_directory\n\n # region _get_repo_path [TYPE Function]\n # @PURPOSE: Resolves the local filesystem path for a dashboard's repository.\n # @PARAM: dashboard_id (int)\n # @PARAM: repo_key (Optional[str]) - Slug-like key used when DB local_path is absent.\n # @PRE: dashboard_id is an integer.\n # @POST: Returns DB-local_path when present, otherwise base_path/.\n # @RETURN: str\n def _get_repo_path(self, dashboard_id: int, repo_key: str | None = None) -> str:\n with belief_scope(\"GitService._get_repo_path\"):\n if dashboard_id is None:\n raise ValueError(\"dashboard_id cannot be None\")\n self._ensure_base_path_exists()\n fallback_key = repo_key if repo_key is not None else str(dashboard_id)\n normalized_key = self._normalize_repo_key(fallback_key)\n target_path = os.path.join(self.base_path, normalized_key)\n if not self._uses_default_base_path:\n return target_path\n try:\n session = SessionLocal()\n try:\n db_repo = (\n session.query(GitRepository)\n .filter(GitRepository.dashboard_id == int(dashboard_id))\n .first()\n )\n finally:\n session.close()\n if db_repo and db_repo.local_path:\n db_path = os.path.abspath(db_repo.local_path)\n if os.path.exists(db_path):\n if (\n os.path.abspath(self.base_path) != os.path.abspath(self.legacy_base_path)\n and db_path.startswith(os.path.abspath(self.legacy_base_path) + os.sep)\n ):\n return self._migrate_repo_directory(dashboard_id, db_path, target_path)\n return db_path\n except Exception as e:\n logger.warning(f\"[_get_repo_path][Coherence:Failed] Could not resolve local_path from DB: {e}\")\n legacy_id_path = os.path.join(self.legacy_base_path, str(dashboard_id))\n if os.path.exists(legacy_id_path) and not os.path.exists(target_path):\n return self._migrate_repo_directory(dashboard_id, legacy_id_path, target_path)\n if os.path.exists(target_path):\n self._update_repo_local_path(dashboard_id, target_path)\n return target_path\n # endregion _get_repo_path\n\n # region init_repo [TYPE Function]\n # @PURPOSE: Initialize or clone a repository for a dashboard.\n # @PARAM: dashboard_id (int), remote_url (str), pat (str), repo_key (Optional[str]).\n # @PRE: dashboard_id is int, remote_url is valid Git URL, pat is provided.\n # @POST: Repository is cloned or opened at the local path.\n # @RETURN: Repo\n def init_repo(self, dashboard_id: int, remote_url: str, pat: str, repo_key: str | None = None) -> Repo:\n with belief_scope(\"GitService.init_repo\"):\n self._ensure_base_path_exists()\n repo_path = self._get_repo_path(dashboard_id, repo_key=repo_key or str(dashboard_id))\n Path(repo_path).parent.mkdir(parents=True, exist_ok=True)\n if pat and \"://\" in remote_url:\n proto, rest = remote_url.split(\"://\", 1)\n auth_url = f\"{proto}://oauth2:{pat}@{rest}\"\n else:\n auth_url = remote_url\n if os.path.exists(repo_path):\n logger.reason(f\"Opening existing repo at {repo_path}\", extra={\"src\": \"init_repo\"})\n try:\n repo = Repo(repo_path)\n except (InvalidGitRepositoryError, NoSuchPathError):\n logger.reason(f\"Existing path is not a Git repository, recreating: {repo_path}\", extra={\"src\": \"init_repo\"})\n stale_path = Path(repo_path)\n if stale_path.exists():\n shutil.rmtree(stale_path, ignore_errors=True)\n if stale_path.exists():\n try:\n stale_path.unlink()\n except Exception:\n pass\n repo = Repo.clone_from(auth_url, repo_path)\n self._ensure_gitflow_branches(repo, dashboard_id)\n return repo\n logger.reason(f\"Cloning {remote_url} to {repo_path}\", extra={\"src\": \"init_repo\"})\n repo = Repo.clone_from(auth_url, repo_path)\n self._ensure_gitflow_branches(repo, dashboard_id)\n return repo\n # endregion init_repo\n\n # region delete_repo [TYPE Function]\n # @PURPOSE: Remove local repository and DB binding for a dashboard.\n # @PRE: dashboard_id is a valid integer.\n # @POST: Local path is deleted when present and GitRepository row is removed.\n def delete_repo(self, dashboard_id: int) -> None:\n with belief_scope(\"GitService.delete_repo\"):\n repo_path = self._get_repo_path(dashboard_id)\n removed_files = False\n if os.path.exists(repo_path):\n if os.path.isdir(repo_path):\n shutil.rmtree(repo_path)\n else:\n os.remove(repo_path)\n removed_files = True\n session = SessionLocal()\n try:\n db_repo = (\n session.query(GitRepository)\n .filter(GitRepository.dashboard_id == int(dashboard_id))\n .first()\n )\n if db_repo:\n session.delete(db_repo)\n session.commit()\n return\n if removed_files:\n return\n raise HTTPException(\n status_code=404,\n detail=f\"Repository for dashboard {dashboard_id} not found\",\n )\n except HTTPException:\n session.rollback()\n raise\n except Exception as e:\n session.rollback()\n logger.error(f\"[delete_repo][Coherence:Failed] Failed to delete repository for dashboard {dashboard_id}: {e}\")\n raise HTTPException(status_code=500, detail=f\"Failed to delete repository: {e!s}\")\n finally:\n session.close()\n # endregion delete_repo\n\n # region get_repo [TYPE Function]\n # @PURPOSE: Get Repo object for a dashboard.\n # @PRE: Repository must exist on disk for the given dashboard_id.\n # @POST: Returns a GitPython Repo instance for the dashboard.\n # @RETURN: Repo\n def get_repo(self, dashboard_id: int) -> Repo:\n with belief_scope(\"GitService.get_repo\"):\n repo_path = self._get_repo_path(dashboard_id)\n if not os.path.exists(repo_path):\n logger.error(f\"[get_repo][Coherence:Failed] Repository for dashboard {dashboard_id} does not exist\")\n raise HTTPException(status_code=404, detail=f\"Repository for dashboard {dashboard_id} not found\")\n try:\n return Repo(repo_path)\n except Exception as e:\n logger.error(f\"[get_repo][Coherence:Failed] Failed to open repository at {repo_path}: {e}\")\n raise HTTPException(status_code=500, detail=\"Failed to open local Git repository\")\n # endregion get_repo\n\n # region configure_identity [TYPE Function]\n # @PURPOSE: Configure repository-local Git committer identity for user-scoped operations.\n # @PRE: dashboard_id repository exists; git_username/git_email may be empty.\n # @POST: Repository config has user.name and user.email when both identity values are provided.\n def configure_identity(self, dashboard_id: int, git_username: str | None, git_email: str | None) -> None:\n with belief_scope(\"GitService.configure_identity\"):\n normalized_username = str(git_username or \"\").strip()\n normalized_email = str(git_email or \"\").strip()\n if not normalized_username or not normalized_email:\n return\n repo = self.get_repo(dashboard_id)\n try:\n with repo.config_writer(config_level=\"repository\") as config_writer:\n config_writer.set_value(\"user\", \"name\", normalized_username)\n config_writer.set_value(\"user\", \"email\", normalized_email)\n logger.reason(f\"Applied repository-local git identity for dashboard {dashboard_id}\", extra={\"src\": \"configure_identity\"})\n except Exception as e:\n logger.error(f\"[configure_identity][Coherence:Failed] Failed to configure git identity: {e}\")\n raise HTTPException(status_code=500, detail=f\"Failed to configure git identity: {e!s}\")\n # endregion configure_identity\n# #endregion GitServiceBase\n# #endregion GitServiceBase\n" + "body": "# #region GitServiceBase [C:4] [TYPE Module] [SEMANTICS git, repository, clone, base, mixin, lock, http]\n# @LAYER: Infra\n# @BRIEF Core GitService base class — initialization, path resolution, repo lifecycle (init/delete/get), identity configuration, concurrent locking, and shared HTTP client pool.\n# @RELATION INHERITED_BY -> [GitService]\n# @RELATION DEPENDS_ON -> [SessionLocal]\n# @RELATION DEPENDS_ON -> [AppConfigRecord]\n# @RELATION DEPENDS_ON -> [GitRepository]\n\nimport os\nimport re\nimport shutil\nimport threading\nfrom contextlib import contextmanager\nfrom pathlib import Path\n\nimport httpx\nfrom fastapi import HTTPException\nfrom git import Repo\nfrom git.exc import InvalidGitRepositoryError, NoSuchPathError\n\nfrom src.core.database import SessionLocal\nfrom src.core.logger import belief_scope, logger\nfrom src.models.config import AppConfigRecord\nfrom src.models.git import GitRepository\n\n\n# #region GitServiceBase [C:4] [TYPE Class]\n# @BRIEF Base class for GitService providing initialization, path resolution, repository lifecycle, identity, concurrent locking, and shared HTTP client.\n# @PRE base_path is a valid string path.\n# @POST GitService is initialized; base_path directory exists; shared AsyncClient ready; lock registry empty.\n# @SIDE_EFFECT Creates HTTP connection pool (max_keepalive=20, max_connections=100).\nclass GitServiceBase:\n # region GitService_init [C:4] [TYPE Function]\n # @PURPOSE: Initializes the GitService with a base path, concurrent access locks, and shared HTTP client.\n # @PRE: base_path is a valid string path.\n # @POST: GitService is initialized; base_path directory exists; _lock_registry, _http_client ready.\n def __init__(self, base_path: str = \"git_repos\"):\n with belief_scope(\"GitService.__init__\"):\n backend_root = Path(__file__).parents[3]\n self.legacy_base_path = str((backend_root / \"git_repos\").resolve())\n self._uses_default_base_path = base_path == \"git_repos\"\n self.base_path = self._resolve_base_path(base_path)\n self._ensure_base_path_exists()\n\n # Fix 3: Per-dashboard reentrant lock registry for concurrent access protection\n self._lock_registry: dict[int, threading.RLock] = {}\n self._reg_lock = threading.Lock()\n\n # Fix 5: Shared httpx.AsyncClient with connection pooling\n self._http_client = httpx.AsyncClient(\n timeout=30.0,\n limits=httpx.Limits(max_keepalive_connections=20, max_connections=100),\n )\n # endregion GitService_init\n\n # region _get_lock [C:2] [TYPE Function] [SEMANTICS lock,concurrency]\n # @BRIEF Get or create a per-dashboard reentrant lock for thread-safe GitPython access.\n # @PRE: dashboard_id is a valid integer.\n # @POST: Returns a threading.RLock unique to the given dashboard_id.\n def _get_lock(self, dashboard_id: int) -> threading.RLock:\n with self._reg_lock:\n if dashboard_id not in self._lock_registry:\n self._lock_registry[dashboard_id] = threading.RLock()\n return self._lock_registry[dashboard_id]\n # endregion _get_lock\n\n # region _locked [C:2] [TYPE Function] [SEMANTICS lock,context,concurrency]\n # @BRIEF Context manager that acquires the per-dashboard reentrant lock for the duration of the block.\n # @PRE: dashboard_id is a valid integer.\n # @POST: Lock is acquired on enter, released on exit.\n @contextmanager\n def _locked(self, dashboard_id: int):\n lock = self._get_lock(dashboard_id)\n lock.acquire()\n try:\n yield\n finally:\n lock.release()\n # endregion _locked\n\n # region _clone_with_auth [C:2] [TYPE Function] [SEMANTICS git,clone,auth,security]\n # @BRIEF Clone repository with PAT and immediately strip credentials from origin remote URL.\n # @PRE: remote_url is a valid Git URL; pat is provided when required; repo_path is writable.\n # @POST: Repo cloned at repo_path; origin remote URL has no embedded PAT.\n # @SIDE_EFFECT Clones remote repository to local filesystem.\n def _clone_with_auth(self, remote_url: str, repo_path: str, pat: str) -> Repo:\n auth_url = remote_url\n if pat and \"://\" in remote_url:\n proto, rest = remote_url.split(\"://\", 1)\n auth_url = f\"{proto}://oauth2:{pat}@{rest}\"\n repo = Repo.clone_from(auth_url, repo_path)\n # Strip PAT from origin URL to prevent credential leakage in .git/config, logs, ps aux\n repo.git.remote(\"set-url\", \"origin\", remote_url)\n return repo\n # endregion _clone_with_auth\n\n # region _ensure_base_path_exists [TYPE Function]\n # @PURPOSE: Ensure the repositories root directory exists and is a directory.\n # @PRE: self.base_path is resolved to filesystem path.\n # @POST: self.base_path exists as directory or raises ValueError.\n def _ensure_base_path_exists(self) -> None:\n base = Path(self.base_path)\n if base.exists() and not base.is_dir():\n raise ValueError(f\"Git repositories base path is not a directory: {self.base_path}\")\n try:\n base.mkdir(parents=True, exist_ok=True)\n except (PermissionError, OSError) as e:\n logger.warning(\n f\"[_ensure_base_path_exists][Coherence:Failed] Cannot create Git repositories base path: {self.base_path}. Error: {e}\"\n )\n raise ValueError(f\"Cannot create Git repositories base path: {self.base_path}. {e}\")\n # endregion _ensure_base_path_exists\n\n # region _resolve_base_path [TYPE Function]\n # @PURPOSE: Resolve base repository directory from explicit argument or global storage settings.\n # @PRE: base_path is a string path.\n # @POST: Returns absolute path for Git repositories root.\n # @RETURN: str\n def _resolve_base_path(self, base_path: str) -> str:\n backend_root = Path(__file__).parents[3]\n fallback_path = str((backend_root / base_path).resolve())\n if base_path != \"git_repos\":\n return fallback_path\n try:\n session = SessionLocal()\n try:\n config_row = session.query(AppConfigRecord).filter(AppConfigRecord.id == \"global\").first()\n finally:\n session.close()\n payload = (config_row.payload if config_row and config_row.payload else {}) if config_row else {}\n storage_cfg = payload.get(\"settings\", {}).get(\"storage\", {}) if isinstance(payload, dict) else {}\n root_path = str(storage_cfg.get(\"root_path\", \"\")).strip()\n repo_path = str(storage_cfg.get(\"repo_path\", \"\")).strip()\n if not root_path:\n return fallback_path\n project_root = Path(__file__).parents[4]\n root = Path(root_path)\n if not root.is_absolute():\n root = (project_root / root).resolve()\n repo_root = Path(repo_path) if repo_path else Path(\"repositorys\")\n if repo_root.is_absolute():\n return str(repo_root.resolve())\n return str((root / repo_root).resolve())\n except Exception as e:\n logger.warning(f\"[_resolve_base_path][Coherence:Failed] Falling back to default path: {e}\")\n return fallback_path\n # endregion _resolve_base_path\n\n # region _normalize_repo_key [TYPE Function]\n # @PURPOSE: Convert user/dashboard-provided key to safe filesystem directory name.\n # @PRE: repo_key can be None/empty.\n # @POST: Returns normalized non-empty key.\n # @RETURN: str\n def _normalize_repo_key(self, repo_key: str | None) -> str:\n raw_key = str(repo_key or \"\").strip().lower()\n normalized = re.sub(r\"[^a-z0-9._-]+\", \"-\", raw_key).strip(\"._-\")\n return normalized or \"dashboard\"\n # endregion _normalize_repo_key\n\n # region _update_repo_local_path [TYPE Function]\n # @PURPOSE: Persist repository local_path in GitRepository table when record exists.\n # @PRE: dashboard_id is valid integer.\n # @POST: local_path is updated for existing record.\n def _update_repo_local_path(self, dashboard_id: int, local_path: str) -> None:\n try:\n session = SessionLocal()\n try:\n db_repo = (\n session.query(GitRepository)\n .filter(GitRepository.dashboard_id == int(dashboard_id))\n .first()\n )\n if db_repo:\n db_repo.local_path = local_path\n session.commit()\n finally:\n session.close()\n except Exception as e:\n logger.warning(f\"[_update_repo_local_path][Coherence:Failed] {e}\")\n # endregion _update_repo_local_path\n\n # region _migrate_repo_directory [TYPE Function]\n # @PURPOSE: Move legacy repository directory to target path and sync DB metadata.\n # @PRE: source_path exists.\n # @POST: Repository content available at target_path.\n # @RETURN: str\n def _migrate_repo_directory(self, dashboard_id: int, source_path: str, target_path: str) -> str:\n source_abs = os.path.abspath(source_path)\n target_abs = os.path.abspath(target_path)\n if source_abs == target_abs:\n return source_abs\n if os.path.exists(target_abs):\n logger.reason(f\"Target already exists, keeping source path: {target_abs}\", extra={\"src\": \"_migrate_repo_directory\"})\n return source_abs\n Path(target_abs).parent.mkdir(parents=True, exist_ok=True)\n try:\n os.replace(source_abs, target_abs)\n except OSError:\n shutil.move(source_abs, target_abs)\n self._update_repo_local_path(dashboard_id, target_abs)\n logger.info(\n f\"[_migrate_repo_directory][Coherence:OK] Repository migrated for dashboard {dashboard_id}: {source_abs} -> {target_abs}\"\n )\n return target_abs\n # endregion _migrate_repo_directory\n\n # region _get_repo_path [TYPE Function]\n # @PURPOSE: Resolves the local filesystem path for a dashboard's repository.\n # @PARAM: dashboard_id (int)\n # @PARAM: repo_key (Optional[str]) - Slug-like key used when DB local_path is absent.\n # @PRE: dashboard_id is an integer.\n # @POST: Returns DB-local_path when present, otherwise base_path/.\n # @RETURN: str\n def _get_repo_path(self, dashboard_id: int, repo_key: str | None = None) -> str:\n with belief_scope(\"GitService._get_repo_path\"):\n if dashboard_id is None:\n raise ValueError(\"dashboard_id cannot be None\")\n self._ensure_base_path_exists()\n fallback_key = repo_key if repo_key is not None else str(dashboard_id)\n normalized_key = self._normalize_repo_key(fallback_key)\n target_path = os.path.join(self.base_path, normalized_key)\n if not self._uses_default_base_path:\n return target_path\n try:\n session = SessionLocal()\n try:\n db_repo = (\n session.query(GitRepository)\n .filter(GitRepository.dashboard_id == int(dashboard_id))\n .first()\n )\n finally:\n session.close()\n if db_repo and db_repo.local_path:\n db_path = os.path.abspath(db_repo.local_path)\n if os.path.exists(db_path):\n if (\n os.path.abspath(self.base_path) != os.path.abspath(self.legacy_base_path)\n and db_path.startswith(os.path.abspath(self.legacy_base_path) + os.sep)\n ):\n return self._migrate_repo_directory(dashboard_id, db_path, target_path)\n return db_path\n except Exception as e:\n logger.warning(f\"[_get_repo_path][Coherence:Failed] Could not resolve local_path from DB: {e}\")\n legacy_id_path = os.path.join(self.legacy_base_path, str(dashboard_id))\n if os.path.exists(legacy_id_path) and not os.path.exists(target_path):\n return self._migrate_repo_directory(dashboard_id, legacy_id_path, target_path)\n if os.path.exists(target_path):\n self._update_repo_local_path(dashboard_id, target_path)\n return target_path\n # endregion _get_repo_path\n\n # region init_repo [C:4] [TYPE Function] [SEMANTICS git,clone,init,lock]\n # @PURPOSE: Initialize or clone a repository for a dashboard with concurrent access protection.\n # @PARAM: dashboard_id (int), remote_url (str), pat (str), repo_key (Optional[str]).\n # @PRE: dashboard_id is int, remote_url is valid Git URL, pat is provided.\n # @POST: Repository is cloned or opened at the local path. Origin remote URL has no embedded PAT.\n # @SIDE_EFFECT Clones remote repository; modifies local filesystem; protected by per-dashboard lock.\n # @RETURN: Repo\n def init_repo(self, dashboard_id: int, remote_url: str, pat: str, repo_key: str | None = None) -> Repo:\n with self._locked(dashboard_id):\n with belief_scope(\"GitService.init_repo\"):\n self._ensure_base_path_exists()\n repo_path = self._get_repo_path(dashboard_id, repo_key=repo_key or str(dashboard_id))\n Path(repo_path).parent.mkdir(parents=True, exist_ok=True)\n if os.path.exists(repo_path):\n logger.reason(f\"Opening existing repo at {repo_path}\", extra={\"src\": \"init_repo\"})\n try:\n repo = Repo(repo_path)\n except (InvalidGitRepositoryError, NoSuchPathError):\n logger.reason(f\"Existing path is not a Git repository, recreating: {repo_path}\", extra={\"src\": \"init_repo\"})\n stale_path = Path(repo_path)\n if stale_path.exists():\n shutil.rmtree(stale_path, ignore_errors=True)\n if stale_path.exists():\n try:\n stale_path.unlink()\n except Exception:\n pass\n repo = self._clone_with_auth(remote_url, repo_path, pat)\n self._ensure_gitflow_branches(repo, dashboard_id)\n return repo\n logger.reason(f\"Cloning {remote_url} to {repo_path}\", extra={\"src\": \"init_repo\"})\n repo = self._clone_with_auth(remote_url, repo_path, pat)\n self._ensure_gitflow_branches(repo, dashboard_id)\n return repo\n # endregion init_repo\n\n # region delete_repo [C:4] [TYPE Function] [SEMANTICS git,delete,lock]\n # @PURPOSE: Remove local repository and DB binding for a dashboard with concurrent access protection.\n # @PRE: dashboard_id is a valid integer.\n # @POST: Local path is deleted when present and GitRepository row is removed.\n # @SIDE_EFFECT Deletes filesystem directory and DB record; protected by per-dashboard lock.\n def delete_repo(self, dashboard_id: int) -> None:\n with self._locked(dashboard_id):\n with belief_scope(\"GitService.delete_repo\"):\n repo_path = self._get_repo_path(dashboard_id)\n removed_files = False\n if os.path.exists(repo_path):\n if os.path.isdir(repo_path):\n shutil.rmtree(repo_path)\n else:\n os.remove(repo_path)\n removed_files = True\n session = SessionLocal()\n try:\n db_repo = (\n session.query(GitRepository)\n .filter(GitRepository.dashboard_id == int(dashboard_id))\n .first()\n )\n if db_repo:\n session.delete(db_repo)\n session.commit()\n return\n if removed_files:\n return\n raise HTTPException(\n status_code=404,\n detail=f\"Repository for dashboard {dashboard_id} not found\",\n )\n except HTTPException:\n session.rollback()\n raise\n except Exception as e:\n session.rollback()\n logger.error(f\"[delete_repo][Coherence:Failed] Failed to delete repository for dashboard {dashboard_id}: {e}\")\n raise HTTPException(status_code=500, detail=f\"Failed to delete repository: {e!s}\")\n finally:\n session.close()\n # endregion delete_repo\n\n # region get_repo [C:4] [TYPE Function] [SEMANTICS git,open,lock]\n # @PURPOSE: Get Repo object for a dashboard with concurrent access protection.\n # @PRE: Repository must exist on disk for the given dashboard_id.\n # @POST: Returns a GitPython Repo instance for the dashboard.\n # @RETURN: Repo\n def get_repo(self, dashboard_id: int) -> Repo:\n with self._locked(dashboard_id):\n with belief_scope(\"GitService.get_repo\"):\n repo_path = self._get_repo_path(dashboard_id)\n if not os.path.exists(repo_path):\n logger.error(f\"[get_repo][Coherence:Failed] Repository for dashboard {dashboard_id} does not exist\")\n raise HTTPException(status_code=404, detail=f\"Repository for dashboard {dashboard_id} not found\")\n try:\n return Repo(repo_path)\n except Exception as e:\n logger.error(f\"[get_repo][Coherence:Failed] Failed to open repository at {repo_path}: {e}\")\n raise HTTPException(status_code=500, detail=\"Failed to open local Git repository\")\n # endregion get_repo\n\n # region configure_identity [C:4] [TYPE Function] [SEMANTICS git,identity,lock]\n # @PURPOSE: Configure repository-local Git committer identity with concurrent access protection.\n # @PRE: dashboard_id repository exists; git_username/git_email may be empty.\n # @POST: Repository config has user.name and user.email when both identity values are provided.\n # @SIDE_EFFECT Writes to repository git config; protected by per-dashboard lock.\n def configure_identity(self, dashboard_id: int, git_username: str | None, git_email: str | None) -> None:\n with self._locked(dashboard_id):\n with belief_scope(\"GitService.configure_identity\"):\n normalized_username = str(git_username or \"\").strip()\n normalized_email = str(git_email or \"\").strip()\n if not normalized_username or not normalized_email:\n return\n repo = self.get_repo(dashboard_id)\n try:\n with repo.config_writer(config_level=\"repository\") as config_writer:\n config_writer.set_value(\"user\", \"name\", normalized_username)\n config_writer.set_value(\"user\", \"email\", normalized_email)\n logger.reason(f\"Applied repository-local git identity for dashboard {dashboard_id}\", extra={\"src\": \"configure_identity\"})\n except Exception as e:\n logger.error(f\"[configure_identity][Coherence:Failed] Failed to configure git identity: {e}\")\n raise HTTPException(status_code=500, detail=f\"Failed to configure git identity: {e!s}\")\n # endregion configure_identity\n\n # region close [C:2] [TYPE Function] [SEMANTICS http,cleanup,shutdown]\n # @BRIEF Gracefully close the shared HTTP client (connection pool).\n # @PRE: _http_client is initialized.\n # @POST: HTTP connections closed.\n async def close(self):\n await self._http_client.aclose()\n # endregion close\n# #endregion GitServiceBase\n# #endregion GitServiceBase\n" }, { "contract_id": "GitServiceBranchMixin", @@ -59288,13 +58537,13 @@ "contract_type": "Module", "file_path": "backend/src/services/git/_merge.py", "start_line": 1, - "end_line": 277, + "end_line": 300, "tier": "TIER_2", - "complexity": 3, + "complexity": 4, "metadata": { - "COMPLEXITY": 3, + "COMPLEXITY": 4, "LAYER": "Infra", - "PURPOSE": "Merge operations for GitService — conflict detection, resolution, abort, continue, and direct promote." + "PURPOSE": "Merge operations for GitService — conflict detection, resolution, abort, continue, and direct promote (all concurrent-safe via per-dashboard locks)." }, "relations": [ { @@ -59322,6 +58571,33 @@ "value": "Infra" } }, + { + "code": "missing_required_tag", + "tag": "POST", + "message": "@POST is required for contract type 'Module' at C4", + "detail": { + "actual_complexity": 4, + "contract_type": "Module" + } + }, + { + "code": "missing_required_tag", + "tag": "PRE", + "message": "@PRE is required for contract type 'Module' at C4", + "detail": { + "actual_complexity": 4, + "contract_type": "Module" + } + }, + { + "code": "missing_required_tag", + "tag": "SIDE_EFFECT", + "message": "@SIDE_EFFECT is required for contract type 'Module' at C4", + "detail": { + "actual_complexity": 4, + "contract_type": "Module" + } + }, { "code": "invalid_relation_predicate", "tag": "RELATION", @@ -59343,7 +58619,7 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region GitServiceMergeMixin [C:3] [TYPE Module] [SEMANTICS git, merge, branch, conflict, resolution]\n# @LAYER: Infra\n# @BRIEF Merge operations for GitService — conflict detection, resolution, abort, continue, and direct promote.\n# @RELATION USED_BY -> [GitService]\n\nimport os\nfrom pathlib import Path\nfrom typing import Any\n\nfrom fastapi import HTTPException\nfrom git import Repo\nfrom git.exc import GitCommandError\nfrom git.objects.blob import Blob\n\nfrom src.core.logger import belief_scope\n\n\n# #region GitServiceMergeMixin [C:3] [TYPE Class]\n# @BRIEF Mixin providing merge operations for GitService.\nclass GitServiceMergeMixin:\n # region _read_blob_text [TYPE Function]\n # @PURPOSE: Read text from a Git blob.\n def _read_blob_text(self, blob: Blob) -> str:\n with belief_scope(\"GitService._read_blob_text\"):\n if blob is None:\n return \"\"\n try:\n return blob.data_stream.read().decode(\"utf-8\", errors=\"replace\")\n except Exception:\n return \"\"\n # endregion _read_blob_text\n\n # region _get_unmerged_file_paths [TYPE Function]\n # @PURPOSE: List files with merge conflicts.\n def _get_unmerged_file_paths(self, repo: Repo) -> list[str]:\n with belief_scope(\"GitService._get_unmerged_file_paths\"):\n try:\n return sorted(list(repo.index.unmerged_blobs().keys()))\n except Exception:\n return []\n # endregion _get_unmerged_file_paths\n\n # region _build_unfinished_merge_payload [TYPE Function]\n # @PURPOSE: Build payload for unfinished merge state.\n def _build_unfinished_merge_payload(self, repo: Repo) -> dict[str, Any]:\n with belief_scope(\"GitService._build_unfinished_merge_payload\"):\n merge_head_path = os.path.join(repo.git_dir, \"MERGE_HEAD\")\n merge_head_value = \"\"\n merge_msg_preview = \"\"\n current_branch = \"unknown\"\n try:\n merge_head_value = Path(merge_head_path).read_text(encoding=\"utf-8\").strip()\n except Exception:\n merge_head_value = \"\"\n try:\n merge_msg_path = os.path.join(repo.git_dir, \"MERGE_MSG\")\n if os.path.exists(merge_msg_path):\n merge_msg_preview = (\n Path(merge_msg_path).read_text(encoding=\"utf-8\").strip().splitlines()[:1] or [\"\"]\n )[0]\n except Exception:\n merge_msg_preview = \"\"\n try:\n current_branch = repo.active_branch.name\n except Exception:\n current_branch = \"detached_or_unknown\"\n conflicts_count = len(self._get_unmerged_file_paths(repo))\n return {\n \"error_code\": \"GIT_UNFINISHED_MERGE\",\n \"message\": (\n \"\\u0412 \\u0440\\u0435\\u043f\\u043e\\u0437\\u0438\\u0442\\u043e\\u0440\\u0438\\u0438 \\u0435\\u0441\\u0442\\u044c \\u043d\\u0435\\u0437\\u0430\\u0432\\u0435\\u0440\\u0448\\u0451\\u043d\\u043d\\u043e\\u0435 \\u0441\\u043b\\u0438\\u044f\\u043d\\u0438\\u0435. \"\n \"\\u0417\\u0430\\u0432\\u0435\\u0440\\u0448\\u0438\\u0442\\u0435 \\u0438\\u043b\\u0438 \\u043e\\u0442\\u043c\\u0435\\u043d\\u0438\\u0442\\u0435 \\u0441\\u043b\\u0438\\u044f\\u043d\\u0438\\u0435 \\u0432\\u0440\\u0443\\u0447\\u043d\\u0443\\u044e.\"\n ),\n \"repository_path\": repo.working_tree_dir,\n \"git_dir\": repo.git_dir,\n \"current_branch\": current_branch,\n \"merge_head\": merge_head_value,\n \"merge_message_preview\": merge_msg_preview,\n \"conflicts_count\": conflicts_count,\n \"next_steps\": [\n \"\\u041e\\u0442\\u043a\\u0440\\u043e\\u0439\\u0442\\u0435 \\u043b\\u043e\\u043a\\u0430\\u043b\\u044c\\u043d\\u044b\\u0439 \\u0440\\u0435\\u043f\\u043e\\u0437\\u0438\\u0442\\u043e\\u0440\\u0438\\u0439 \\u043f\\u043e \\u043f\\u0443\\u0442\\u0438 repository_path\",\n \"\\u041f\\u0440\\u043e\\u0432\\u0435\\u0440\\u044c\\u0442\\u0435 \\u0441\\u043e\\u0441\\u0442\\u043e\\u044f\\u043d\\u0438\\u0435: git status\",\n \"\\u0420\\u0430\\u0437\\u0440\\u0435\\u0448\\u0438\\u0442\\u0435 \\u043a\\u043e\\u043d\\u0444\\u043b\\u0438\\u043a\\u0442\\u044b \\u0438 \\u0432\\u044b\\u043f\\u043e\\u043b\\u043d\\u0438\\u0442\\u0435 commit, \\u043b\\u0438\\u0431\\u043e \\u043e\\u0442\\u043c\\u0435\\u043d\\u0438\\u0442\\u0435: git merge --abort\",\n \"\\u041f\\u043e\\u0441\\u043b\\u0435 \\u0437\\u0430\\u0432\\u0435\\u0440\\u0448\\u0435\\u043d\\u0438\\u044f/\\u043e\\u0442\\u043c\\u0435\\u043d\\u044b \\u0441\\u043b\\u0438\\u044f\\u043d\\u0438\\u044f \\u043f\\u043e\\u0432\\u0442\\u043e\\u0440\\u0438\\u0442\\u0435 Pull \\u0438\\u0437 \\u0438\\u043d\\u0442\\u0435\\u0440\\u0444\\u0435\\u0439\\u0441\\u0430\",\n ],\n \"manual_commands\": [\"git status\", \"git add \", 'git commit -m \"resolve merge conflicts\"', \"git merge --abort\"],\n }\n # endregion _build_unfinished_merge_payload\n\n # region get_merge_status [TYPE Function]\n # @PURPOSE: Get current merge status for a dashboard repository.\n def get_merge_status(self, dashboard_id: int) -> dict[str, Any]:\n with belief_scope(\"GitService.get_merge_status\"):\n repo = self.get_repo(dashboard_id)\n merge_head_path = os.path.join(repo.git_dir, \"MERGE_HEAD\")\n if not os.path.exists(merge_head_path):\n current_branch = \"unknown\"\n try:\n current_branch = repo.active_branch.name\n except Exception:\n current_branch = \"detached_or_unknown\"\n return {\n \"has_unfinished_merge\": False,\n \"repository_path\": repo.working_tree_dir,\n \"git_dir\": repo.git_dir,\n \"current_branch\": current_branch,\n \"merge_head\": None,\n \"merge_message_preview\": None,\n \"conflicts_count\": 0,\n }\n payload = self._build_unfinished_merge_payload(repo)\n return {\n \"has_unfinished_merge\": True,\n \"repository_path\": payload[\"repository_path\"],\n \"git_dir\": payload[\"git_dir\"],\n \"current_branch\": payload[\"current_branch\"],\n \"merge_head\": payload[\"merge_head\"],\n \"merge_message_preview\": payload[\"merge_message_preview\"],\n \"conflicts_count\": int(payload.get(\"conflicts_count\") or 0),\n }\n # endregion get_merge_status\n\n # region get_merge_conflicts [TYPE Function]\n # @PURPOSE: List all files with conflicts and their contents.\n def get_merge_conflicts(self, dashboard_id: int) -> list[dict[str, Any]]:\n with belief_scope(\"GitService.get_merge_conflicts\"):\n repo = self.get_repo(dashboard_id)\n conflicts = []\n unmerged = repo.index.unmerged_blobs()\n for file_path, stages in unmerged.items():\n mine_blob = None\n theirs_blob = None\n for stage, blob in stages:\n if stage == 2:\n mine_blob = blob\n elif stage == 3:\n theirs_blob = blob\n conflicts.append({\n \"file_path\": file_path,\n \"mine\": self._read_blob_text(mine_blob) if mine_blob else \"\",\n \"theirs\": self._read_blob_text(theirs_blob) if theirs_blob else \"\",\n })\n return sorted(conflicts, key=lambda item: item[\"file_path\"])\n # endregion get_merge_conflicts\n\n # region resolve_merge_conflicts [TYPE Function]\n # @PURPOSE: Resolve conflicts using specified strategy.\n def resolve_merge_conflicts(self, dashboard_id: int, resolutions: list[dict[str, Any]]) -> list[str]:\n with belief_scope(\"GitService.resolve_merge_conflicts\"):\n repo = self.get_repo(dashboard_id)\n resolved_files: list[str] = []\n repo_root = os.path.abspath(str(repo.working_tree_dir or \"\"))\n if not repo_root:\n raise HTTPException(status_code=500, detail=\"Repository working tree directory is unavailable\")\n for item in resolutions or []:\n file_path = str(item.get(\"file_path\") or \"\").strip()\n strategy = str(item.get(\"resolution\") or \"\").strip().lower()\n content = item.get(\"content\")\n if not file_path:\n raise HTTPException(status_code=400, detail=\"resolution.file_path is required\")\n if strategy not in {\"mine\", \"theirs\", \"manual\"}:\n raise HTTPException(status_code=400, detail=f\"Unsupported resolution strategy: {strategy}\")\n if strategy == \"mine\":\n repo.git.checkout(\"--ours\", \"--\", file_path)\n elif strategy == \"theirs\":\n repo.git.checkout(\"--theirs\", \"--\", file_path)\n else:\n abs_target = os.path.abspath(os.path.join(repo_root, file_path))\n if abs_target != repo_root and not abs_target.startswith(repo_root + os.sep):\n raise HTTPException(status_code=400, detail=f\"Invalid conflict file path: {file_path}\")\n os.makedirs(os.path.dirname(abs_target), exist_ok=True)\n with open(abs_target, \"w\", encoding=\"utf-8\") as file_obj:\n file_obj.write(str(content or \"\"))\n repo.git.add(file_path)\n resolved_files.append(file_path)\n return resolved_files\n # endregion resolve_merge_conflicts\n\n # region abort_merge [TYPE Function]\n # @PURPOSE: Abort ongoing merge.\n def abort_merge(self, dashboard_id: int) -> dict[str, Any]:\n with belief_scope(\"GitService.abort_merge\"):\n repo = self.get_repo(dashboard_id)\n try:\n repo.git.merge(\"--abort\")\n except GitCommandError as e:\n details = str(e)\n lowered = details.lower()\n if \"there is no merge to abort\" in lowered or \"no merge to abort\" in lowered:\n return {\"status\": \"no_merge_in_progress\"}\n raise HTTPException(status_code=409, detail=f\"Cannot abort merge: {details}\")\n return {\"status\": \"aborted\"}\n # endregion abort_merge\n\n # region continue_merge [TYPE Function]\n # @PURPOSE: Finalize merge after conflict resolution.\n def continue_merge(self, dashboard_id: int, message: str | None = None) -> dict[str, Any]:\n with belief_scope(\"GitService.continue_merge\"):\n repo = self.get_repo(dashboard_id)\n unmerged_files = self._get_unmerged_file_paths(repo)\n if unmerged_files:\n raise HTTPException(\n status_code=409,\n detail={\n \"error_code\": \"GIT_MERGE_CONFLICTS_REMAIN\",\n \"message\": \"\\u041d\\u0435\\u0432\\u043e\\u0437\\u043c\\u043e\\u0436\\u043d\\u043e \\u0437\\u0430\\u0432\\u0435\\u0440\\u0448\\u0438\\u0442\\u044c merge: \\u043e\\u0441\\u0442\\u0430\\u043b\\u0438\\u0441\\u044c \\u043d\\u0435\\u0440\\u0430\\u0437\\u0440\\u0435\\u0448\\u0451\\u043d\\u043d\\u044b\\u0435 \\u043a\\u043e\\u043d\\u0444\\u043b\\u0438\\u043a\\u0442\\u044b.\",\n \"unresolved_files\": unmerged_files,\n },\n )\n try:\n normalized_message = str(message or \"\").strip()\n if normalized_message:\n repo.git.commit(\"-m\", normalized_message)\n else:\n repo.git.commit(\"--no-edit\")\n except GitCommandError as e:\n details = str(e)\n lowered = details.lower()\n if \"nothing to commit\" in lowered:\n return {\"status\": \"already_clean\"}\n raise HTTPException(status_code=409, detail=f\"Cannot continue merge: {details}\")\n commit_hash = \"\"\n try:\n commit_hash = repo.head.commit.hexsha\n except Exception:\n commit_hash = \"\"\n return {\"status\": \"committed\", \"commit_hash\": commit_hash}\n # endregion continue_merge\n\n # region promote_direct_merge [TYPE Function]\n # @PURPOSE: Perform direct merge between branches in local repo and push target branch.\n # @PRE: Repository exists and both branches are valid.\n # @POST: Target branch contains merged changes from source branch.\n # @RETURN: Dict[str, Any]\n def promote_direct_merge(self, dashboard_id: int, from_branch: str, to_branch: str) -> dict[str, Any]:\n with belief_scope(\"GitService.promote_direct_merge\"):\n if not from_branch or not to_branch:\n raise HTTPException(status_code=400, detail=\"from_branch and to_branch are required\")\n repo = self.get_repo(dashboard_id)\n source = from_branch.strip()\n target = to_branch.strip()\n if source == target:\n raise HTTPException(status_code=400, detail=\"from_branch and to_branch must be different\")\n try:\n origin = repo.remote(name=\"origin\")\n except ValueError:\n raise HTTPException(status_code=400, detail=\"Remote 'origin' not configured\")\n try:\n origin.fetch()\n if source not in [head.name for head in repo.heads]:\n if f\"origin/{source}\" in [ref.name for ref in repo.refs]:\n repo.git.checkout(\"-b\", source, f\"origin/{source}\")\n else:\n raise HTTPException(status_code=404, detail=f\"Source branch '{source}' not found\")\n if target in [head.name for head in repo.heads]:\n repo.git.checkout(target)\n elif f\"origin/{target}\" in [ref.name for ref in repo.refs]:\n repo.git.checkout(\"-b\", target, f\"origin/{target}\")\n else:\n raise HTTPException(status_code=404, detail=f\"Target branch '{target}' not found\")\n try:\n origin.pull(target)\n except Exception:\n pass\n repo.git.merge(source, \"--no-ff\", \"-m\", f\"chore(flow): promote {source} -> {target}\")\n origin.push(refspec=f\"{target}:{target}\")\n except HTTPException:\n raise\n except Exception as e:\n message = str(e)\n if \"CONFLICT\" in message.upper():\n raise HTTPException(status_code=409, detail=f\"Merge conflict during direct promote: {message}\")\n raise HTTPException(status_code=500, detail=f\"Direct promote failed: {message}\")\n return {\"mode\": \"direct\", \"from_branch\": source, \"to_branch\": target, \"status\": \"merged\"}\n # endregion promote_direct_merge\n# #endregion GitServiceMergeMixin\n# #endregion GitServiceMergeMixin\n" + "body": "# #region GitServiceMergeMixin [C:4] [TYPE Module] [SEMANTICS git, merge, branch, conflict, resolution, lock]\n# @LAYER: Infra\n# @BRIEF Merge operations for GitService — conflict detection, resolution, abort, continue, and direct promote (all concurrent-safe via per-dashboard locks).\n# @RELATION USED_BY -> [GitService]\n\nimport os\nfrom pathlib import Path\nfrom typing import Any\n\nfrom fastapi import HTTPException\nfrom git import Repo\nfrom git.exc import GitCommandError\nfrom git.objects.blob import Blob\n\nfrom src.core.logger import belief_scope\n\n\n# #region GitServiceMergeMixin [C:3] [TYPE Class]\n# @BRIEF Mixin providing merge operations for GitService.\nclass GitServiceMergeMixin:\n # region _read_blob_text [TYPE Function]\n # @PURPOSE: Read text from a Git blob.\n def _read_blob_text(self, blob: Blob) -> str:\n with belief_scope(\"GitService._read_blob_text\"):\n if blob is None:\n return \"\"\n try:\n return blob.data_stream.read().decode(\"utf-8\", errors=\"replace\")\n except Exception:\n return \"\"\n # endregion _read_blob_text\n\n # region _get_unmerged_file_paths [TYPE Function]\n # @PURPOSE: List files with merge conflicts.\n def _get_unmerged_file_paths(self, repo: Repo) -> list[str]:\n with belief_scope(\"GitService._get_unmerged_file_paths\"):\n try:\n return sorted(list(repo.index.unmerged_blobs().keys()))\n except Exception:\n return []\n # endregion _get_unmerged_file_paths\n\n # region _build_unfinished_merge_payload [TYPE Function]\n # @PURPOSE: Build payload for unfinished merge state.\n def _build_unfinished_merge_payload(self, repo: Repo) -> dict[str, Any]:\n with belief_scope(\"GitService._build_unfinished_merge_payload\"):\n merge_head_path = os.path.join(repo.git_dir, \"MERGE_HEAD\")\n merge_head_value = \"\"\n merge_msg_preview = \"\"\n current_branch = \"unknown\"\n try:\n merge_head_value = Path(merge_head_path).read_text(encoding=\"utf-8\").strip()\n except Exception:\n merge_head_value = \"\"\n try:\n merge_msg_path = os.path.join(repo.git_dir, \"MERGE_MSG\")\n if os.path.exists(merge_msg_path):\n merge_msg_preview = (\n Path(merge_msg_path).read_text(encoding=\"utf-8\").strip().splitlines()[:1] or [\"\"]\n )[0]\n except Exception:\n merge_msg_preview = \"\"\n try:\n current_branch = repo.active_branch.name\n except Exception:\n current_branch = \"detached_or_unknown\"\n conflicts_count = len(self._get_unmerged_file_paths(repo))\n return {\n \"error_code\": \"GIT_UNFINISHED_MERGE\",\n \"message\": (\n \"\\u0412 \\u0440\\u0435\\u043f\\u043e\\u0437\\u0438\\u0442\\u043e\\u0440\\u0438\\u0438 \\u0435\\u0441\\u0442\\u044c \\u043d\\u0435\\u0437\\u0430\\u0432\\u0435\\u0440\\u0448\\u0451\\u043d\\u043d\\u043e\\u0435 \\u0441\\u043b\\u0438\\u044f\\u043d\\u0438\\u0435. \"\n \"\\u0417\\u0430\\u0432\\u0435\\u0440\\u0448\\u0438\\u0442\\u0435 \\u0438\\u043b\\u0438 \\u043e\\u0442\\u043c\\u0435\\u043d\\u0438\\u0442\\u0435 \\u0441\\u043b\\u0438\\u044f\\u043d\\u0438\\u0435 \\u0432\\u0440\\u0443\\u0447\\u043d\\u0443\\u044e.\"\n ),\n \"repository_path\": repo.working_tree_dir,\n \"git_dir\": repo.git_dir,\n \"current_branch\": current_branch,\n \"merge_head\": merge_head_value,\n \"merge_message_preview\": merge_msg_preview,\n \"conflicts_count\": conflicts_count,\n \"next_steps\": [\n \"\\u041e\\u0442\\u043a\\u0440\\u043e\\u0439\\u0442\\u0435 \\u043b\\u043e\\u043a\\u0430\\u043b\\u044c\\u043d\\u044b\\u0439 \\u0440\\u0435\\u043f\\u043e\\u0437\\u0438\\u0442\\u043e\\u0440\\u0438\\u0439 \\u043f\\u043e \\u043f\\u0443\\u0442\\u0438 repository_path\",\n \"\\u041f\\u0440\\u043e\\u0432\\u0435\\u0440\\u044c\\u0442\\u0435 \\u0441\\u043e\\u0441\\u0442\\u043e\\u044f\\u043d\\u0438\\u0435: git status\",\n \"\\u0420\\u0430\\u0437\\u0440\\u0435\\u0448\\u0438\\u0442\\u0435 \\u043a\\u043e\\u043d\\u0444\\u043b\\u0438\\u043a\\u0442\\u044b \\u0438 \\u0432\\u044b\\u043f\\u043e\\u043b\\u043d\\u0438\\u0442\\u0435 commit, \\u043b\\u0438\\u0431\\u043e \\u043e\\u0442\\u043c\\u0435\\u043d\\u0438\\u0442\\u0435: git merge --abort\",\n \"\\u041f\\u043e\\u0441\\u043b\\u0435 \\u0437\\u0430\\u0432\\u0435\\u0440\\u0448\\u0435\\u043d\\u0438\\u044f/\\u043e\\u0442\\u043c\\u0435\\u043d\\u044b \\u0441\\u043b\\u0438\\u044f\\u043d\\u0438\\u044f \\u043f\\u043e\\u0432\\u0442\\u043e\\u0440\\u0438\\u0442\\u0435 Pull \\u0438\\u0437 \\u0438\\u043d\\u0442\\u0435\\u0440\\u0444\\u0435\\u0439\\u0441\\u0430\",\n ],\n \"manual_commands\": [\"git status\", \"git add \", 'git commit -m \"resolve merge conflicts\"', \"git merge --abort\"],\n }\n # endregion _build_unfinished_merge_payload\n\n # region get_merge_status [C:4] [TYPE Function] [SEMANTICS git,merge,status,lock]\n # @PURPOSE: Get current merge status for a dashboard repository (concurrent-safe).\n def get_merge_status(self, dashboard_id: int) -> dict[str, Any]:\n with self._locked(dashboard_id):\n with belief_scope(\"GitService.get_merge_status\"):\n repo = self.get_repo(dashboard_id)\n merge_head_path = os.path.join(repo.git_dir, \"MERGE_HEAD\")\n if not os.path.exists(merge_head_path):\n current_branch = \"unknown\"\n try:\n current_branch = repo.active_branch.name\n except Exception:\n current_branch = \"detached_or_unknown\"\n return {\n \"has_unfinished_merge\": False,\n \"repository_path\": repo.working_tree_dir,\n \"git_dir\": repo.git_dir,\n \"current_branch\": current_branch,\n \"merge_head\": None,\n \"merge_message_preview\": None,\n \"conflicts_count\": 0,\n }\n payload = self._build_unfinished_merge_payload(repo)\n return {\n \"has_unfinished_merge\": True,\n \"repository_path\": payload[\"repository_path\"],\n \"git_dir\": payload[\"git_dir\"],\n \"current_branch\": payload[\"current_branch\"],\n \"merge_head\": payload[\"merge_head\"],\n \"merge_message_preview\": payload[\"merge_message_preview\"],\n \"conflicts_count\": int(payload.get(\"conflicts_count\") or 0),\n }\n # endregion get_merge_status\n\n # region get_merge_conflicts [C:4] [TYPE Function] [SEMANTICS git,conflict,list,lock]\n # @PURPOSE: List all files with conflicts and their contents (concurrent-safe).\n def get_merge_conflicts(self, dashboard_id: int) -> list[dict[str, Any]]:\n with self._locked(dashboard_id):\n with belief_scope(\"GitService.get_merge_conflicts\"):\n repo = self.get_repo(dashboard_id)\n conflicts = []\n unmerged = repo.index.unmerged_blobs()\n for file_path, stages in unmerged.items():\n mine_blob = None\n theirs_blob = None\n for stage, blob in stages:\n if stage == 2:\n mine_blob = blob\n elif stage == 3:\n theirs_blob = blob\n conflicts.append({\n \"file_path\": file_path,\n \"mine\": self._read_blob_text(mine_blob) if mine_blob else \"\",\n \"theirs\": self._read_blob_text(theirs_blob) if theirs_blob else \"\",\n })\n return sorted(conflicts, key=lambda item: item[\"file_path\"])\n # endregion get_merge_conflicts\n\n # region resolve_merge_conflicts [C:4] [TYPE Function] [SEMANTICS git,conflict,resolve,lock]\n # @PURPOSE: Resolve conflicts using specified strategy (concurrent-safe).\n def resolve_merge_conflicts(self, dashboard_id: int, resolutions: list[dict[str, Any]]) -> list[str]:\n with self._locked(dashboard_id):\n with belief_scope(\"GitService.resolve_merge_conflicts\"):\n repo = self.get_repo(dashboard_id)\n resolved_files: list[str] = []\n repo_root = os.path.abspath(str(repo.working_tree_dir or \"\"))\n if not repo_root:\n raise HTTPException(status_code=500, detail=\"Repository working tree directory is unavailable\")\n for item in resolutions or []:\n file_path = str(item.get(\"file_path\") or \"\").strip()\n strategy = str(item.get(\"resolution\") or \"\").strip().lower()\n content = item.get(\"content\")\n if not file_path:\n raise HTTPException(status_code=400, detail=\"resolution.file_path is required\")\n if strategy not in {\"mine\", \"theirs\", \"manual\"}:\n raise HTTPException(status_code=400, detail=f\"Unsupported resolution strategy: {strategy}\")\n if strategy == \"mine\":\n repo.git.checkout(\"--ours\", \"--\", file_path)\n elif strategy == \"theirs\":\n repo.git.checkout(\"--theirs\", \"--\", file_path)\n else:\n abs_target = os.path.abspath(os.path.join(repo_root, file_path))\n if abs_target != repo_root and not abs_target.startswith(repo_root + os.sep):\n raise HTTPException(status_code=400, detail=f\"Invalid conflict file path: {file_path}\")\n os.makedirs(os.path.dirname(abs_target), exist_ok=True)\n with open(abs_target, \"w\", encoding=\"utf-8\") as file_obj:\n file_obj.write(str(content or \"\"))\n repo.git.add(file_path)\n resolved_files.append(file_path)\n return resolved_files\n # endregion resolve_merge_conflicts\n\n # region abort_merge [C:4] [TYPE Function] [SEMANTICS git,merge,abort,lock]\n # @PURPOSE: Abort ongoing merge (concurrent-safe).\n def abort_merge(self, dashboard_id: int) -> dict[str, Any]:\n with self._locked(dashboard_id):\n with belief_scope(\"GitService.abort_merge\"):\n repo = self.get_repo(dashboard_id)\n try:\n repo.git.merge(\"--abort\")\n except GitCommandError as e:\n details = str(e)\n lowered = details.lower()\n if \"there is no merge to abort\" in lowered or \"no merge to abort\" in lowered:\n return {\"status\": \"no_merge_in_progress\"}\n raise HTTPException(status_code=409, detail=f\"Cannot abort merge: {details}\")\n return {\"status\": \"aborted\"}\n # endregion abort_merge\n\n # region continue_merge [C:4] [TYPE Function] [SEMANTICS git,merge,continue,lock]\n # @PURPOSE: Finalize merge after conflict resolution (concurrent-safe).\n def continue_merge(self, dashboard_id: int, message: str | None = None) -> dict[str, Any]:\n with self._locked(dashboard_id):\n with belief_scope(\"GitService.continue_merge\"):\n repo = self.get_repo(dashboard_id)\n unmerged_files = self._get_unmerged_file_paths(repo)\n if unmerged_files:\n raise HTTPException(\n status_code=409,\n detail={\n \"error_code\": \"GIT_MERGE_CONFLICTS_REMAIN\",\n \"message\": \"\\u041d\\u0435\\u0432\\u043e\\u0437\\u043c\\u043e\\u0436\\u043d\\u043e \\u0437\\u0430\\u0432\\u0435\\u0440\\u0448\\u0438\\u0442\\u044c merge: \\u043e\\u0441\\u0442\\u0430\\u043b\\u0438\\u0441\\u044c \\u043d\\u0435\\u0440\\u0430\\u0437\\u0440\\u0435\\u0448\\u0451\\u043d\\u043d\\u044b\\u0435 \\u043a\\u043e\\u043d\\u0444\\u043b\\u0438\\u043a\\u0442\\u044b.\",\n \"unresolved_files\": unmerged_files,\n },\n )\n try:\n normalized_message = str(message or \"\").strip()\n if normalized_message:\n repo.git.commit(\"-m\", normalized_message)\n else:\n repo.git.commit(\"--no-edit\")\n except GitCommandError as e:\n details = str(e)\n lowered = details.lower()\n if \"nothing to commit\" in lowered:\n return {\"status\": \"already_clean\"}\n raise HTTPException(status_code=409, detail=f\"Cannot continue merge: {details}\")\n commit_hash = \"\"\n try:\n commit_hash = repo.head.commit.hexsha\n except Exception:\n commit_hash = \"\"\n return {\"status\": \"committed\", \"commit_hash\": commit_hash}\n # endregion continue_merge\n\n # region promote_direct_merge [C:4] [TYPE Function] [SEMANTICS git,merge,promote,branch,isolation]\n # @PURPOSE: Perform direct merge between branches with branch isolation — original branch restored on error.\n # @PRE: Repository exists and both branches are valid.\n # @POST: Target branch contains merged changes from source branch. Active branch restored to original.\n # Merge survives locally even if push fails (partial success).\n # @SIDE_EFFECT: Changes local branch state during merge; restores original branch in finally block.\n # @RETURN: Dict[str, Any]\n def promote_direct_merge(self, dashboard_id: int, from_branch: str, to_branch: str) -> dict[str, Any]:\n with self._locked(dashboard_id):\n with belief_scope(\"GitService.promote_direct_merge\"):\n if not from_branch or not to_branch:\n raise HTTPException(status_code=400, detail=\"from_branch and to_branch are required\")\n repo = self.get_repo(dashboard_id)\n source = from_branch.strip()\n target = to_branch.strip()\n if source == target:\n raise HTTPException(status_code=400, detail=\"from_branch and to_branch must be different\")\n try:\n origin = repo.remote(name=\"origin\")\n except ValueError:\n raise HTTPException(status_code=400, detail=\"Remote 'origin' not configured\")\n\n # Remember original branch for restoration in finally\n original_branch = None\n try:\n original_branch = repo.active_branch.name\n except Exception:\n original_branch = None\n\n try:\n origin.fetch()\n if source not in [head.name for head in repo.heads]:\n if f\"origin/{source}\" in [ref.name for ref in repo.refs]:\n repo.git.checkout(\"-b\", source, f\"origin/{source}\")\n else:\n raise HTTPException(status_code=404, detail=f\"Source branch '{source}' not found\")\n if target in [head.name for head in repo.heads]:\n repo.git.checkout(target)\n elif f\"origin/{target}\" in [ref.name for ref in repo.refs]:\n repo.git.checkout(\"-b\", target, f\"origin/{target}\")\n else:\n raise HTTPException(status_code=404, detail=f\"Target branch '{target}' not found\")\n try:\n origin.pull(target)\n except Exception:\n pass\n repo.git.merge(source, \"--no-ff\", \"-m\", f\"chore(flow): promote {source} -> {target}\")\n origin.push(refspec=f\"{target}:{target}\")\n except HTTPException:\n raise\n except Exception as e:\n message = str(e)\n if \"CONFLICT\" in message.upper():\n raise HTTPException(status_code=409, detail=f\"Merge conflict during direct promote: {message}\")\n raise HTTPException(status_code=500, detail=f\"Direct promote failed: {message}\")\n finally:\n # Restore original branch even if merge/push partially failed\n if original_branch:\n try:\n repo.git.checkout(original_branch)\n except Exception:\n pass\n return {\"mode\": \"direct\", \"from_branch\": source, \"to_branch\": target, \"status\": \"merged\"}\n # endregion promote_direct_merge\n# #endregion GitServiceMergeMixin\n# #endregion GitServiceMergeMixin\n" }, { "contract_id": "GitServiceGitlabMixin", @@ -59749,7 +59025,7 @@ "contract_type": "Module", "file_path": "backend/src/services/llm_prompt_templates.py", "start_line": 1, - "end_line": 194, + "end_line": 205, "tier": "TIER_1", "complexity": 2, "metadata": { @@ -59788,14 +59064,14 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region llm_prompt_templates [C:2] [TYPE Module] [SEMANTICS llm, prompt, template, normalization]\n# @BRIEF Provide default LLM prompt templates and normalization helpers for runtime usage.\n# @LAYER: Domain\n# @RELATION DEPENDS_ON -> [backend.src.core.config_manager:Function]\n# @INVARIANT: All required prompt template keys are always present after normalization.\n\nfrom __future__ import annotations\n\nfrom copy import deepcopy\nfrom typing import Any\n\n# #region DEFAULT_LLM_PROMPTS [C:2] [TYPE Constant]\n# @BRIEF Default prompt templates used by documentation, dashboard validation, and git commit generation.\nDEFAULT_LLM_PROMPTS: dict[str, str] = {\n \"dashboard_validation_prompt\": (\n \"Analyze the attached dashboard screenshot and the following execution logs for health and visual issues.\\n\\n\"\n \"Logs:\\n\"\n \"{logs}\\n\\n\"\n \"Provide the analysis in JSON format with the following structure:\\n\"\n \"{\\n\"\n ' \"status\": \"PASS\" | \"WARN\" | \"FAIL\",\\n'\n ' \"summary\": \"Short summary of findings\",\\n'\n ' \"issues\": [\\n'\n \" {\\n\"\n ' \"severity\": \"WARN\" | \"FAIL\",\\n'\n ' \"message\": \"Description of the issue\",\\n'\n ' \"location\": \"Optional location info (e.g. chart name)\"\\n'\n \" }\\n\"\n \" ]\\n\"\n \"}\"\n ),\n \"documentation_prompt\": (\n \"Generate professional documentation for the following dataset and its columns.\\n\"\n \"Dataset: {dataset_name}\\n\"\n \"Columns: {columns_json}\\n\\n\"\n \"Provide the documentation in JSON format:\\n\"\n \"{\\n\"\n ' \"dataset_description\": \"General description of the dataset\",\\n'\n ' \"column_descriptions\": [\\n'\n \" {\\n\"\n ' \"name\": \"column_name\",\\n'\n ' \"description\": \"Generated description\"\\n'\n \" }\\n\"\n \" ]\\n\"\n \"}\"\n ),\n \"git_commit_prompt\": (\n \"Generate a concise and professional git commit message based on the following diff and recent history.\\n\"\n \"Use Conventional Commits format (e.g., feat: ..., fix: ..., docs: ...).\\n\\n\"\n \"Recent History:\\n\"\n \"{history}\\n\\n\"\n \"Diff:\\n\"\n \"{diff}\\n\\n\"\n \"Commit Message:\"\n ),\n}\n# #endregion DEFAULT_LLM_PROMPTS\n\n\n# #region DEFAULT_LLM_PROVIDER_BINDINGS [C:2] [TYPE Constant]\n# @BRIEF Default provider binding per task domain.\nDEFAULT_LLM_PROVIDER_BINDINGS: dict[str, str] = {\n \"dashboard_validation\": \"\",\n \"documentation\": \"\",\n \"git_commit\": \"\",\n}\n# #endregion DEFAULT_LLM_PROVIDER_BINDINGS\n\n\n# #region DEFAULT_LLM_ASSISTANT_SETTINGS [C:2] [TYPE Constant]\n# @BRIEF Default planner settings for assistant chat intent model/provider resolution.\nDEFAULT_LLM_ASSISTANT_SETTINGS: dict[str, str] = {\n \"assistant_planner_provider\": \"\",\n \"assistant_planner_model\": \"\",\n}\n# #endregion DEFAULT_LLM_ASSISTANT_SETTINGS\n\n\n# #region normalize_llm_settings [C:3] [TYPE Function]\n# @BRIEF Ensure llm settings contain stable schema with prompts section and default templates.\n# @PRE: llm_settings is dictionary-like value or None.\n# @POST: Returned dict contains prompts with all required template keys.\n# @RELATION DEPENDS_ON -> LLMProviderService\ndef normalize_llm_settings(llm_settings: Any) -> dict[str, Any]:\n normalized: dict[str, Any] = {\n \"providers\": [],\n \"default_provider\": \"\",\n \"prompts\": {},\n \"provider_bindings\": {},\n **DEFAULT_LLM_ASSISTANT_SETTINGS,\n }\n if isinstance(llm_settings, dict):\n normalized.update(\n {\n k: v\n for k, v in llm_settings.items()\n if k\n in (\n \"providers\",\n \"default_provider\",\n \"prompts\",\n \"provider_bindings\",\n \"assistant_planner_provider\",\n \"assistant_planner_model\",\n )\n }\n )\n prompts = normalized.get(\"prompts\") if isinstance(normalized.get(\"prompts\"), dict) else {}\n merged_prompts = deepcopy(DEFAULT_LLM_PROMPTS)\n merged_prompts.update({k: v for k, v in prompts.items() if isinstance(v, str) and v.strip()})\n normalized[\"prompts\"] = merged_prompts\n bindings = normalized.get(\"provider_bindings\") if isinstance(normalized.get(\"provider_bindings\"), dict) else {}\n merged_bindings = deepcopy(DEFAULT_LLM_PROVIDER_BINDINGS)\n merged_bindings.update({k: v for k, v in bindings.items() if isinstance(v, str)})\n normalized[\"provider_bindings\"] = merged_bindings\n for key, default_value in DEFAULT_LLM_ASSISTANT_SETTINGS.items():\n value = normalized.get(key, default_value)\n normalized[key] = value.strip() if isinstance(value, str) else default_value\n return normalized\n# #endregion normalize_llm_settings\n\n\n# #region is_multimodal_model [C:3] [TYPE Function]\n# @BRIEF Heuristically determine whether model supports image input required for dashboard validation.\n# @PRE: model_name may be empty or mixed-case.\n# @POST: Returns True when model likely supports multimodal input.\n# @RELATION DEPENDS_ON -> LLMProviderService\ndef is_multimodal_model(model_name: str, provider_type: str | None = None) -> bool:\n token = (model_name or \"\").strip().lower()\n if not token:\n return False\n provider = (provider_type or \"\").strip().lower()\n text_only_markers = (\n \"text-only\",\n \"embedding\",\n \"rerank\",\n \"whisper\",\n \"tts\",\n \"transcribe\",\n )\n if any(marker in token for marker in text_only_markers):\n return False\n multimodal_markers = (\n \"gpt-4o\",\n \"gpt-4.1\",\n \"vision\",\n \"vl\",\n \"gemini\",\n \"claude-3\",\n \"claude-sonnet-4\",\n \"omni\",\n \"multimodal\",\n \"pixtral\",\n \"llava\",\n \"internvl\",\n \"qwen-vl\",\n \"qwen2-vl\",\n )\n if any(marker in token for marker in multimodal_markers):\n return True\n return False\n# #endregion is_multimodal_model\n\n\n# #region resolve_bound_provider_id [C:3] [TYPE Function]\n# @BRIEF Resolve provider id configured for a task binding with fallback to default provider.\n# @PRE: llm_settings is normalized or raw dict from config.\n# @POST: Returns configured provider id or fallback id/empty string when not defined.\n# @RELATION DEPENDS_ON -> LLMProviderService\ndef resolve_bound_provider_id(llm_settings: Any, task_key: str) -> str:\n normalized = normalize_llm_settings(llm_settings)\n bindings = normalized.get(\"provider_bindings\", {})\n bound = bindings.get(task_key)\n if isinstance(bound, str) and bound.strip():\n return bound.strip()\n default_provider = normalized.get(\"default_provider\", \"\")\n return default_provider.strip() if isinstance(default_provider, str) else \"\"\n# #endregion resolve_bound_provider_id\n\n\n# #region render_prompt [C:3] [TYPE Function]\n# @BRIEF Render prompt template using deterministic placeholder replacement with graceful fallback.\n# @PRE: template is a string and variables values are already stringifiable.\n# @POST: Returns rendered prompt text with known placeholders substituted.\n# @RELATION DEPENDS_ON -> LLMProviderService\ndef render_prompt(template: str, variables: dict[str, Any]) -> str:\n rendered = template\n for key, value in variables.items():\n rendered = rendered.replace(\"{\" + key + \"}\", str(value))\n return rendered\n# #endregion render_prompt\n\n\n# #endregion llm_prompt_templates\n" + "body": "# #region llm_prompt_templates [C:2] [TYPE Module] [SEMANTICS llm, prompt, template, normalization]\n# @BRIEF Provide default LLM prompt templates and normalization helpers for runtime usage.\n# @LAYER: Domain\n# @RELATION DEPENDS_ON -> [backend.src.core.config_manager:Function]\n# @INVARIANT: All required prompt template keys are always present after normalization.\n\nfrom __future__ import annotations\n\nfrom copy import deepcopy\nfrom typing import Any\n\nfrom ..core.logger import logger\n\n# #region DEFAULT_LLM_PROMPTS [C:2] [TYPE Constant]\n# @BRIEF Default prompt templates used by documentation, dashboard validation, and git commit generation.\nDEFAULT_LLM_PROMPTS: dict[str, str] = {\n \"dashboard_validation_prompt\": (\n \"Analyze the attached dashboard screenshot and the following execution logs for health and visual issues.\\n\\n\"\n \"Logs:\\n\"\n \"{logs}\\n\\n\"\n \"Provide the analysis in JSON format with the following structure:\\n\"\n \"{\\n\"\n ' \"status\": \"PASS\" | \"WARN\" | \"FAIL\",\\n'\n ' \"summary\": \"Short summary of findings\",\\n'\n ' \"issues\": [\\n'\n \" {\\n\"\n ' \"severity\": \"WARN\" | \"FAIL\",\\n'\n ' \"message\": \"Description of the issue\",\\n'\n ' \"location\": \"Optional location info (e.g. chart name)\"\\n'\n \" }\\n\"\n \" ]\\n\"\n \"}\"\n ),\n \"documentation_prompt\": (\n \"Generate professional documentation for the following dataset and its columns.\\n\"\n \"Dataset: {dataset_name}\\n\"\n \"Columns: {columns_json}\\n\\n\"\n \"Provide the documentation in JSON format:\\n\"\n \"{\\n\"\n ' \"dataset_description\": \"General description of the dataset\",\\n'\n ' \"column_descriptions\": [\\n'\n \" {\\n\"\n ' \"name\": \"column_name\",\\n'\n ' \"description\": \"Generated description\"\\n'\n \" }\\n\"\n \" ]\\n\"\n \"}\"\n ),\n \"git_commit_prompt\": (\n \"Generate a concise and professional git commit message based on the following diff and recent history.\\n\"\n \"Use Conventional Commits format (e.g., feat: ..., fix: ..., docs: ...).\\n\\n\"\n \"Recent History:\\n\"\n \"{history}\\n\\n\"\n \"Diff:\\n\"\n \"{diff}\\n\\n\"\n \"Commit Message:\"\n ),\n}\n# #endregion DEFAULT_LLM_PROMPTS\n\n\n# #region DEFAULT_LLM_PROVIDER_BINDINGS [C:2] [TYPE Constant]\n# @BRIEF Default provider binding per task domain.\nDEFAULT_LLM_PROVIDER_BINDINGS: dict[str, str] = {\n \"dashboard_validation\": \"\",\n \"documentation\": \"\",\n \"git_commit\": \"\",\n}\n# #endregion DEFAULT_LLM_PROVIDER_BINDINGS\n\n\n# #region DEFAULT_LLM_ASSISTANT_SETTINGS [C:2] [TYPE Constant]\n# @BRIEF Default planner settings for assistant chat intent model/provider resolution.\nDEFAULT_LLM_ASSISTANT_SETTINGS: dict[str, str] = {\n \"assistant_planner_provider\": \"\",\n \"assistant_planner_model\": \"\",\n}\n# #endregion DEFAULT_LLM_ASSISTANT_SETTINGS\n\n\n# #region normalize_llm_settings [C:3] [TYPE Function]\n# @BRIEF Ensure llm settings contain stable schema with prompts section and default templates.\n# @PRE: llm_settings is dictionary-like value or None.\n# @POST: Returned dict contains prompts with all required template keys.\n# @RELATION DEPENDS_ON -> LLMProviderService\ndef normalize_llm_settings(llm_settings: Any) -> dict[str, Any]:\n normalized: dict[str, Any] = {\n \"providers\": [],\n \"default_provider\": \"\",\n \"prompts\": {},\n \"provider_bindings\": {},\n **DEFAULT_LLM_ASSISTANT_SETTINGS,\n }\n if isinstance(llm_settings, dict):\n normalized.update(\n {\n k: v\n for k, v in llm_settings.items()\n if k\n in (\n \"providers\",\n \"default_provider\",\n \"prompts\",\n \"provider_bindings\",\n \"assistant_planner_provider\",\n \"assistant_planner_model\",\n )\n }\n )\n prompts = normalized.get(\"prompts\") if isinstance(normalized.get(\"prompts\"), dict) else {}\n merged_prompts = deepcopy(DEFAULT_LLM_PROMPTS)\n merged_prompts.update({k: v for k, v in prompts.items() if isinstance(v, str) and v.strip()})\n normalized[\"prompts\"] = merged_prompts\n bindings = normalized.get(\"provider_bindings\") if isinstance(normalized.get(\"provider_bindings\"), dict) else {}\n merged_bindings = deepcopy(DEFAULT_LLM_PROVIDER_BINDINGS)\n merged_bindings.update({k: v for k, v in bindings.items() if isinstance(v, str)})\n normalized[\"provider_bindings\"] = merged_bindings\n for key, default_value in DEFAULT_LLM_ASSISTANT_SETTINGS.items():\n value = normalized.get(key, default_value)\n normalized[key] = value.strip() if isinstance(value, str) else default_value\n return normalized\n# #endregion normalize_llm_settings\n\n\n# #region is_multimodal_model [C:3] [TYPE Function]\n# @BRIEF Heuristically determine whether model supports image input required for dashboard validation.\n# @PRE: model_name may be empty or mixed-case.\n# @POST: Returns True when model likely supports multimodal input.\n# @RELATION DEPENDS_ON -> LLMProviderService\ndef is_multimodal_model(model_name: str, provider_type: str | None = None) -> bool:\n token = (model_name or \"\").strip().lower()\n if not token:\n return False\n provider = (provider_type or \"\").strip().lower()\n text_only_markers = (\n \"text-only\",\n \"embedding\",\n \"rerank\",\n \"whisper\",\n \"tts\",\n \"transcribe\",\n )\n if any(marker in token for marker in text_only_markers):\n return False\n multimodal_markers = (\n \"gpt-4o\",\n \"gpt-4.1\",\n \"vision\",\n \"vl\",\n \"gemini\",\n \"claude-3\",\n \"claude-sonnet-4\",\n \"omni\",\n \"multimodal\",\n \"pixtral\",\n \"llava\",\n \"internvl\",\n \"qwen-vl\",\n \"qwen2-vl\",\n )\n if any(marker in token for marker in multimodal_markers):\n return True\n return False\n# #endregion is_multimodal_model\n\n\n# #region resolve_bound_provider_id [C:3] [TYPE Function]\n# @BRIEF Resolve provider id configured for a task binding with fallback to default provider.\n# @PRE: llm_settings is normalized or raw dict from config.\n# @POST: Returns configured provider id or fallback id/empty string when not defined.\n# @RELATION DEPENDS_ON -> LLMProviderService\ndef resolve_bound_provider_id(llm_settings: Any, task_key: str) -> str:\n normalized = normalize_llm_settings(llm_settings)\n bindings = normalized.get(\"provider_bindings\", {})\n bound = bindings.get(task_key)\n if isinstance(bound, str) and bound.strip():\n return bound.strip()\n default_provider = normalized.get(\"default_provider\", \"\")\n return default_provider.strip() if isinstance(default_provider, str) else \"\"\n# #endregion resolve_bound_provider_id\n\n\n# #region render_prompt [C:3] [TYPE Function]\n# @BRIEF Render prompt template using deterministic placeholder replacement with graceful fallback.\n# @PRE: template is a string and variables values are already stringifiable.\n# @POST: Returns rendered prompt text with known placeholders substituted. Warns about unfilled placeholders.\n# @RELATION DEPENDS_ON -> LLMProviderService\ndef render_prompt(template: str, variables: dict[str, Any]) -> str:\n rendered = template\n for key, value in variables.items():\n rendered = rendered.replace(\"{\" + key + \"}\", str(value))\n\n # Warn about unfilled placeholders that would be sent to LLM\n import re\n unfilled = re.findall(r'\\{(\\w+)\\}', rendered)\n if unfilled:\n logger.warning(\n f\"[render_prompt] Unfilled placeholders in rendered prompt: {unfilled}\"\n )\n\n return rendered\n# #endregion render_prompt\n\n\n# #endregion llm_prompt_templates\n" }, { "contract_id": "DEFAULT_LLM_PROMPTS", "contract_type": "Constant", "file_path": "backend/src/services/llm_prompt_templates.py", - "start_line": 12, - "end_line": 57, + "start_line": 14, + "end_line": 59, "tier": "TIER_1", "complexity": 2, "metadata": { @@ -59866,8 +59142,8 @@ "contract_id": "DEFAULT_LLM_PROVIDER_BINDINGS", "contract_type": "Constant", "file_path": "backend/src/services/llm_prompt_templates.py", - "start_line": 60, - "end_line": 67, + "start_line": 62, + "end_line": 69, "tier": "TIER_1", "complexity": 2, "metadata": { @@ -59938,8 +59214,8 @@ "contract_id": "DEFAULT_LLM_ASSISTANT_SETTINGS", "contract_type": "Constant", "file_path": "backend/src/services/llm_prompt_templates.py", - "start_line": 70, - "end_line": 76, + "start_line": 72, + "end_line": 78, "tier": "TIER_1", "complexity": 2, "metadata": { @@ -60010,8 +59286,8 @@ "contract_id": "normalize_llm_settings", "contract_type": "Function", "file_path": "backend/src/services/llm_prompt_templates.py", - "start_line": 79, - "end_line": 120, + "start_line": 81, + "end_line": 122, "tier": "TIER_2", "complexity": 3, "metadata": { @@ -60056,8 +59332,8 @@ "contract_id": "is_multimodal_model", "contract_type": "Function", "file_path": "backend/src/services/llm_prompt_templates.py", - "start_line": 123, - "end_line": 162, + "start_line": 125, + "end_line": 164, "tier": "TIER_2", "complexity": 3, "metadata": { @@ -60102,8 +59378,8 @@ "contract_id": "resolve_bound_provider_id", "contract_type": "Function", "file_path": "backend/src/services/llm_prompt_templates.py", - "start_line": 165, - "end_line": 178, + "start_line": 167, + "end_line": 180, "tier": "TIER_2", "complexity": 3, "metadata": { @@ -60148,13 +59424,13 @@ "contract_id": "render_prompt", "contract_type": "Function", "file_path": "backend/src/services/llm_prompt_templates.py", - "start_line": 181, - "end_line": 191, + "start_line": 183, + "end_line": 202, "tier": "TIER_2", "complexity": 3, "metadata": { "COMPLEXITY": 3, - "POST": "Returns rendered prompt text with known placeholders substituted.", + "POST": "Returns rendered prompt text with known placeholders substituted. Warns about unfilled placeholders.", "PRE": "template is a string and variables values are already stringifiable.", "PURPOSE": "Render prompt template using deterministic placeholder replacement with graceful fallback." }, @@ -60188,14 +59464,14 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region render_prompt [C:3] [TYPE Function]\n# @BRIEF Render prompt template using deterministic placeholder replacement with graceful fallback.\n# @PRE: template is a string and variables values are already stringifiable.\n# @POST: Returns rendered prompt text with known placeholders substituted.\n# @RELATION DEPENDS_ON -> LLMProviderService\ndef render_prompt(template: str, variables: dict[str, Any]) -> str:\n rendered = template\n for key, value in variables.items():\n rendered = rendered.replace(\"{\" + key + \"}\", str(value))\n return rendered\n# #endregion render_prompt\n" + "body": "# #region render_prompt [C:3] [TYPE Function]\n# @BRIEF Render prompt template using deterministic placeholder replacement with graceful fallback.\n# @PRE: template is a string and variables values are already stringifiable.\n# @POST: Returns rendered prompt text with known placeholders substituted. Warns about unfilled placeholders.\n# @RELATION DEPENDS_ON -> LLMProviderService\ndef render_prompt(template: str, variables: dict[str, Any]) -> str:\n rendered = template\n for key, value in variables.items():\n rendered = rendered.replace(\"{\" + key + \"}\", str(value))\n\n # Warn about unfilled placeholders that would be sent to LLM\n import re\n unfilled = re.findall(r'\\{(\\w+)\\}', rendered)\n if unfilled:\n logger.warning(\n f\"[render_prompt] Unfilled placeholders in rendered prompt: {unfilled}\"\n )\n\n return rendered\n# #endregion render_prompt\n" }, { "contract_id": "llm_provider", "contract_type": "Module", "file_path": "backend/src/services/llm_provider.py", "start_line": 1, - "end_line": 261, + "end_line": 304, "tier": "TIER_2", "complexity": 3, "metadata": { @@ -60226,14 +59502,92 @@ "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region llm_provider [C:3] [TYPE Module] [SEMANTICS sqlalchemy, llm, provider, encryption, config]\n# @BRIEF Service for managing LLM provider configurations with encrypted API keys.\n# @LAYER: Domain\n# @RELATION DEPENDS_ON -> [LLMProvider]\n# @RELATION DEPENDS_ON -> [EncryptionManager]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\nimport os\nfrom typing import TYPE_CHECKING\n\nfrom cryptography.fernet import Fernet\nfrom sqlalchemy.orm import Session\n\nfrom ..core.logger import belief_scope, logger\nfrom ..models.llm import LLMProvider\n\nif TYPE_CHECKING:\n from ..plugins.llm_analysis.models import LLMProviderConfig\n\nMASKED_API_KEY_PLACEHOLDER = \"********\"\n\n\n# #region _require_fernet_key [C:5] [TYPE Function]\n# @BRIEF Load and validate the Fernet key used for secret encryption.\n# @PRE: ENCRYPTION_KEY environment variable must be set to a valid Fernet key.\n# @POST: Returns validated key bytes ready for Fernet initialization.\n# @RELATION DEPENDS_ON -> [backend.src.core.logger:Function]\n# @SIDE_EFFECT: Emits belief-state logs for missing or invalid encryption configuration.\n# @DATA_CONTRACT: Input[ENCRYPTION_KEY:str] -> Output[bytes]\n# @INVARIANT: Encryption initialization never falls back to a hardcoded secret.\ndef _require_fernet_key() -> bytes:\n with belief_scope(\"_require_fernet_key\"):\n raw_key = os.getenv(\"ENCRYPTION_KEY\", \"\").strip()\n if not raw_key:\n logger.explore(\n \"Missing ENCRYPTION_KEY blocks EncryptionManager initialization\"\n )\n raise RuntimeError(\"ENCRYPTION_KEY must be set\")\n\n key = raw_key.encode()\n try:\n Fernet(key)\n except Exception as exc:\n logger.explore(\n \"Invalid ENCRYPTION_KEY blocks EncryptionManager initialization\"\n )\n raise RuntimeError(\"ENCRYPTION_KEY must be a valid Fernet key\") from exc\n\n logger.reflect(\"Validated ENCRYPTION_KEY for EncryptionManager initialization\")\n return key\n\n\n# #endregion _require_fernet_key\n\n\n# #region EncryptionManager [C:5] [TYPE Class]\n# @BRIEF Handles encryption and decryption of sensitive data like API keys.\n# @RELATION CALLS -> [_require_fernet_key]\n# @PRE: ENCRYPTION_KEY is configured with a valid Fernet key before instantiation.\n# @POST: Manager exposes reversible encrypt/decrypt operations for persisted secrets.\n# @SIDE_EFFECT: Initializes Fernet cryptography state from process environment.\n# @DATA_CONTRACT: Input[str] -> Output[str]\n# @INVARIANT: Uses only a validated secret key from environment.\n#\n# @TEST_CONTRACT: EncryptionManagerModel ->\n# {\n# required_fields: {},\n# invariants: [\n# \"encrypted data can be decrypted back to the original string\"\n# ]\n# }\n# @TEST_FIXTURE: basic_encryption_cycle -> {\"data\": \"my_secret_key\"}\n# @TEST_EDGE: decrypt_invalid_data -> raises Exception\n# @TEST_EDGE: empty_string_encryption -> {\"data\": \"\"}\n# @TEST_INVARIANT: symmetric_encryption -> verifies: [basic_encryption_cycle, empty_string_encryption]\nclass EncryptionManager:\n # region EncryptionManager_init [TYPE Function]\n # @PURPOSE: Initialize the encryption manager with a Fernet key.\n # @PRE: ENCRYPTION_KEY env var must be set to a valid Fernet key.\n # @POST: Fernet instance ready for encryption/decryption.\n def __init__(self):\n self.key = _require_fernet_key()\n self.fernet = Fernet(self.key)\n\n # endregion EncryptionManager_init\n\n # region encrypt [TYPE Function]\n # @PURPOSE: Encrypt a plaintext string.\n # @PRE: data must be a non-empty string.\n # @POST: Returns encrypted string.\n def encrypt(self, data: str) -> str:\n with belief_scope(\"encrypt\"):\n return self.fernet.encrypt(data.encode()).decode()\n\n # endregion encrypt\n\n # region decrypt [TYPE Function]\n # @PURPOSE: Decrypt an encrypted string.\n # @PRE: encrypted_data must be a valid Fernet-encrypted string.\n # @POST: Returns original plaintext string.\n def decrypt(self, encrypted_data: str) -> str:\n with belief_scope(\"decrypt\"):\n return self.fernet.decrypt(encrypted_data.encode()).decode()\n\n # endregion decrypt\n\n\n# #endregion EncryptionManager\n\n\n# #region LLMProviderService [C:3] [TYPE Class]\n# @BRIEF Service to manage LLM provider lifecycle.\n# @RELATION DEPENDS_ON -> [LLMProvider]\n# @RELATION DEPENDS_ON -> [EncryptionManager]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\nclass LLMProviderService:\n # region LLMProviderService_init [TYPE Function]\n # @PURPOSE: Initialize the service with database session.\n # @PRE: db must be a valid SQLAlchemy Session.\n # @POST: Service ready for provider operations.\n # @RELATION: [DEPENDS_ON] ->[EncryptionManager]\n def __init__(self, db: Session):\n self.db = db\n self.encryption = EncryptionManager()\n\n # endregion LLMProviderService_init\n\n # region get_all_providers [TYPE Function]\n # @PURPOSE: Returns all configured LLM providers.\n # @PRE: Database connection must be active.\n # @POST: Returns list of all LLMProvider records.\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n def get_all_providers(self) -> list[LLMProvider]:\n with belief_scope(\"get_all_providers\"):\n return self.db.query(LLMProvider).all()\n\n # endregion get_all_providers\n\n # region get_provider [TYPE Function]\n # @PURPOSE: Returns a single LLM provider by ID.\n # @PRE: provider_id must be a valid string.\n # @POST: Returns LLMProvider or None if not found.\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n def get_provider(self, provider_id: str) -> LLMProvider | None:\n with belief_scope(\"get_provider\"):\n return (\n self.db.query(LLMProvider).filter(LLMProvider.id == provider_id).first()\n )\n\n # endregion get_provider\n\n # region create_provider [TYPE Function]\n # @PURPOSE: Creates a new LLM provider with encrypted API key.\n # @PRE: config must contain valid provider configuration.\n # @POST: New provider created and persisted to database.\n # @RELATION: [DEPENDS_ON] ->[LLMProviderConfig]\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n # @RELATION: [CALLS] ->[encrypt]\n def create_provider(self, config: \"LLMProviderConfig\") -> LLMProvider:\n with belief_scope(\"create_provider\"):\n encrypted_key = self.encryption.encrypt(config.api_key)\n db_provider = LLMProvider(\n provider_type=config.provider_type.value,\n name=config.name,\n base_url=config.base_url,\n api_key=encrypted_key,\n default_model=config.default_model,\n is_active=config.is_active,\n )\n self.db.add(db_provider)\n self.db.commit()\n self.db.refresh(db_provider)\n return db_provider\n\n # endregion create_provider\n\n # region update_provider [TYPE Function]\n # @PURPOSE: Updates an existing LLM provider.\n # @PRE: provider_id must exist, config must be valid.\n # @POST: Provider updated and persisted to database.\n # @RELATION: [DEPENDS_ON] ->[LLMProviderConfig]\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n # @RELATION: [CALLS] ->[encrypt]\n def update_provider(\n self, provider_id: str, config: \"LLMProviderConfig\"\n ) -> LLMProvider | None:\n with belief_scope(\"update_provider\"):\n db_provider = self.get_provider(provider_id)\n if not db_provider:\n return None\n\n db_provider.provider_type = config.provider_type.value\n db_provider.name = config.name\n db_provider.base_url = config.base_url\n # Ignore masked placeholder values; they are display-only and must not overwrite secrets.\n if (\n config.api_key is not None\n and config.api_key != \"\"\n and config.api_key != MASKED_API_KEY_PLACEHOLDER\n ):\n db_provider.api_key = self.encryption.encrypt(config.api_key)\n db_provider.default_model = config.default_model\n db_provider.is_active = config.is_active\n\n self.db.commit()\n self.db.refresh(db_provider)\n return db_provider\n\n # endregion update_provider\n\n # region delete_provider [TYPE Function]\n # @PURPOSE: Deletes an LLM provider.\n # @PRE: provider_id must exist.\n # @POST: Provider removed from database.\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n def delete_provider(self, provider_id: str) -> bool:\n with belief_scope(\"delete_provider\"):\n db_provider = self.get_provider(provider_id)\n if not db_provider:\n return False\n self.db.delete(db_provider)\n self.db.commit()\n return True\n\n # endregion delete_provider\n\n # region get_decrypted_api_key [TYPE Function]\n # @PURPOSE: Returns the decrypted API key for a provider.\n # @PRE: provider_id must exist with valid encrypted key.\n # @POST: Returns decrypted API key or None on failure.\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n # @RELATION: [CALLS] ->[decrypt]\n def get_decrypted_api_key(self, provider_id: str) -> str | None:\n with belief_scope(\"get_decrypted_api_key\"):\n db_provider = self.get_provider(provider_id)\n if not db_provider:\n logger.warning(\n f\"[get_decrypted_api_key] Provider {provider_id} not found in database\"\n )\n return None\n\n logger.info(f\"[get_decrypted_api_key] Provider found: {db_provider.id}\")\n logger.info(\n f\"[get_decrypted_api_key] Encrypted API key length: {len(db_provider.api_key) if db_provider.api_key else 0}\"\n )\n\n try:\n decrypted_key = self.encryption.decrypt(db_provider.api_key)\n logger.info(\n f\"[get_decrypted_api_key] Decryption successful, key length: {len(decrypted_key) if decrypted_key else 0}\"\n )\n return decrypted_key\n except Exception as e:\n logger.error(f\"[get_decrypted_api_key] Decryption failed: {e!s}\")\n return None\n\n # endregion get_decrypted_api_key\n\n\n# #endregion LLMProviderService\n\n# #endregion llm_provider\n" + "body": "# #region llm_provider [C:3] [TYPE Module] [SEMANTICS sqlalchemy, llm, provider, encryption, config]\n# @BRIEF Service for managing LLM provider configurations with encrypted API keys.\n# @LAYER: Domain\n# @RELATION DEPENDS_ON -> [LLMProvider]\n# @RELATION DEPENDS_ON -> [EncryptionManager]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\nimport os\nfrom typing import TYPE_CHECKING\n\nfrom cryptography.fernet import Fernet\nfrom cryptography.exceptions import InvalidTag\nfrom sqlalchemy.orm import Session\n\nfrom ..core.logger import belief_scope, logger\nfrom ..models.llm import LLMProvider\n\nif TYPE_CHECKING:\n from ..plugins.llm_analysis.models import LLMProviderConfig\n\nMASKED_API_KEY_PLACEHOLDER = \"********\"\n\n\n# #region mask_api_key [C:2] [TYPE Function]\n# @BRIEF Mask an API key for safe display, showing first 4 and last 4 characters.\n# @PRE: api_key is a plaintext string or None.\n# @POST: Returns \"****\" for very short keys; \"{first 2}...{last 2}\" for <=8 chars;\n# \"{first 4}...{last 4}\" for longer keys; \"\" for None/empty.\ndef mask_api_key(api_key: str | None) -> str:\n if not api_key:\n return \"\"\n if len(api_key) <= 4:\n return \"****\"\n if len(api_key) <= 8:\n return f\"{api_key[:2]}...{api_key[-2:]}\"\n return f\"{api_key[:4]}...{api_key[-4:]}\"\n\n\n# #endregion mask_api_key\n\n\n# #region is_masked_or_placeholder [C:2] [TYPE Function]\n# @BRIEF Predicate: True when api_key is None, empty, \"********\", or contains \"...\".\n# @PRE: api_key can be None.\n# @POST: Returns True only for non-real-key values.\ndef is_masked_or_placeholder(api_key: str | None) -> bool:\n if not api_key:\n return True\n return api_key == MASKED_API_KEY_PLACEHOLDER or \"...\" in api_key\n\n\n# #endregion is_masked_or_placeholder\n\n\n# #region _require_fernet_key [C:5] [TYPE Function]\n# @BRIEF Load and validate the Fernet key used for secret encryption.\n# @PRE: ENCRYPTION_KEY environment variable must be set to a valid Fernet key.\n# @POST: Returns validated key bytes ready for Fernet initialization.\n# @RELATION DEPENDS_ON -> [backend.src.core.logger:Function]\n# @SIDE_EFFECT: Emits belief-state logs for missing or invalid encryption configuration.\n# @DATA_CONTRACT: Input[ENCRYPTION_KEY:str] -> Output[bytes]\n# @INVARIANT: Encryption initialization never falls back to a hardcoded secret.\ndef _require_fernet_key() -> bytes:\n with belief_scope(\"_require_fernet_key\"):\n raw_key = os.getenv(\"ENCRYPTION_KEY\", \"\").strip()\n if not raw_key:\n logger.explore(\n \"Missing ENCRYPTION_KEY blocks EncryptionManager initialization\"\n )\n raise RuntimeError(\"ENCRYPTION_KEY must be set\")\n\n key = raw_key.encode()\n try:\n Fernet(key)\n except Exception as exc:\n logger.explore(\n \"Invalid ENCRYPTION_KEY blocks EncryptionManager initialization\"\n )\n raise RuntimeError(\"ENCRYPTION_KEY must be a valid Fernet key\") from exc\n\n logger.reflect(\"Validated ENCRYPTION_KEY for EncryptionManager initialization\")\n return key\n\n\n# #endregion _require_fernet_key\n\n\n# #region EncryptionManager [C:5] [TYPE Class]\n# @BRIEF Handles encryption and decryption of sensitive data like API keys.\n# @RELATION CALLS -> [_require_fernet_key]\n# @PRE: ENCRYPTION_KEY is configured with a valid Fernet key before instantiation.\n# @POST: Manager exposes reversible encrypt/decrypt operations for persisted secrets.\n# @SIDE_EFFECT: Initializes Fernet cryptography state from process environment.\n# @DATA_CONTRACT: Input[str] -> Output[str]\n# @INVARIANT: Uses only a validated secret key from environment.\n#\n# @TEST_CONTRACT: EncryptionManagerModel ->\n# {\n# required_fields: {},\n# invariants: [\n# \"encrypted data can be decrypted back to the original string\"\n# ]\n# }\n# @TEST_FIXTURE: basic_encryption_cycle -> {\"data\": \"my_secret_key\"}\n# @TEST_EDGE: decrypt_invalid_data -> raises Exception\n# @TEST_EDGE: empty_string_encryption -> {\"data\": \"\"}\n# @TEST_INVARIANT: symmetric_encryption -> verifies: [basic_encryption_cycle, empty_string_encryption]\nclass EncryptionManager:\n # region EncryptionManager_init [TYPE Function]\n # @PURPOSE: Initialize the encryption manager with a Fernet key.\n # @PRE: ENCRYPTION_KEY env var must be set to a valid Fernet key.\n # @POST: Fernet instance ready for encryption/decryption.\n def __init__(self):\n self.key = _require_fernet_key()\n self.fernet = Fernet(self.key)\n\n # endregion EncryptionManager_init\n\n # region encrypt [TYPE Function]\n # @PURPOSE: Encrypt a plaintext string.\n # @PRE: data must be a non-empty string.\n # @POST: Returns encrypted string.\n def encrypt(self, data: str) -> str:\n with belief_scope(\"encrypt\"):\n return self.fernet.encrypt(data.encode()).decode()\n\n # endregion encrypt\n\n # region decrypt [TYPE Function]\n # @PURPOSE: Decrypt an encrypted string.\n # @PRE: encrypted_data must be a valid Fernet-encrypted string.\n # @POST: Returns original plaintext string.\n def decrypt(self, encrypted_data: str) -> str:\n with belief_scope(\"decrypt\"):\n return self.fernet.decrypt(encrypted_data.encode()).decode()\n\n # endregion decrypt\n\n\n# #endregion EncryptionManager\n\n\n# #region LLMProviderService [C:3] [TYPE Class]\n# @BRIEF Service to manage LLM provider lifecycle.\n# @RELATION DEPENDS_ON -> [LLMProvider]\n# @RELATION DEPENDS_ON -> [EncryptionManager]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\nclass LLMProviderService:\n # region LLMProviderService_init [TYPE Function]\n # @PURPOSE: Initialize the service with database session.\n # @PRE: db must be a valid SQLAlchemy Session.\n # @POST: Service ready for provider operations.\n # @RELATION: [DEPENDS_ON] ->[EncryptionManager]\n def __init__(self, db: Session):\n self.db = db\n self.encryption = EncryptionManager()\n\n # endregion LLMProviderService_init\n\n # region get_all_providers [TYPE Function]\n # @PURPOSE: Returns all configured LLM providers.\n # @PRE: Database connection must be active.\n # @POST: Returns list of all LLMProvider records.\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n def get_all_providers(self) -> list[LLMProvider]:\n with belief_scope(\"get_all_providers\"):\n return self.db.query(LLMProvider).all()\n\n # endregion get_all_providers\n\n # region get_provider [TYPE Function]\n # @PURPOSE: Returns a single LLM provider by ID.\n # @PRE: provider_id must be a valid string.\n # @POST: Returns LLMProvider or None if not found.\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n def get_provider(self, provider_id: str) -> LLMProvider | None:\n with belief_scope(\"get_provider\"):\n return (\n self.db.query(LLMProvider).filter(LLMProvider.id == provider_id).first()\n )\n\n # endregion get_provider\n\n # region create_provider [TYPE Function]\n # @PURPOSE: Creates a new LLM provider with encrypted API key.\n # @PRE: config must contain valid provider configuration.\n # @POST: New provider created and persisted to database.\n # @RELATION: [DEPENDS_ON] ->[LLMProviderConfig]\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n # @RELATION: [CALLS] ->[encrypt]\n def create_provider(self, config: \"LLMProviderConfig\") -> LLMProvider:\n with belief_scope(\"create_provider\"):\n encrypted_key = self.encryption.encrypt(config.api_key)\n db_provider = LLMProvider(\n provider_type=config.provider_type.value,\n name=config.name,\n base_url=config.base_url,\n api_key=encrypted_key,\n default_model=config.default_model,\n is_active=config.is_active,\n )\n self.db.add(db_provider)\n self.db.commit()\n self.db.refresh(db_provider)\n return db_provider\n\n # endregion create_provider\n\n # region update_provider [TYPE Function]\n # @PURPOSE: Updates an existing LLM provider.\n # @PRE: provider_id must exist, config must be valid.\n # @POST: Provider updated and persisted to database.\n # @RELATION: [DEPENDS_ON] ->[LLMProviderConfig]\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n # @RELATION: [CALLS] ->[encrypt]\n def update_provider(\n self, provider_id: str, config: \"LLMProviderConfig\"\n ) -> LLMProvider | None:\n with belief_scope(\"update_provider\"):\n db_provider = self.get_provider(provider_id)\n if not db_provider:\n return None\n\n db_provider.provider_type = config.provider_type.value\n db_provider.name = config.name\n db_provider.base_url = config.base_url\n # Ignore masked/placeholder values; they are display-only and must not overwrite secrets.\n if not is_masked_or_placeholder(config.api_key):\n db_provider.api_key = self.encryption.encrypt(config.api_key)\n db_provider.default_model = config.default_model\n db_provider.is_active = config.is_active\n\n self.db.commit()\n self.db.refresh(db_provider)\n return db_provider\n\n # endregion update_provider\n\n # region delete_provider [TYPE Function]\n # @PURPOSE: Deletes an LLM provider.\n # @PRE: provider_id must exist.\n # @POST: Provider removed from database.\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n def delete_provider(self, provider_id: str) -> bool:\n with belief_scope(\"delete_provider\"):\n db_provider = self.get_provider(provider_id)\n if not db_provider:\n return False\n self.db.delete(db_provider)\n self.db.commit()\n return True\n\n # endregion delete_provider\n\n # region get_decrypted_api_key [TYPE Function]\n # @PURPOSE: Returns the decrypted API key for a provider.\n # @PRE: provider_id must exist with valid encrypted key.\n # @POST: Returns decrypted API key or None on failure.\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n # @RELATION: [CALLS] ->[decrypt]\n def get_decrypted_api_key(self, provider_id: str) -> str | None:\n with belief_scope(\"get_decrypted_api_key\"):\n db_provider = self.get_provider(provider_id)\n if not db_provider:\n logger.warning(\n f\"[get_decrypted_api_key] Provider {provider_id} not found in database\"\n )\n return None\n\n logger.info(f\"[get_decrypted_api_key] Provider found: {db_provider.id}\")\n logger.info(\n f\"[get_decrypted_api_key] Encrypted API key length: {len(db_provider.api_key) if db_provider.api_key else 0}\"\n )\n\n try:\n decrypted_key = self.encryption.decrypt(db_provider.api_key)\n logger.info(\n f\"[get_decrypted_api_key] Decryption successful, key length: {len(decrypted_key) if decrypted_key else 0}\"\n )\n return decrypted_key\n except InvalidTag as e:\n logger.error(\n f\"[get_decrypted_api_key] Integrity check failed (InvalidTag): {e!s}. \"\n \"The encrypted API key may be corrupted or the ENCRYPTION_KEY has changed.\"\n )\n return None\n except ValueError as e:\n logger.error(\n f\"[get_decrypted_api_key] Decryption format error (ValueError): {e!s}. \"\n \"The encrypted data may not be valid Fernet ciphertext.\"\n )\n return None\n except Exception as e:\n logger.error(\n f\"[get_decrypted_api_key] Decryption failed with unexpected error \"\n f\"({type(e).__name__}): {e!s}\"\n )\n return None\n\n # endregion get_decrypted_api_key\n\n\n# #endregion LLMProviderService\n\n# #endregion llm_provider\n" + }, + { + "contract_id": "mask_api_key", + "contract_type": "Function", + "file_path": "backend/src/services/llm_provider.py", + "start_line": 23, + "end_line": 38, + "tier": "TIER_1", + "complexity": 2, + "metadata": { + "COMPLEXITY": 2, + "POST": "Returns \"****\" for very short keys; \"{first 2}...{last 2}\" for <=8 chars;", + "PRE": "api_key is a plaintext string or None.", + "PURPOSE": "Mask an API key for safe display, showing first 4 and last 4 characters." + }, + "relations": [], + "schema_warnings": [ + { + "code": "tag_forbidden_by_complexity", + "tag": "POST", + "message": "@POST is forbidden for contract type 'Function' at C2", + "detail": { + "actual_complexity": 2, + "contract_type": "Function" + } + }, + { + "code": "tag_forbidden_by_complexity", + "tag": "PRE", + "message": "@PRE is forbidden for contract type 'Function' at C2", + "detail": { + "actual_complexity": 2, + "contract_type": "Function" + } + } + ], + "anchor_syntax": "region", + "tier_source": "AutoCalculated", + "body": "# #region mask_api_key [C:2] [TYPE Function]\n# @BRIEF Mask an API key for safe display, showing first 4 and last 4 characters.\n# @PRE: api_key is a plaintext string or None.\n# @POST: Returns \"****\" for very short keys; \"{first 2}...{last 2}\" for <=8 chars;\n# \"{first 4}...{last 4}\" for longer keys; \"\" for None/empty.\ndef mask_api_key(api_key: str | None) -> str:\n if not api_key:\n return \"\"\n if len(api_key) <= 4:\n return \"****\"\n if len(api_key) <= 8:\n return f\"{api_key[:2]}...{api_key[-2:]}\"\n return f\"{api_key[:4]}...{api_key[-4:]}\"\n\n\n# #endregion mask_api_key\n" + }, + { + "contract_id": "is_masked_or_placeholder", + "contract_type": "Function", + "file_path": "backend/src/services/llm_provider.py", + "start_line": 41, + "end_line": 51, + "tier": "TIER_1", + "complexity": 2, + "metadata": { + "COMPLEXITY": 2, + "POST": "Returns True only for non-real-key values.", + "PRE": "api_key can be None.", + "PURPOSE": "Predicate: True when api_key is None, empty, \"********\", or contains \"...\"." + }, + "relations": [], + "schema_warnings": [ + { + "code": "tag_forbidden_by_complexity", + "tag": "POST", + "message": "@POST is forbidden for contract type 'Function' at C2", + "detail": { + "actual_complexity": 2, + "contract_type": "Function" + } + }, + { + "code": "tag_forbidden_by_complexity", + "tag": "PRE", + "message": "@PRE is forbidden for contract type 'Function' at C2", + "detail": { + "actual_complexity": 2, + "contract_type": "Function" + } + } + ], + "anchor_syntax": "region", + "tier_source": "AutoCalculated", + "body": "# #region is_masked_or_placeholder [C:2] [TYPE Function]\n# @BRIEF Predicate: True when api_key is None, empty, \"********\", or contains \"...\".\n# @PRE: api_key can be None.\n# @POST: Returns True only for non-real-key values.\ndef is_masked_or_placeholder(api_key: str | None) -> bool:\n if not api_key:\n return True\n return api_key == MASKED_API_KEY_PLACEHOLDER or \"...\" in api_key\n\n\n# #endregion is_masked_or_placeholder\n" }, { "contract_id": "_require_fernet_key", "contract_type": "Function", "file_path": "backend/src/services/llm_provider.py", - "start_line": 22, - "end_line": 52, + "start_line": 54, + "end_line": 84, "tier": "TIER_3", "complexity": 5, "metadata": { @@ -60262,8 +59616,8 @@ "contract_id": "EncryptionManager", "contract_type": "Class", "file_path": "backend/src/services/llm_provider.py", - "start_line": 55, - "end_line": 107, + "start_line": 87, + "end_line": 139, "tier": "TIER_3", "complexity": 5, "metadata": { @@ -60315,8 +59669,8 @@ "contract_id": "LLMProviderService", "contract_type": "Class", "file_path": "backend/src/services/llm_provider.py", - "start_line": 110, - "end_line": 259, + "start_line": 142, + "end_line": 302, "tier": "TIER_2", "complexity": 3, "metadata": { @@ -60346,7 +59700,7 @@ "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "# #region LLMProviderService [C:3] [TYPE Class]\n# @BRIEF Service to manage LLM provider lifecycle.\n# @RELATION DEPENDS_ON -> [LLMProvider]\n# @RELATION DEPENDS_ON -> [EncryptionManager]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\nclass LLMProviderService:\n # region LLMProviderService_init [TYPE Function]\n # @PURPOSE: Initialize the service with database session.\n # @PRE: db must be a valid SQLAlchemy Session.\n # @POST: Service ready for provider operations.\n # @RELATION: [DEPENDS_ON] ->[EncryptionManager]\n def __init__(self, db: Session):\n self.db = db\n self.encryption = EncryptionManager()\n\n # endregion LLMProviderService_init\n\n # region get_all_providers [TYPE Function]\n # @PURPOSE: Returns all configured LLM providers.\n # @PRE: Database connection must be active.\n # @POST: Returns list of all LLMProvider records.\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n def get_all_providers(self) -> list[LLMProvider]:\n with belief_scope(\"get_all_providers\"):\n return self.db.query(LLMProvider).all()\n\n # endregion get_all_providers\n\n # region get_provider [TYPE Function]\n # @PURPOSE: Returns a single LLM provider by ID.\n # @PRE: provider_id must be a valid string.\n # @POST: Returns LLMProvider or None if not found.\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n def get_provider(self, provider_id: str) -> LLMProvider | None:\n with belief_scope(\"get_provider\"):\n return (\n self.db.query(LLMProvider).filter(LLMProvider.id == provider_id).first()\n )\n\n # endregion get_provider\n\n # region create_provider [TYPE Function]\n # @PURPOSE: Creates a new LLM provider with encrypted API key.\n # @PRE: config must contain valid provider configuration.\n # @POST: New provider created and persisted to database.\n # @RELATION: [DEPENDS_ON] ->[LLMProviderConfig]\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n # @RELATION: [CALLS] ->[encrypt]\n def create_provider(self, config: \"LLMProviderConfig\") -> LLMProvider:\n with belief_scope(\"create_provider\"):\n encrypted_key = self.encryption.encrypt(config.api_key)\n db_provider = LLMProvider(\n provider_type=config.provider_type.value,\n name=config.name,\n base_url=config.base_url,\n api_key=encrypted_key,\n default_model=config.default_model,\n is_active=config.is_active,\n )\n self.db.add(db_provider)\n self.db.commit()\n self.db.refresh(db_provider)\n return db_provider\n\n # endregion create_provider\n\n # region update_provider [TYPE Function]\n # @PURPOSE: Updates an existing LLM provider.\n # @PRE: provider_id must exist, config must be valid.\n # @POST: Provider updated and persisted to database.\n # @RELATION: [DEPENDS_ON] ->[LLMProviderConfig]\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n # @RELATION: [CALLS] ->[encrypt]\n def update_provider(\n self, provider_id: str, config: \"LLMProviderConfig\"\n ) -> LLMProvider | None:\n with belief_scope(\"update_provider\"):\n db_provider = self.get_provider(provider_id)\n if not db_provider:\n return None\n\n db_provider.provider_type = config.provider_type.value\n db_provider.name = config.name\n db_provider.base_url = config.base_url\n # Ignore masked placeholder values; they are display-only and must not overwrite secrets.\n if (\n config.api_key is not None\n and config.api_key != \"\"\n and config.api_key != MASKED_API_KEY_PLACEHOLDER\n ):\n db_provider.api_key = self.encryption.encrypt(config.api_key)\n db_provider.default_model = config.default_model\n db_provider.is_active = config.is_active\n\n self.db.commit()\n self.db.refresh(db_provider)\n return db_provider\n\n # endregion update_provider\n\n # region delete_provider [TYPE Function]\n # @PURPOSE: Deletes an LLM provider.\n # @PRE: provider_id must exist.\n # @POST: Provider removed from database.\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n def delete_provider(self, provider_id: str) -> bool:\n with belief_scope(\"delete_provider\"):\n db_provider = self.get_provider(provider_id)\n if not db_provider:\n return False\n self.db.delete(db_provider)\n self.db.commit()\n return True\n\n # endregion delete_provider\n\n # region get_decrypted_api_key [TYPE Function]\n # @PURPOSE: Returns the decrypted API key for a provider.\n # @PRE: provider_id must exist with valid encrypted key.\n # @POST: Returns decrypted API key or None on failure.\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n # @RELATION: [CALLS] ->[decrypt]\n def get_decrypted_api_key(self, provider_id: str) -> str | None:\n with belief_scope(\"get_decrypted_api_key\"):\n db_provider = self.get_provider(provider_id)\n if not db_provider:\n logger.warning(\n f\"[get_decrypted_api_key] Provider {provider_id} not found in database\"\n )\n return None\n\n logger.info(f\"[get_decrypted_api_key] Provider found: {db_provider.id}\")\n logger.info(\n f\"[get_decrypted_api_key] Encrypted API key length: {len(db_provider.api_key) if db_provider.api_key else 0}\"\n )\n\n try:\n decrypted_key = self.encryption.decrypt(db_provider.api_key)\n logger.info(\n f\"[get_decrypted_api_key] Decryption successful, key length: {len(decrypted_key) if decrypted_key else 0}\"\n )\n return decrypted_key\n except Exception as e:\n logger.error(f\"[get_decrypted_api_key] Decryption failed: {e!s}\")\n return None\n\n # endregion get_decrypted_api_key\n\n\n# #endregion LLMProviderService\n" + "body": "# #region LLMProviderService [C:3] [TYPE Class]\n# @BRIEF Service to manage LLM provider lifecycle.\n# @RELATION DEPENDS_ON -> [LLMProvider]\n# @RELATION DEPENDS_ON -> [EncryptionManager]\n# @RELATION DEPENDS_ON -> [LLMProviderConfig]\nclass LLMProviderService:\n # region LLMProviderService_init [TYPE Function]\n # @PURPOSE: Initialize the service with database session.\n # @PRE: db must be a valid SQLAlchemy Session.\n # @POST: Service ready for provider operations.\n # @RELATION: [DEPENDS_ON] ->[EncryptionManager]\n def __init__(self, db: Session):\n self.db = db\n self.encryption = EncryptionManager()\n\n # endregion LLMProviderService_init\n\n # region get_all_providers [TYPE Function]\n # @PURPOSE: Returns all configured LLM providers.\n # @PRE: Database connection must be active.\n # @POST: Returns list of all LLMProvider records.\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n def get_all_providers(self) -> list[LLMProvider]:\n with belief_scope(\"get_all_providers\"):\n return self.db.query(LLMProvider).all()\n\n # endregion get_all_providers\n\n # region get_provider [TYPE Function]\n # @PURPOSE: Returns a single LLM provider by ID.\n # @PRE: provider_id must be a valid string.\n # @POST: Returns LLMProvider or None if not found.\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n def get_provider(self, provider_id: str) -> LLMProvider | None:\n with belief_scope(\"get_provider\"):\n return (\n self.db.query(LLMProvider).filter(LLMProvider.id == provider_id).first()\n )\n\n # endregion get_provider\n\n # region create_provider [TYPE Function]\n # @PURPOSE: Creates a new LLM provider with encrypted API key.\n # @PRE: config must contain valid provider configuration.\n # @POST: New provider created and persisted to database.\n # @RELATION: [DEPENDS_ON] ->[LLMProviderConfig]\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n # @RELATION: [CALLS] ->[encrypt]\n def create_provider(self, config: \"LLMProviderConfig\") -> LLMProvider:\n with belief_scope(\"create_provider\"):\n encrypted_key = self.encryption.encrypt(config.api_key)\n db_provider = LLMProvider(\n provider_type=config.provider_type.value,\n name=config.name,\n base_url=config.base_url,\n api_key=encrypted_key,\n default_model=config.default_model,\n is_active=config.is_active,\n )\n self.db.add(db_provider)\n self.db.commit()\n self.db.refresh(db_provider)\n return db_provider\n\n # endregion create_provider\n\n # region update_provider [TYPE Function]\n # @PURPOSE: Updates an existing LLM provider.\n # @PRE: provider_id must exist, config must be valid.\n # @POST: Provider updated and persisted to database.\n # @RELATION: [DEPENDS_ON] ->[LLMProviderConfig]\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n # @RELATION: [CALLS] ->[encrypt]\n def update_provider(\n self, provider_id: str, config: \"LLMProviderConfig\"\n ) -> LLMProvider | None:\n with belief_scope(\"update_provider\"):\n db_provider = self.get_provider(provider_id)\n if not db_provider:\n return None\n\n db_provider.provider_type = config.provider_type.value\n db_provider.name = config.name\n db_provider.base_url = config.base_url\n # Ignore masked/placeholder values; they are display-only and must not overwrite secrets.\n if not is_masked_or_placeholder(config.api_key):\n db_provider.api_key = self.encryption.encrypt(config.api_key)\n db_provider.default_model = config.default_model\n db_provider.is_active = config.is_active\n\n self.db.commit()\n self.db.refresh(db_provider)\n return db_provider\n\n # endregion update_provider\n\n # region delete_provider [TYPE Function]\n # @PURPOSE: Deletes an LLM provider.\n # @PRE: provider_id must exist.\n # @POST: Provider removed from database.\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n def delete_provider(self, provider_id: str) -> bool:\n with belief_scope(\"delete_provider\"):\n db_provider = self.get_provider(provider_id)\n if not db_provider:\n return False\n self.db.delete(db_provider)\n self.db.commit()\n return True\n\n # endregion delete_provider\n\n # region get_decrypted_api_key [TYPE Function]\n # @PURPOSE: Returns the decrypted API key for a provider.\n # @PRE: provider_id must exist with valid encrypted key.\n # @POST: Returns decrypted API key or None on failure.\n # @RELATION: [DEPENDS_ON] ->[LLMProvider]\n # @RELATION: [CALLS] ->[decrypt]\n def get_decrypted_api_key(self, provider_id: str) -> str | None:\n with belief_scope(\"get_decrypted_api_key\"):\n db_provider = self.get_provider(provider_id)\n if not db_provider:\n logger.warning(\n f\"[get_decrypted_api_key] Provider {provider_id} not found in database\"\n )\n return None\n\n logger.info(f\"[get_decrypted_api_key] Provider found: {db_provider.id}\")\n logger.info(\n f\"[get_decrypted_api_key] Encrypted API key length: {len(db_provider.api_key) if db_provider.api_key else 0}\"\n )\n\n try:\n decrypted_key = self.encryption.decrypt(db_provider.api_key)\n logger.info(\n f\"[get_decrypted_api_key] Decryption successful, key length: {len(decrypted_key) if decrypted_key else 0}\"\n )\n return decrypted_key\n except InvalidTag as e:\n logger.error(\n f\"[get_decrypted_api_key] Integrity check failed (InvalidTag): {e!s}. \"\n \"The encrypted API key may be corrupted or the ENCRYPTION_KEY has changed.\"\n )\n return None\n except ValueError as e:\n logger.error(\n f\"[get_decrypted_api_key] Decryption format error (ValueError): {e!s}. \"\n \"The encrypted data may not be valid Fernet ciphertext.\"\n )\n return None\n except Exception as e:\n logger.error(\n f\"[get_decrypted_api_key] Decryption failed with unexpected error \"\n f\"({type(e).__name__}): {e!s}\"\n )\n return None\n\n # endregion get_decrypted_api_key\n\n\n# #endregion LLMProviderService\n" }, { "contract_id": "mapping_service", @@ -78986,7 +78340,7 @@ "contract_type": "Component", "file_path": "frontend/src/components/llm/ProviderConfig.svelte", "start_line": 1, - "end_line": 536, + "end_line": 588, "tier": "TIER_2", "complexity": 3, "metadata": { @@ -79029,7 +78383,7 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "\n\n\n\n\n\n\n
\n
\n

{$t.llm.providers_title}

\n {\n resetForm();\n showForm = true;\n }}\n >\n {$t.llm.add_provider}\n \n
\n\n {#if showForm}\n \n
\n

\n {editingProvider ? $t.llm.edit_provider : $t.llm.new_provider}\n

\n\n
\n
\n {$t.llm.name}\n \n
\n\n
\n {$t.llm.type}\n \n \n \n \n \n
\n\n
\n {$t.llm.base_url}\n
\n \n \n {isLoadingModels ? \"...\" : \"↻\"}\n \n
\n
\n\n
\n {$t.llm.api_key}\n \n
\n\n
\n {$t.llm.default_model}\n\n {#if isLoadingModels}\n
\n \n {$t.llm.loading_models}\n
\n {:else if modelsLoadError}\n
{modelsLoadError}
\n {/if}\n\n {#if availableModels.length > 0 && !isLoadingModels}\n \n {#each availableModels as model}\n \n {/each}\n \n
\n {($t.llm.models_loaded || \"{count} models loaded\").replace(\"{count}\", availableModels.length)}\n
\n {:else}\n \n {/if}\n
\n\n
\n \n {$t.llm.active}\n
\n
\n\n {#if testStatus.message}\n \n {testStatus.message}\n
\n {/if}\n\n
\n {\n showForm = false;\n }}\n >\n {$t.llm.cancel}\n \n \n {isTesting ? $t.llm.testing : $t.llm.test}\n \n \n {$t.llm.save}\n \n
\n
\n \n {/if}\n\n
\n {#each providers as provider}\n \n
\n
\n {provider.name}\n \n {provider.is_active ? $t.llm.active : \"Inactive\"}\n \n \n {isMultimodalModel(provider.default_model)\n ? ($t.llm?.multimodal )\n : ($t.llm?.text_only )}\n \n
\n
\n {provider.provider_type} • {provider.default_model}\n
\n
\n
\n handleEdit(provider)}\n >\n {$t.common.edit}\n \n handleDelete(provider)}\n disabled={deletingProviderIds.has(provider.id)}\n >\n {#if deletingProviderIds.has(provider.id)}\n ...\n {:else}\n {$t.common.delete}\n {/if}\n \n toggleActive(provider)}\n disabled={togglingProviderIds.has(provider.id) || deletingProviderIds.has(provider.id)}\n >\n {#if togglingProviderIds.has(provider.id)}\n ...\n {:else}\n {provider.is_active ? \"Deactivate\" : \"Activate\"}\n {/if}\n \n
\n
\n {:else}\n \n {$t.llm.no_providers}\n \n {/each}\n \n\n\n\n" + "body": "\n\n\n\n\n\n\n
\n
\n

{$t.llm.providers_title}

\n {\n resetForm();\n showForm = true;\n }}\n >\n {$t.llm.add_provider}\n \n
\n\n {#if showForm}\n \n
\n

\n {editingProvider ? $t.llm.edit_provider : $t.llm.new_provider}\n

\n\n
\n
\n {$t.llm.name}\n \n
\n\n
\n {$t.llm.type}\n updateBaseUrlForType(formData.provider_type)}\n class=\"mt-1 block w-full border rounded-md p-2\"\n >\n \n \n \n \n \n
\n\n
\n {$t.llm.base_url}\n
\n \n \n {isLoadingModels ? \"...\" : \"↻\"}\n \n
\n
\n\n
\n {$t.llm.api_key}\n {#if editingProvider && formData.api_key && isMaskedKey(formData.api_key)}\n
\n \n {formData.api_key}\n \n { formData.api_key = \"\"; }}\n >\n {$t.llm?.change_key || \"Change\"}\n \n
\n

\n {$t.llm?.key_masked_hint || \"Masked for security. Click \\\"Change\\\" to enter a new key.\"}\n

\n {:else}\n \n {/if}\n
\n\n
\n {$t.llm.default_model}\n\n {#if isLoadingModels}\n
\n \n {$t.llm.loading_models}\n
\n {:else if modelsLoadError}\n
{modelsLoadError}
\n {/if}\n\n {#if availableModels.length > 0 && !isLoadingModels}\n \n {#each availableModels as model}\n \n {/each}\n \n
\n {($t.llm.models_loaded || \"{count} models loaded\").replace(\"{count}\", availableModels.length)}\n
\n {:else}\n \n {/if}\n
\n\n
\n \n {$t.llm.active}\n
\n
\n\n {#if testStatus.message}\n \n {testStatus.message}\n
\n {/if}\n\n
\n {\n showForm = false;\n }}\n >\n {$t.llm.cancel}\n \n \n {isTesting ? $t.llm.testing : $t.llm.test}\n \n \n {$t.llm.save}\n \n
\n
\n \n {/if}\n\n
\n {#each providers as provider}\n \n
\n
\n {provider.name}\n \n {provider.is_active ? $t.llm.active : \"Inactive\"}\n \n \n {isMultimodalModel(provider.default_model)\n ? ($t.llm?.multimodal )\n : ($t.llm?.text_only )}\n \n
\n
\n {provider.provider_type} • {provider.default_model}\n
\n
\n
\n handleEdit(provider)}\n >\n {$t.common.edit}\n \n handleDelete(provider)}\n disabled={deletingProviderIds.has(provider.id)}\n >\n {#if deletingProviderIds.has(provider.id)}\n ...\n {:else}\n {$t.common.delete}\n {/if}\n \n toggleActive(provider)}\n disabled={togglingProviderIds.has(provider.id) || deletingProviderIds.has(provider.id)}\n >\n {#if togglingProviderIds.has(provider.id)}\n ...\n {:else}\n {provider.is_active ? \"Deactivate\" : \"Activate\"}\n {/if}\n \n
\n
\n {:else}\n \n {$t.llm.no_providers}\n \n {/each}\n \n\n\n\n" }, { "contract_id": "ValidationReport", @@ -79095,126 +78449,12 @@ "tier_source": "AutoCalculated", "body": "\n\n\n\n\n\n\n\n\n{#if result}\n
\n
\n

{$t.llm?.validation_report_title}

\n \n {result.status}\n \n
\n\n
\n

{$t.reports?.summary}

\n

{result.summary}

\n
\n\n {#if result.issues && result.issues.length > 0}\n
\n

{$t.tasks?.issues}

\n
\n \n \n \n \n \n \n \n \n \n {#each result.issues as issue}\n \n \n \n \n \n {/each}\n \n
{$t.reports?.severity}{$t.reports?.message}{$t.tasks?.location}
\n \n {issue.severity}\n \n {issue.message}{issue.location || $t.common?.not_available}
\n
\n
\n {/if}\n\n {#if result.screenshot_path}\n
\n

{$t.dashboard?.screenshot_strategy}

\n {$t.dashboard?.dashboard_validation}\n
\n {/if}\n
\n{:else}\n
\n

{$t.llm?.no_validation_result}

\n
\n{/if}\n\n\n" }, - { - "contract_id": "ProviderConfigIntegrationTest:Module", - "contract_type": "Function", - "file_path": "frontend/src/components/llm/__tests__/provider_config.integration.test.js", - "start_line": 1, - "end_line": 59, - "tier": "TIER_1", - "complexity": 1, - "metadata": { - "INVARIANT": "Edit action keeps explicit click handler and opens normalized edit form.", - "LAYER": "UI Tests", - "PURPOSE": "Protect edit and delete interaction contracts in LLM provider settings UI.", - "SEMANTICS": [ - "llm", - "provider-config", - "integration-test", - "edit-flow", - "delete-flow" - ] - }, - "relations": [ - { - "source_id": "ProviderConfigIntegrationTest:Module", - "relation_type": "DEPENDS_ON", - "target_id": "ProviderConfig", - "target_ref": "[ProviderConfig]" - } - ], - "schema_warnings": [ - { - "code": "tag_forbidden_by_complexity", - "tag": "INVARIANT", - "message": "@INVARIANT is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_not_for_contract_type", - "tag": "LAYER", - "message": "@LAYER is not allowed for contract type 'Function'", - "detail": { - "actual_type": "Function", - "allowed_types": [ - "Module", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "LAYER", - "message": "@LAYER is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "invalid_enum_value", - "tag": "LAYER", - "message": "@LAYER value 'UI Tests' is not in allowed enum", - "detail": { - "allowed": [ - "Core", - "Domain", - "API", - "UI", - "Service", - "Infrastructure", - "Plugin" - ], - "value": "UI Tests" - } - }, - { - "code": "tag_not_for_contract_type", - "tag": "SEMANTICS", - "message": "@SEMANTICS is not allowed for contract type 'Function'", - "detail": { - "actual_type": "Function", - "allowed_types": [ - "Module", - "Block", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "SEMANTICS", - "message": "@SEMANTICS is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "RELATION", - "message": "@RELATION is forbidden for contract type 'Function' at C1", - "detail": { - "actual_complexity": 1, - "contract_type": "Function" - } - } - ], - "anchor_syntax": "region", - "tier_source": "AutoCalculated", - "body": "// #region ProviderConfigIntegrationTest:Module [TYPE Function]\n// @SEMANTICS: llm, provider-config, integration-test, edit-flow, delete-flow\n// @PURPOSE: Protect edit and delete interaction contracts in LLM provider settings UI.\n// @LAYER: UI Tests\n// @RELATION: DEPENDS_ON -> [ProviderConfig]\n// @INVARIANT: Edit action keeps explicit click handler and opens normalized edit form.\n\nimport { describe, it, expect } from 'vitest';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nconst COMPONENT_PATH = path.resolve(\n process.cwd(),\n 'src/components/llm/ProviderConfig.svelte',\n);\n\n// #region provider_config_edit_contract_tests:Function [TYPE Function]\n// @RELATION: BINDS_TO -> [ProviderConfigIntegrationTest]\n// @PURPOSE: Validate edit and delete handler wiring plus normalized edit form state mapping.\n// @PRE: ProviderConfig component source exists in expected path.\n// @POST: Contract checks ensure edit click cannot degrade into no-op flow.\ndescribe('ProviderConfig edit interaction contract', () => {\n it('keeps explicit edit click handler with guarded button semantics', () => {\n const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');\n\n expect(source).toContain('type=\"button\"');\n expect(source).toContain('onclick={() => handleEdit(provider)}');\n });\n\n it('normalizes provider payload into editable form shape', () => {\n const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');\n\n expect(source).toContain('formData = {');\n expect(source).toContain('name: provider?.name ?? \"\"');\n expect(source).toContain('provider_type: provider?.provider_type ?? \"openai\"');\n expect(source).toContain('default_model: provider?.default_model ?? \"gpt-4o\"');\n expect(source).toContain('showForm = true;');\n });\n\n it('keeps explicit delete flow with confirmation and delete request', () => {\n const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');\n\n expect(source).toContain('async function handleDelete(provider)');\n expect(source).toContain('$t.llm.delete_confirm.replace(\"{name}\", provider.name || provider.id)');\n expect(source).toContain('await requestApi(`/llm/providers/${provider.id}`, \"DELETE\")');\n expect(source).toContain('onclick={() => handleDelete(provider)}');\n });\n\n it('does not forward masked api_key when toggling provider activation', () => {\n const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');\n\n expect(source).toContain('const updatePayload = {');\n expect(source).toContain('provider_type: provider.provider_type');\n expect(source).toContain('default_model: provider.default_model');\n expect(source).not.toContain('await requestApi(`/llm/providers/${provider.id}`, \"PUT\", {\\n ...provider,');\n });\n});\n// #endregion provider_config_edit_contract_tests:Function\n// #endregion ProviderConfigIntegrationTest:Module\n" - }, { "contract_id": "provider_config_edit_contract_tests:Function", "contract_type": "Function", "file_path": "frontend/src/components/llm/__tests__/provider_config.integration.test.js", "start_line": 17, - "end_line": 58, + "end_line": 92, "tier": "TIER_1", "complexity": 1, "metadata": { @@ -79261,7 +78501,7 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "// #region provider_config_edit_contract_tests:Function [TYPE Function]\n// @RELATION: BINDS_TO -> [ProviderConfigIntegrationTest]\n// @PURPOSE: Validate edit and delete handler wiring plus normalized edit form state mapping.\n// @PRE: ProviderConfig component source exists in expected path.\n// @POST: Contract checks ensure edit click cannot degrade into no-op flow.\ndescribe('ProviderConfig edit interaction contract', () => {\n it('keeps explicit edit click handler with guarded button semantics', () => {\n const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');\n\n expect(source).toContain('type=\"button\"');\n expect(source).toContain('onclick={() => handleEdit(provider)}');\n });\n\n it('normalizes provider payload into editable form shape', () => {\n const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');\n\n expect(source).toContain('formData = {');\n expect(source).toContain('name: provider?.name ?? \"\"');\n expect(source).toContain('provider_type: provider?.provider_type ?? \"openai\"');\n expect(source).toContain('default_model: provider?.default_model ?? \"gpt-4o\"');\n expect(source).toContain('showForm = true;');\n });\n\n it('keeps explicit delete flow with confirmation and delete request', () => {\n const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');\n\n expect(source).toContain('async function handleDelete(provider)');\n expect(source).toContain('$t.llm.delete_confirm.replace(\"{name}\", provider.name || provider.id)');\n expect(source).toContain('await requestApi(`/llm/providers/${provider.id}`, \"DELETE\")');\n expect(source).toContain('onclick={() => handleDelete(provider)}');\n });\n\n it('does not forward masked api_key when toggling provider activation', () => {\n const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');\n\n expect(source).toContain('const updatePayload = {');\n expect(source).toContain('provider_type: provider.provider_type');\n expect(source).toContain('default_model: provider.default_model');\n expect(source).not.toContain('await requestApi(`/llm/providers/${provider.id}`, \"PUT\", {\\n ...provider,');\n });\n});\n// #endregion provider_config_edit_contract_tests:Function\n" + "body": "// #region provider_config_edit_contract_tests:Function [TYPE Function]\n// @RELATION: BINDS_TO -> [ProviderConfigIntegrationTest]\n// @PURPOSE: Validate edit and delete handler wiring plus normalized edit form state mapping.\n// @PRE: ProviderConfig component source exists in expected path.\n// @POST: Contract checks ensure edit click cannot degrade into no-op flow.\ndescribe('ProviderConfig edit interaction contract', () => {\n it('keeps explicit edit click handler with guarded button semantics', () => {\n const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');\n\n expect(source).toContain('type=\"button\"');\n expect(source).toContain('onclick={() => handleEdit(provider)}');\n });\n\n it('normalizes provider payload into editable form shape', () => {\n const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');\n\n expect(source).toContain('formData = {');\n expect(source).toContain('name: provider?.name ?? \"\"');\n expect(source).toContain('provider_type: provider?.provider_type ?? \"openai\"');\n expect(source).toContain('default_model: provider?.default_model ?? \"gpt-4o\"');\n expect(source).toContain('showForm = true;');\n });\n\n it('preserves masked api_key from provider in edit form', () => {\n const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');\n\n expect(source).toContain('api_key: provider?.api_key ?? \"\"');\n });\n\n it('includes isMaskedKey helper to detect masked placeholders', () => {\n const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');\n\n expect(source).toContain('function isMaskedKey(key)');\n expect(source).toContain('key === \"********\" || key.includes(\"...\")');\n });\n\n it('excludes masked api_key from fetchModels payload, uses provider_id fallback', () => {\n const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');\n\n expect(source).toContain(\"if (formData.api_key && !isMaskedKey(formData.api_key))\");\n expect(source).toContain('payload.provider_id = editingProvider.id;');\n });\n\n it('keeps explicit delete flow with confirmation and delete request', () => {\n const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');\n\n expect(source).toContain('async function handleDelete(provider)');\n expect(source).toContain('$t.llm.delete_confirm.replace(\"{name}\", provider.name || provider.id)');\n expect(source).toContain('await requestApi(`/llm/providers/${provider.id}`, \"DELETE\")');\n expect(source).toContain('onclick={() => handleDelete(provider)}');\n });\n\n it('excludes masked or empty api_key from submit data when editing', () => {\n const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');\n\n expect(source).toContain(\"if (editingProvider && (!submitData.api_key || isMaskedKey(submitData.api_key)))\");\n expect(source).toContain(\"delete submitData.api_key;\");\n });\n\n it('excludes masked api_key from test payload when testing connection', () => {\n const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');\n\n expect(source).toContain(\"if (isMaskedKey(testData.api_key))\");\n expect(source).toContain(\"delete testData.api_key;\");\n });\n\n it('does not forward api_key (masked or otherwise) when toggling provider activation', () => {\n const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');\n\n expect(source).toContain('const updatePayload = {');\n expect(source).toContain('provider_type: provider.provider_type');\n expect(source).toContain('default_model: provider.default_model');\n expect(source).not.toContain('await requestApi(`/llm/providers/${provider.id}`, \"PUT\", {\\n ...provider,');\n });\n});\n// #endregion provider_config_edit_contract_tests:Function\n" }, { "contract_id": "isDirectory:Function", @@ -88130,74 +87370,46 @@ "contract_type": "Component", "file_path": "frontend/src/lib/components/translate/BulkCorrectionSidebar.svelte", "start_line": 1, - "end_line": 293, + "end_line": 301, "tier": "TIER_2", "complexity": 3, "metadata": { "COMPLEXITY": 3, - "LAYER": "UI", - "PURPOSE": "Sidebar for collecting multiple incorrect terms across different rows," + "PURPOSE": "Sidebar for collecting multiple incorrect terms across different rows,", + "UX_FEEDBACK": "Toast on success/error; count badge on toggle button", + "UX_RECOVERY": "Remove individual items; retry submission", + "UX_STATE": "submitted -> Success feedback" }, - "relations": [], - "schema_warnings": [ + "relations": [ { - "code": "tag_not_for_contract_type", - "tag": "LAYER", - "message": "@LAYER is not allowed for contract type 'Component'", - "detail": { - "actual_type": "Component", - "allowed_types": [ - "Module", - "Skill", - "Agent" - ] - } + "source_id": "BulkCorrectionSidebar", + "relation_type": "DEPENDS_ON", + "target_id": "TranslateApi", + "target_ref": "[TranslateApi]" }, { - "code": "tag_forbidden_by_complexity", - "tag": "LAYER", - "message": "@LAYER is forbidden for contract type 'Component' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Component" - } - }, - { - "code": "missing_required_tag", - "tag": "RELATION", - "message": "@RELATION is required for contract type 'Component' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Component" - } - }, - { - "code": "missing_required_tag", - "tag": "UX_STATE", - "message": "@UX_STATE is required for contract type 'Component' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Component" - } + "source_id": "BulkCorrectionSidebar", + "relation_type": "DEPENDS_ON", + "target_id": "dictionaryApi", + "target_ref": "[dictionaryApi]" } ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "\n\n\n\n\n\n\n \n \n \n {$t.translate?.corrections?.title}\n {#if items.length > 0}\n \n {items.length}\n \n {/if}\n\n\n\n{#if isOpen}\n
\n\n
\n \n
\n
\n

{$t.translate?.corrections?.title}

\n

{$t.translate?.corrections?.subtitle}

\n
\n \n
\n\n \n
\n {#if uxState === 'collecting'}\n {#if items.length === 0}\n
\n \n \n \n

{$t.translate?.corrections?.no_items}

\n

{$t.translate?.corrections?.add_hint}

\n
\n {:else}\n {#each items as item, idx}\n
\n
\n
\n

{$t.translate?.corrections?.source_term}

\n

{item.sourceTerm}

\n
\n removeItem(idx)}\n class=\"ml-2 p-0.5 text-gray-400 hover:text-red-500 rounded\"\n title={$t.translate?.corrections?.remove}\n >\n \n \n \n \n
\n
\n

{$t.translate?.corrections?.incorrect_target}

\n

{item.incorrectTarget}

\n
\n
\n \n updateCorrection(idx, e.target.value)}\n placeholder={$t.translate?.corrections?.corrected_placeholder}\n class=\"w-full mt-1 px-2 py-1 text-sm border border-gray-300 rounded focus:ring-2 focus:ring-green-500 focus:border-green-500\"\n />\n
\n
\n {/each}\n {/if}\n\n {:else if uxState === 'submitting'}\n
\n
\n

{$t.translate?.corrections?.submitting}

\n
\n\n {:else if uxState === 'submitted'}\n
\n \n \n \n

{$t.translate?.corrections?.submit_success}

\n {#if submitResult}\n

\n {$t.translate?.corrections?.submit_partial\n ?.replace('{success}', submitResult.created_count || submitResult.updated_count || items.length)\n ?.replace('{total}', items.length)}\n

\n {/if}\n
\n {/if}\n
\n\n \n
\n {#if uxState === 'collecting' && items.length > 0}\n \n
\n \n \n \n {#each dictionaries as dict}\n \n {/each}\n \n
\n\n \n {$t.translate?.corrections?.submit_all?.replace('{count}', validItemCount)}\n \n {:else if uxState === 'submitted'}\n \n {$t.translate?.common?.close}\n \n {/if}\n
\n
\n{/if}\n\n" + "body": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n {$t.translate?.corrections?.title}\n {#if items.length > 0}\n \n {items.length}\n \n {/if}\n\n\n\n{#if isOpen}\n
\n\n
\n \n
\n
\n

{$t.translate?.corrections?.title}

\n

{$t.translate?.corrections?.subtitle}

\n
\n \n
\n\n \n
\n {#if uxState === 'collecting'}\n {#if items.length === 0}\n
\n \n \n \n

{$t.translate?.corrections?.no_items}

\n

{$t.translate?.corrections?.add_hint}

\n
\n {:else}\n {#each items as item, idx}\n
\n
\n
\n

{$t.translate?.corrections?.source_term}

\n

{item.sourceTerm}

\n
\n removeItem(idx)}\n class=\"ml-2 p-0.5 text-gray-400 hover:text-red-500 rounded\"\n title={$t.translate?.corrections?.remove}\n >\n \n \n \n \n
\n
\n

{$t.translate?.corrections?.incorrect_target}

\n

{item.incorrectTarget}

\n
\n
\n \n updateCorrection(idx, e.target.value)}\n placeholder={$t.translate?.corrections?.corrected_placeholder}\n class=\"w-full mt-1 px-2 py-1 text-sm border border-gray-300 rounded focus:ring-2 focus:ring-green-500 focus:border-green-500\"\n />\n
\n
\n {/each}\n {/if}\n\n {:else if uxState === 'submitting'}\n
\n
\n

{$t.translate?.corrections?.submitting}

\n
\n\n {:else if uxState === 'submitted'}\n
\n \n \n \n

{$t.translate?.corrections?.submit_success}

\n {#if submitResult}\n

\n {$t.translate?.corrections?.submit_partial\n ?.replace('{success}', submitResult.created_count || submitResult.updated_count || items.length)\n ?.replace('{total}', items.length)}\n

\n {/if}\n
\n {/if}\n
\n\n \n
\n {#if uxState === 'collecting' && items.length > 0}\n \n
\n \n \n \n {#each dictionaries as dict}\n \n {/each}\n \n
\n\n \n {$t.translate?.corrections?.submit_all?.replace('{count}', validItemCount)}\n \n {:else if uxState === 'submitted'}\n \n {$t.translate?.common?.close}\n \n {/if}\n
\n
\n{/if}\n\n" }, { "contract_id": "BulkReplaceModal", "contract_type": "Component", "file_path": "frontend/src/lib/components/translate/BulkReplaceModal.svelte", "start_line": 1, - "end_line": 396, + "end_line": 379, "tier": "TIER_2", "complexity": 3, "metadata": { "COMPLEXITY": 3, - "LAYER": "UI", "PURPOSE": "Modal dialog for bulk find-and-replace on translated values within a completed run.", - "TYPE": "{'closed'|'configuring'|'previewing'|'preview_error'|'confirming'|'applying'|'applied'|'apply_error'}", "UX_STATE": "apply_error -> Apply failed with error message" }, "relations": [ @@ -88208,61 +87420,30 @@ "target_ref": "[TranslateApi]" } ], - "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "LAYER", - "message": "@LAYER is not allowed for contract type 'Component'", - "detail": { - "actual_type": "Component", - "allowed_types": [ - "Module", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "LAYER", - "message": "@LAYER is forbidden for contract type 'Component' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Component" - } - }, - { - "code": "unknown_tag", - "tag": "TYPE", - "message": "@TYPE is not defined in axiom_config.yaml tags", - "detail": null - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "\n\n\n\n\n\n\n{#if show}\n\t\n\t\t e.stopPropagation()}\n\t\t\trole=\"dialog\"\n\t\t\taria-modal=\"true\"\n\t\t\taria-label={$t.translate?.bulk_replace?.title}\n\t\t>\n\t\t\t\n\t\t\t
\n\t\t\t\t

{$t.translate?.bulk_replace?.title}

\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t
\n\n\t\t\t\n\t\t\t
\n\n\t\t\t\t\n\t\t\t\t{#if uxState === 'configuring' || uxState === 'previewing' || uxState === 'preview_error'}\n\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t e.key === 'Enter' && handlePreview()}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\n\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t e.key === 'Enter' && handlePreview()}\n\t\t\t\t\t\t/>\n\t\t\t\t\t
\n\n\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{#each targetLanguages as lang}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t{$t.translate?.bulk_replace?.preview_affected}\n\t\t\t\t\t\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if uxState === 'preview_error'}\n\t\t\t\t\t
\n\t\t\t\t\t\t

{errorMessage}

\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if uxState === 'previewing' && affectedRecords.length > 0}\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t

\n\t\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.preview_count.replace('{count}', affectedRecords.length)}\n\t\t\t\t\t\t\t

\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.apply_changes}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{#each affectedRecords.slice(0, 100) as row, i}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
{$t.translate?.bulk_replace?.table_number}{$t.translate?.bulk_replace?.table_before}{$t.translate?.bulk_replace?.table_after}
{i + 1}{row.final_value || row.translated_value || ''}{previewAfter(row)}
\n\t\t\t\t\t\t\t{#if affectedRecords.length > 100}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.showing_first.replace('{shown}', 100).replace('{total}', affectedRecords.length)}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t{#if uxState === 'previewing' && affectedRecords.length === 0}\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.bulk_replace?.no_matching}

\n\t\t\t\t\t\t

{$t.translate?.bulk_replace?.no_matching_hint}

\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if uxState === 'confirming'}\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t

\n\t\t\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.confirm_title.replace('{count}', applyCount)}\n\t\t\t\t\t\t\t\t

\n\t\t\t\t\t\t\t\t

\n\t\t\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.confirm_body.replace('{language}', targetLanguage)}\n\t\t\t\t\t\t\t\t

\n\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{#if submitToDict}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t
\n\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.cancel}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.apply_count.replace('{count}', applyCount)}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if uxState === 'applying'}\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t{$t.translate?.bulk_replace?.applying}\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if uxState === 'applied'}\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t

{$t.translate?.bulk_replace?.applied_title}

\n\t\t\t\t\t\t

{$t.translate?.bulk_replace?.applied_body.replace('{count}', applyCount)}

\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.done}\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if uxState === 'apply_error'}\n\t\t\t\t\t
\n\t\t\t\t\t\t

{errorMessage}

\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.retry}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.cancel}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t
\n\n\t\t\t\n\t\t\t
\n\t\t\t\t\n\t\t\t\t\t{$t.translate?.bulk_replace?.close}\n\t\t\t\t\n\t\t\t
\n\t\t
\n\t\n{/if}\n\n" + "body": "\n\n\n\n\n\n\n\n\n\n\n\n\tlet uxState = $state('closed');\n\n\tlet findPattern = $state('');\n\tlet replacementText = $state('');\n\tlet isRegex = $state(false);\n\tlet targetLanguage = $state('');\n\tlet affectedRecords = $state([]);\n\tlet applyCount = $state(0);\n\tlet errorMessage = $state('');\n\tlet submitToDict = $state(false);\n\tlet usageNotes = $state('');\n\n\t$effect(() => {\n\t\tif (show) {\n\t\t\tuxState = 'configuring';\n\t\t\tfindPattern = '';\n\t\t\treplacementText = '';\n\t\t\tisRegex = false;\n\t\t\ttargetLanguage = '';\n\t\t\taffectedRecords = [];\n\t\t\tapplyCount = 0;\n\t\t\terrorMessage = '';\n\t\t\tsubmitToDict = false;\n\t\t\tusageNotes = '';\n\t\t} else {\n\t\t\tuxState = 'closed';\n\t\t}\n\t});\n\n\t/** Preview affected records */\n\tasync function handlePreview() {\n\t\tif (!findPattern.trim()) {\n\t\t\taddToast(_('translate.bulk_replace.find_pattern_required'), 'warning');\n\t\t\treturn;\n\t\t}\n\t\tif (!targetLanguage) {\n\t\t\taddToast(_('translate.bulk_replace.target_language_required'), 'warning');\n\t\t\treturn;\n\t\t}\n\t\tuxState = 'previewing';\n\t\terrorMessage = '';\n\t\ttry {\n\t\t\tconst result = await bulkReplacePreview(runId, {\n\t\t\t\tpattern: findPattern,\n\t\t\t\tis_regex: isRegex,\n\t\t\t\treplacement_text: replacementText,\n\t\t\t\ttarget_language: targetLanguage\n\t\t\t});\n\t\t\taffectedRecords = result?.items || result?.records || [];\n\t\t\tapplyCount = affectedRecords.length;\n\t\t\tuxState = 'previewing';\n\t\t} catch (err) {\n\t\t\terrorMessage = err?.message || _('translate.bulk_replace.preview_failed');\n\t\t\tuxState = 'preview_error';\n\t\t\taddToast(errorMessage, 'error');\n\t\t}\n\t}\n\n\t/** Open confirmation */\n\tfunction handleShowConfirm() {\n\t\tuxState = 'confirming';\n\t}\n\n\t/** Cancel confirmation, back to preview */\n\tfunction handleCancelConfirm() {\n\t\tuxState = 'previewing';\n\t}\n\n\t/** Apply the bulk replacement */\n\tasync function handleApply() {\n\t\tuxState = 'applying';\n\t\ttry {\n\t\t\tconst result = await bulkFindReplace(runId, {\n\t\t\t\tpattern: findPattern,\n\t\t\t\tis_regex: isRegex,\n\t\t\t\treplacement_text: replacementText,\n\t\t\t\ttarget_language: targetLanguage,\n\t\t\t\tsubmit_to_dictionary: submitToDict,\n\t\t\t\tusage_notes: usageNotes || undefined,\n\t\t\t\tsubmit_to_dictionary_with_context: submitToDict\n\t\t\t});\n\t\t\tconst changed = result?.changed || result?.affected || applyCount;\n\t\t\tuxState = 'applied';\n\t\t\tonApplied(changed);\n\t\t\taddToast(_('translate.bulk_replace.applied_toast').replace('{count}', changed), 'success');\n\t\t} catch (err) {\n\t\t\terrorMessage = err?.message || _('translate.bulk_replace.apply_failed');\n\t\t\tuxState = 'apply_error';\n\t\t\taddToast(errorMessage, 'error');\n\t\t}\n\t}\n\n\tfunction handleClose() {\n\t\tonClose();\n\t}\n\n\tfunction previewAfter(row) {\n\t\tif (!replacementText && !isRegex) return '';\n\t\tif (isRegex) {\n\t\t\ttry {\n\t\t\t\tconst re = new RegExp(findPattern, 'g');\n\t\t\t\treturn (row.final_value || row.translated_value || '').replace(re, replacementText);\n\t\t\t} catch {\n\t\t\t\treturn row.final_value || row.translated_value || '';\n\t\t\t}\n\t\t}\n\t\treturn (row.final_value || row.translated_value || '').split(findPattern).join(replacementText);\n\t}\n\n\n{#if show}\n\t\n\t\t e.stopPropagation()}\n\t\t\trole=\"dialog\"\n\t\t\taria-modal=\"true\"\n\t\t\taria-label={$t.translate?.bulk_replace?.title}\n\t\t>\n\t\t\t\n\t\t\t
\n\t\t\t\t

{$t.translate?.bulk_replace?.title}

\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t
\n\n\t\t\t\n\t\t\t
\n\n\t\t\t\t\n\t\t\t\t{#if uxState === 'configuring' || uxState === 'previewing' || uxState === 'preview_error'}\n\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t e.key === 'Enter' && handlePreview()}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\n\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t e.key === 'Enter' && handlePreview()}\n\t\t\t\t\t\t/>\n\t\t\t\t\t
\n\n\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{#each targetLanguages as lang}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t{$t.translate?.bulk_replace?.preview_affected}\n\t\t\t\t\t\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if uxState === 'preview_error'}\n\t\t\t\t\t
\n\t\t\t\t\t\t

{errorMessage}

\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if uxState === 'previewing' && affectedRecords.length > 0}\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t

\n\t\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.preview_count.replace('{count}', affectedRecords.length)}\n\t\t\t\t\t\t\t

\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.apply_changes}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{#each affectedRecords.slice(0, 100) as row, i}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
{$t.translate?.bulk_replace?.table_number}{$t.translate?.bulk_replace?.table_before}{$t.translate?.bulk_replace?.table_after}
{i + 1}{row.final_value || row.translated_value || ''}{previewAfter(row)}
\n\t\t\t\t\t\t\t{#if affectedRecords.length > 100}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.showing_first.replace('{shown}', 100).replace('{total}', affectedRecords.length)}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t{#if uxState === 'previewing' && affectedRecords.length === 0}\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.bulk_replace?.no_matching}

\n\t\t\t\t\t\t

{$t.translate?.bulk_replace?.no_matching_hint}

\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if uxState === 'confirming'}\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t

\n\t\t\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.confirm_title.replace('{count}', applyCount)}\n\t\t\t\t\t\t\t\t

\n\t\t\t\t\t\t\t\t

\n\t\t\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.confirm_body.replace('{language}', targetLanguage)}\n\t\t\t\t\t\t\t\t

\n\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{#if submitToDict}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t
\n\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.cancel}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.apply_count.replace('{count}', applyCount)}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if uxState === 'applying'}\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t{$t.translate?.bulk_replace?.applying}\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if uxState === 'applied'}\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t

{$t.translate?.bulk_replace?.applied_title}

\n\t\t\t\t\t\t

{$t.translate?.bulk_replace?.applied_body.replace('{count}', applyCount)}

\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.done}\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if uxState === 'apply_error'}\n\t\t\t\t\t
\n\t\t\t\t\t\t

{errorMessage}

\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.retry}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{$t.translate?.bulk_replace?.cancel}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t
\n\n\t\t\t\n\t\t\t
\n\t\t\t\t\n\t\t\t\t\t{$t.translate?.bulk_replace?.close}\n\t\t\t\t\n\t\t\t
\n\t\t
\n\t\n{/if}\n\n" }, { "contract_id": "CorrectionCell", "contract_type": "Component", "file_path": "frontend/src/lib/components/translate/CorrectionCell.svelte", "start_line": 1, - "end_line": 326, + "end_line": 307, "tier": "TIER_2", "complexity": 3, "metadata": { "COMPLEXITY": 3, - "LAYER": "UI", "PURPOSE": "Inline-editable cell for translation run results with edit-save-cancel UX and submit-to-dictionary flow.", - "TYPE": "{'view'|'editing'|'saving'|'saved'|'submitting_to_dict'|'dict_submitted'|'error'}", "UX_STATE": "error -> Error state with retry option" }, "relations": [ { "source_id": "CorrectionCell", "relation_type": "DEPENDS_ON", - "target_id": "TranslateApi", - "target_ref": "[TranslateApi]" + "target_id": "dictionaryApi", + "target_ref": "[dictionaryApi]" }, { "source_id": "CorrectionCell", @@ -88271,51 +87452,21 @@ "target_ref": "[dictionaryApi]" } ], - "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "LAYER", - "message": "@LAYER is not allowed for contract type 'Component'", - "detail": { - "actual_type": "Component", - "allowed_types": [ - "Module", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "LAYER", - "message": "@LAYER is forbidden for contract type 'Component' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Component" - } - }, - { - "code": "unknown_tag", - "tag": "TYPE", - "message": "@TYPE is not defined in axiom_config.yaml tags", - "detail": null - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "\n\n\n\n\n\n\n\n\n{#if uxState === 'view'}\n\t e.key === 'Enter' && startEditing()}\n\t>\n\t\t\t{#if displayValue}\n\t\t\t{displayValue}\n\t\t{:else}\n\t\t\t\n\t\t{/if}\n\t\n\n\n{:else if uxState === 'editing'}\n\t
\n\t\t {\n\t\t\t\tif (e.key === 'Enter') saveEdit();\n\t\t\t\tif (e.key === 'Escape') cancelEditing();\n\t\t\t}}\n\t\t/>\n\t\t
\n\t\t\t\n\t\t\t\t✓\n\t\t\t\n\t\t\t\n\t\t\t\t✕\n\t\t\t\n\t\t
\n\t
\n\n\n{:else if uxState === 'saving'}\n\t
\n\t\t
\n\t\t{$t.translate?.corrections?.cell_saving}\n\t
\n\n\n{:else if uxState === 'saved'}\n\t
\n\t\t{displayValue}\n\t\t📝\n\t\t\n\t\t\t📕 {$t.translate?.corrections?.cell_submit_to_dict}\n\t\t\n\t
\n\n\n{:else if uxState === 'submitting_to_dict'}\n\t
\n\t\t
\n\t\t{$t.translate?.corrections?.cell_submitting}\n\t
\n\n\n{:else if uxState === 'dict_submitted'}\n\t
\n\t\t{displayValue}\n\t\t✅ {$t.translate?.corrections?.cell_submitted_badge}\n\t
\n\n\n{:else if uxState === 'error'}\n\t
\n\t\t{displayValue}\n\t\t{errorMessage}\n\t\t\n\t\t\t{$t.translate?.corrections?.cell_retry}\n\t\t\n\t
\n{/if}\n\n\n{#if dictPopupOpen}\n\t\n\t\t
e.stopPropagation()}>\n\t\t\t

{$t.translate?.corrections?.cell_submit_to_dict}

\n\t\t\t
\n\t\t\t\t{#if sourceLanguage}\n\t\t\t\t\t
\n\t\t\t\t\t\t{$t.translate?.corrections?.cell_language_pair} {sourceLanguage} → {languageCode}\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t
{editValue}
\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t{#each dictionaries as dict}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t\n\t\t\t\t
\n\n\t\t\t\t\n\t\t\t\t{#if editableContextData || contextEditMode}\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{$t.translate?.corrections?.cell_context_data}\n\t\t\t\t\t\t\t { contextEditMode = !contextEditMode; if (!contextEditMode) editableContextData = contextData ? JSON.parse(JSON.stringify(contextData)) : null; }}\n\t\t\t\t\t\t\t\tclass=\"text-xs text-blue-600 hover:text-blue-700\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{contextEditMode ? $t.translate?.corrections?.cell_cancel_edit : $t.translate?.corrections?.cell_edit}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t\t{#if contextEditMode}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t{:else if typeof editableContextData === 'object' && editableContextData !== null}\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t{#each Object.entries(editableContextData) as [key, val]}\n\t\t\t\t\t\t\t\t\t
{key}: {String(val).substring(0, 100)}
\n\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t

{$t.translate?.corrections?.cell_no_context_data}

\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
\n\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t{$t.translate?.corrections?.cell_cancel}\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t{$t.translate?.corrections?.cell_submit}\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t
\n\t\t
\n\t
\n{/if}\n\n" + "body": "\n\n\n\n\n\n\n\n\n\n\n\n\n\tlet uxState = $state('view');\n\tlet editValue = $state(value);\n\tlet displayValue = $state(value);\n\tlet errorMessage = $state('');\n\tlet dictPopupOpen = $state(false);\n\tlet dictionaries = $state([]);\n\tlet selectedDictId = $state('');\n\tlet editableContextData = $state(null);\n\tlet editableUsageNotes = $state('');\n\tlet contextEditMode = $state(false);\n\n\t$effect(() => {\n\t\t// Reset if value prop changes externally\n\t\tif (value !== displayValue) {\n\t\t\teditValue = value;\n\t\t\tdisplayValue = value;\n\t\t\tuxState = 'view';\n\t\t}\n\t});\n\n\tfunction startEditing() {\n\t\teditValue = value;\n\t\tuxState = 'editing';\n\t}\n\n\tfunction cancelEditing() {\n\t\teditValue = value;\n\t\tuxState = 'view';\n\t}\n\n\t/** @returns {Promise} */\n\tasync function saveEdit() {\n\t\tconst newValue = editValue.trim();\n\t\tif (!newValue || newValue === displayValue) {\n\t\t\tuxState = 'view';\n\t\t\treturn;\n\t\t}\n\t\tuxState = 'saving';\n\t\terrorMessage = '';\n\t\ttry {\n\t\t\tawait inlineEditCorrection(runId, recordId, languageCode, {\n\t\t\t\tfinal_value: newValue,\n\t\t\t\tsubmit_to_dictionary: false\n\t\t\t});\n\t\t\tdisplayValue = newValue;\n\t\t\tuxState = 'saved';\n\t\t\tonSave(newValue);\n\t\t\taddToast(_('translate.corrections.cell_save_success'), 'success');\n\t\t} catch (err) {\n\t\t\terrorMessage = err?.message || _('translate.corrections.cell_save_failed');\n\t\t\tuxState = 'error';\n\t\t\taddToast(errorMessage, 'error');\n\t\t}\n\t}\n\n\t/** @returns {Promise} */\n\tasync function openDictPopup() {\n\t\tdictPopupOpen = true;\n\t\teditableContextData = contextData ? JSON.parse(JSON.stringify(contextData)) : null;\n\t\teditableUsageNotes = usageNotes || '';\n\t\tcontextEditMode = false;\n\t\ttry {\n\t\t\tconst result = await dictionaryApi.fetchDictionaries({ page_size: 100 });\n\t\t\tdictionaries = Array.isArray(result) ? result : (result?.items || []);\n\t\t\tif (dictionaries.length === 1) {\n\t\t\t\tselectedDictId = dictionaries[0].id;\n\t\t\t}\n\t\t} catch (err) {\n\t\t\taddToast(_('translate.corrections.cell_dict_load_failed'), 'error');\n\t\t}\n\t}\n\n\t/** @returns {Promise} */\n\tasync function handleDictSubmit() {\n\t\tif (!selectedDictId) {\n\t\t\taddToast(_('translate.corrections.cell_select_dict_warning'), 'warning');\n\t\t\treturn;\n\t\t}\n\t\tuxState = 'submitting_to_dict';\n\t\ttry {\n\t\t\t// First save the edit to dictionary\n\t\t\tawait inlineEditCorrection(runId, recordId, languageCode, {\n\t\t\t\tfinal_value: editValue,\n\t\t\t\tsubmit_to_dictionary: true,\n\t\t\t\tdictionary_id: selectedDictId\n\t\t\t});\n\t\t\tuxState = 'dict_submitted';\n\t\t\taddToast(_('translate.corrections.cell_dict_submit_success'), 'success');\n\t\t\tdictPopupOpen = false;\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || _('translate.corrections.cell_dict_submit_failed'), 'error');\n\t\t\tuxState = 'saved';\n\t\t}\n\t}\n\n\tfunction cancelDictSubmit() {\n\t\tdictPopupOpen = false;\n\t\tuxState = 'saved';\n\t}\n\n\tfunction handleCloseDictPopup() {\n\t\tdictPopupOpen = false;\n\t}\n\n\n\n{#if uxState === 'view'}\n\t e.key === 'Enter' && startEditing()}\n\t>\n\t\t\t{#if displayValue}\n\t\t\t{displayValue}\n\t\t{:else}\n\t\t\t\n\t\t{/if}\n\t\n\n\n{:else if uxState === 'editing'}\n\t
\n\t\t {\n\t\t\t\tif (e.key === 'Enter') saveEdit();\n\t\t\t\tif (e.key === 'Escape') cancelEditing();\n\t\t\t}}\n\t\t/>\n\t\t
\n\t\t\t\n\t\t\t\t✓\n\t\t\t\n\t\t\t\n\t\t\t\t✕\n\t\t\t\n\t\t
\n\t
\n\n\n{:else if uxState === 'saving'}\n\t
\n\t\t
\n\t\t{$t.translate?.corrections?.cell_saving}\n\t
\n\n\n{:else if uxState === 'saved'}\n\t
\n\t\t{displayValue}\n\t\t📝\n\t\t\n\t\t\t📕 {$t.translate?.corrections?.cell_submit_to_dict}\n\t\t\n\t
\n\n\n{:else if uxState === 'submitting_to_dict'}\n\t
\n\t\t
\n\t\t{$t.translate?.corrections?.cell_submitting}\n\t
\n\n\n{:else if uxState === 'dict_submitted'}\n\t
\n\t\t{displayValue}\n\t\t✅ {$t.translate?.corrections?.cell_submitted_badge}\n\t
\n\n\n{:else if uxState === 'error'}\n\t
\n\t\t{displayValue}\n\t\t{errorMessage}\n\t\t\n\t\t\t{$t.translate?.corrections?.cell_retry}\n\t\t\n\t
\n{/if}\n\n\n{#if dictPopupOpen}\n\t\n\t\t
e.stopPropagation()}>\n\t\t\t

{$t.translate?.corrections?.cell_submit_to_dict}

\n\t\t\t
\n\t\t\t\t{#if sourceLanguage}\n\t\t\t\t\t
\n\t\t\t\t\t\t{$t.translate?.corrections?.cell_language_pair} {sourceLanguage} → {languageCode}\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t
{editValue}
\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t{#each dictionaries as dict}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t\n\t\t\t\t
\n\n\t\t\t\t\n\t\t\t\t{#if editableContextData || contextEditMode}\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{$t.translate?.corrections?.cell_context_data}\n\t\t\t\t\t\t\t { contextEditMode = !contextEditMode; if (!contextEditMode) editableContextData = contextData ? JSON.parse(JSON.stringify(contextData)) : null; }}\n\t\t\t\t\t\t\t\tclass=\"text-xs text-blue-600 hover:text-blue-700\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{contextEditMode ? $t.translate?.corrections?.cell_cancel_edit : $t.translate?.corrections?.cell_edit}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t\t{#if contextEditMode}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t{:else if typeof editableContextData === 'object' && editableContextData !== null}\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t{#each Object.entries(editableContextData) as [key, val]}\n\t\t\t\t\t\t\t\t\t
{key}: {String(val).substring(0, 100)}
\n\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t

{$t.translate?.corrections?.cell_no_context_data}

\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
\n\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t{$t.translate?.corrections?.cell_cancel}\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t{$t.translate?.corrections?.cell_submit}\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t
\n\t\t
\n\t
\n{/if}\n\n" }, { "contract_id": "ScheduleConfig", "contract_type": "Component", "file_path": "frontend/src/lib/components/translate/ScheduleConfig.svelte", "start_line": 1, - "end_line": 289, + "end_line": 273, "tier": "TIER_2", "complexity": 3, "metadata": { "COMPLEXITY": 3, - "LAYER": "UI", "PURPOSE": "Schedule configuration for a translation job — cron/interval/once triggers, timezone, enable/disable.", "UX_FEEDBACK": "Next-3-executions preview; toast on save/error", "UX_RECOVERY": "Enable/disable toggle; delete schedule", @@ -88329,45 +87480,21 @@ "target_ref": "[TranslateApi]" } ], - "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "LAYER", - "message": "@LAYER is not allowed for contract type 'Component'", - "detail": { - "actual_type": "Component", - "allowed_types": [ - "Module", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "LAYER", - "message": "@LAYER is forbidden for contract type 'Component' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Component" - } - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "\n\n\n\n\n
\n\t
\n\t\t

{$t.translate?.schedule?.title || 'Schedule Configuration'}

\n\t\t{#if !isLoading && scheduleExists}\n\t\t\t\n\t\t\t\t\n\t\t\t\t{isEnabled ? ($t.translate?.schedule?.enabled || 'Enabled') : ($t.translate?.schedule?.disabled || 'Disabled')}\n\t\t\t\n\t\t{/if}\n\t
\n\n\t{#if isLoading}\n\t\t
\n\n\t{:else if uxState === 'idle'}\n\t\t
\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t

{$t.translate?.schedule?.no_schedule || 'No schedule configured'}

\n\t\t\t

{$t.translate?.schedule?.no_schedule_hint || 'Set up a recurring schedule for automatic translations'}

\n\t\t\t\n\t\t
\n\n\t{:else if uxState === 'editing' || uxState === 'enabled' || uxState === 'disabled'}\n\t\t
\n\t\t\t\n\t\t\t
\n\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t

\n\t\t\t\t\t{getCronDescription(cronExpression)}\n\t\t\t\t

\n\t\t\t
\n\n\t\t\t\n\t\t\t
\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t{#each commonTimezones as tz}\n\t\t\t\t\t\t\n\t\t\t\t\t{/each}\n\t\t\t\t\n\t\t\t
\n\n\t\t\t\n\t\t\t
\n\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t
\n\n\t\t\t\n\t\t\t{#if nextExecutions.length > 0}\n\t\t\t\t
\n\t\t\t\t\t

{$t.translate?.schedule?.next_executions || 'Next Executions'}

\n\t\t\t\t\t{#each nextExecutions as dt, i}\n\t\t\t\t\t\t

{i + 1}. {new Date(dt).toLocaleString()}

\n\t\t\t\t\t{/each}\n\t\t\t\t
\n\t\t\t{/if}\n\n\t\t\t\n\t\t\t{#if uxState === 'no_prior_run_warning'}\n\t\t\t\t
\n\t\t\t\t\t

\n\t\t\t\t\t\t⚠ {$t.translate?.schedule?.no_prior_run_warning || 'No prior successful manual run. Schedule may run with default settings. Consider running manually first.'}\n\t\t\t\t\t

\n\t\t\t\t
\n\t\t\t{/if}\n\n\t\t\t\n\t\t\t
\n\t\t\t\t{#if scheduleExists}\n\t\t\t\t\t\n\t\t\t\t{:else}\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\t\t\t\t
\n\t\t\t\t\t{#if scheduleExists && (uxState === 'enabled' || uxState === 'disabled')}\n\t\t\t\t\t\t\n\t\t\t\t\t{/if}\n\t\t\t\t\t{#if uxState === 'editing'}\n\t\t\t\t\t\t\n\t\t\t\t\t{/if}\n\t\t\t\t
\n\t\t\t
\n\t\t
\n\t{/if}\n
\n\n" + "body": "\n\n\n\n\n\n\n\n\n\n\n\n\tlet uxState = $state('idle');\n\tlet cronExpression = $state('0 2 * * *');\n\tlet timezone = $state('UTC');\n\tlet executionMode = $state('full');\n\tlet isEnabled = $state(false);\n\tlet isLoading = $state(true);\n\tlet nextExecutions = $state([]);\n\tlet hasPriorRun = $state(true);\n\tlet scheduleExists = $state(false);\n\tlet isEditing = $derived(uxState === 'editing');\n\n\t$effect(() => {\n\t\tif (jobId) loadSchedule();\n\t});\n\n\tasync function loadSchedule() {\n\t\tisLoading = true;\n\t\ttry {\n\t\t\tconst sch = await fetchSchedule(jobId);\n\t\t\tif (sch && sch.cron_expression) {\n\t\t\t\tcronExpression = sch.cron_expression;\n\t\t\t\ttimezone = sch.timezone || 'UTC';\n\t\t\t\texecutionMode = sch.execution_mode || 'full';\n\t\t\t\tisEnabled = sch.is_active !== false;\n\t\t\t\tscheduleExists = true;\n\t\t\t\tuxState = isEnabled ? 'enabled' : 'disabled';\n\t\t\t\tloadNextExecutions();\n\t\t\t} else {\n\t\t\t\tuxState = 'idle';\n\t\t\t}\n\t\t} catch (err) {\n\t\t\t// 404 = no schedule\n\t\t\tuxState = 'idle';\n\t\t} finally {\n\t\t\tisLoading = false;\n\t\t}\n\t}\n\n\tasync function loadNextExecutions() {\n\t\ttry {\n\t\t\tconst result = await fetchNextExecutions(jobId, 3);\n\t\t\tnextExecutions = result?.next_executions || [];\n\t\t} catch (err) {\n\t\t\tnextExecutions = [];\n\t\t}\n\t}\n\n\tasync function handleSave() {\n\t\ttry {\n\t\t\tconst payload = {\n\t\t\t\tcron_expression: cronExpression,\n\t\t\t\ttimezone: timezone,\n\t\t\t\tis_active: isEnabled,\n\t\t\t\texecution_mode: executionMode,\n\t\t\t};\n\t\t\tawait setSchedule(jobId, payload);\n\t\t\taddToast($t.translate?.schedule?.saved || 'Schedule saved', 'success');\n\t\t\tscheduleExists = true;\n\t\t\tuxState = isEnabled ? 'enabled' : 'disabled';\n\t\t\tloadNextExecutions();\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || ($t.translate?.schedule?.save_failed || 'Failed to save schedule'), 'error');\n\t\t}\n\t}\n\n\tasync function handleDelete() {\n\t\ttry {\n\t\t\tawait deleteSchedule(jobId);\n\t\t\taddToast($t.translate?.schedule?.deleted || 'Schedule deleted', 'success');\n\t\t\tscheduleExists = false;\n\t\t\tuxState = 'idle';\n\t\t\tcronExpression = '0 2 * * *';\n\t\t\tnextExecutions = [];\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || ($t.translate?.schedule?.delete_failed || 'Failed to delete schedule'), 'error');\n\t\t}\n\t}\n\n\tasync function handleToggle() {\n\t\ttry {\n\t\t\tif (isEnabled) {\n\t\t\t\tawait disableSchedule(jobId);\n\t\t\t\tisEnabled = false;\n\t\t\t\tuxState = 'disabled';\n\t\t\t\taddToast($t.translate?.schedule?.disabled_toast || 'Schedule disabled', 'info');\n\t\t\t} else {\n\t\t\t\tif (!scheduleExists) {\n\t\t\t\t\tawait handleSave();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tawait enableSchedule(jobId);\n\t\t\t\tisEnabled = true;\n\t\t\t\tuxState = 'enabled';\n\t\t\t\taddToast($t.translate?.schedule?.enabled_toast || 'Schedule enabled', 'success');\n\t\t\t\tloadNextExecutions();\n\t\t\t}\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || ($t.translate?.schedule?.toggle_failed || 'Failed to toggle schedule'), 'error');\n\t\t}\n\t}\n\n\tfunction getCronDescription(cron) {\n\t\tconst parts = cron.split(' ');\n\t\tif (parts.length !== 5) return cron;\n\t\tif (parts[1] === '*' && parts[2] === '*' && parts[4] === '*') {\n\t\t\tconst hour = parts[0] === '*' ? '' : parts[0];\n\t\t\tconst min = parts[1];\n\t\t\tif (parts[0] === '*') {\n\t\t\t\treturn ($t.translate?.schedule?.description_every_hour || 'at :{minute} past the hour').replace('{minute}', min);\n\t\t\t}\n\t\t\treturn ($t.translate?.schedule?.description_daily || 'Daily at {hour}:{minute}').replace('{hour}', hour).replace('{minute}', min);\n\t\t}\n\t\treturn ($t.translate?.schedule?.description_cron || 'Cron: {cron}').replace('{cron}', cron);\n\t}\n\n\tconst commonTimezones = [\n\t\t'UTC', 'US/Eastern', 'US/Central', 'US/Mountain', 'US/Pacific',\n\t\t'Europe/London', 'Europe/Berlin', 'Europe/Moscow', 'Europe/Paris',\n\t\t'Asia/Tokyo', 'Asia/Shanghai', 'Asia/Kolkata', 'Australia/Sydney',\n\t];\n\n\n
\n\t
\n\t\t

{$t.translate?.schedule?.title || 'Schedule Configuration'}

\n\t\t{#if !isLoading && scheduleExists}\n\t\t\t\n\t\t\t\t\n\t\t\t\t{isEnabled ? ($t.translate?.schedule?.enabled || 'Enabled') : ($t.translate?.schedule?.disabled || 'Disabled')}\n\t\t\t\n\t\t{/if}\n\t
\n\n\t{#if isLoading}\n\t\t
\n\n\t{:else if uxState === 'idle'}\n\t\t
\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t

{$t.translate?.schedule?.no_schedule || 'No schedule configured'}

\n\t\t\t

{$t.translate?.schedule?.no_schedule_hint || 'Set up a recurring schedule for automatic translations'}

\n\t\t\t\n\t\t
\n\n\t{:else if uxState === 'editing' || uxState === 'enabled' || uxState === 'disabled'}\n\t\t
\n\t\t\t\n\t\t\t
\n\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t

\n\t\t\t\t\t{getCronDescription(cronExpression)}\n\t\t\t\t

\n\t\t\t
\n\n\t\t\t\n\t\t\t
\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t{#each commonTimezones as tz}\n\t\t\t\t\t\t\n\t\t\t\t\t{/each}\n\t\t\t\t\n\t\t\t
\n\n\t\t\t\n\t\t\t
\n\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t
\n\n\t\t\t\n\t\t\t{#if nextExecutions.length > 0}\n\t\t\t\t
\n\t\t\t\t\t

{$t.translate?.schedule?.next_executions || 'Next Executions'}

\n\t\t\t\t\t{#each nextExecutions as dt, i}\n\t\t\t\t\t\t

{i + 1}. {new Date(dt).toLocaleString()}

\n\t\t\t\t\t{/each}\n\t\t\t\t
\n\t\t\t{/if}\n\n\t\t\t\n\t\t\t{#if uxState === 'no_prior_run_warning'}\n\t\t\t\t
\n\t\t\t\t\t

\n\t\t\t\t\t\t⚠ {$t.translate?.schedule?.no_prior_run_warning || 'No prior successful manual run. Schedule may run with default settings. Consider running manually first.'}\n\t\t\t\t\t

\n\t\t\t\t
\n\t\t\t{/if}\n\n\t\t\t\n\t\t\t
\n\t\t\t\t{#if scheduleExists}\n\t\t\t\t\t\n\t\t\t\t{:else}\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\t\t\t\t
\n\t\t\t\t\t{#if scheduleExists && (uxState === 'enabled' || uxState === 'disabled')}\n\t\t\t\t\t\t\n\t\t\t\t\t{/if}\n\t\t\t\t\t{#if uxState === 'editing'}\n\t\t\t\t\t\t\n\t\t\t\t\t{/if}\n\t\t\t\t
\n\t\t\t
\n\t\t
\n\t{/if}\n
\n\n" }, { "contract_id": "TermCorrectionPopup", "contract_type": "Component", "file_path": "frontend/src/lib/components/translate/TermCorrectionPopup.svelte", "start_line": 1, - "end_line": 349, + "end_line": 323, "tier": "TIER_2", "complexity": 3, "metadata": { "COMPLEXITY": 3, - "LAYER": "UI", "PURPOSE": "Popup for submitting a term correction from a run result row.", "UX_FEEDBACK": "Toast on success/error; conflict dialog with action buttons", "UX_RECOVERY": "Cancel button returns to previous state", @@ -88376,9 +87503,9 @@ "relations": [ { "source_id": "TermCorrectionPopup", - "relation_type": "DEPENDS_ON", - "target_id": "TranslateApi", - "target_ref": "[TranslateApi]" + "relation_type": "BINDS_TO", + "target_id": "dictionaryApi", + "target_ref": "[dictionaryApi]" }, { "source_id": "TermCorrectionPopup", @@ -88387,105 +87514,49 @@ "target_ref": "[dictionaryApi]" } ], - "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "LAYER", - "message": "@LAYER is not allowed for contract type 'Component'", - "detail": { - "actual_type": "Component", - "allowed_types": [ - "Module", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "LAYER", - "message": "@LAYER is forbidden for contract type 'Component' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Component" - } - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "\n\n\n\n\n{#if uxState !== 'closed'}\n\t
\n\t\t
e.stopPropagation()}>\n\t\t\t\n\t\t\t
\n\t\t\t\t

{$t.translate?.term_correction?.title}

\n\t\t\t\t\n\t\t\t
\n\n\t\t\t\n\t\t\t{#if uxState === 'selecting'}\n\t\t\t\t

{$t.translate?.term_correction?.loading_dictionaries}

\n\n\t\t\t\n\t\t\t{:else if uxState === 'editing'}\n\t\t\t\t
\n\t\t\t\t\t{#if sourceLanguage || targetLanguage}\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{$t.translate?.term_correction?.language_pair} {sourceLanguage || $t.translate?.term_correction?.detected} → {targetLanguage || languageCode}\n\t\t\t\t\t\t
\n\t\t\t\t\t{/if}\n\n\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\t { showContextEditor = !showContextEditor; }}\n\t\t\t\t\t\t\tclass=\"w-full flex items-center justify-between px-3 py-2 text-xs font-medium text-gray-600 bg-gray-50 hover:bg-gray-100 transition-colors\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t📋\n\t\t\t\t\t\t\t\t{$t.translate?.term_correction?.context_from_source}\n\t\t\t\t\t\t\t\t{#if contextData}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{hasEditedContext ? '✏️ ' + $t.translate?.term_correction?.edited_badge : '🤖 ' + $t.translate?.term_correction?.auto_badge}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t{#if showContextEditor}\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t{#if contextData}\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t{JSON.stringify(contextData, null, 2)}\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t {\n\t\t\t\t\t\t\t\t\t\t\t\tcontextEditorText = JSON.stringify(contextData, null, 2);\n\t\t\t\t\t\t\t\t\t\t\t\tshowContextEditor = true;\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\tclass=\"text-[11px] px-2 py-1 rounded border border-gray-300 text-gray-600 hover:bg-gray-50\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.term_correction?.edit_context}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t {\n\t\t\t\t\t\t\t\t\t\t\t\tcontextData = null;\n\t\t\t\t\t\t\t\t\t\t\t\thasEditedContext = true;\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\tclass=\"text-[11px] px-2 py-1 rounded border border-red-200 text-red-600 hover:bg-red-50\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.term_correction?.remove_context}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t

{$t.translate?.term_correction?.no_context}

\n\t\t\t\t\t\t\t\t\t {\n\t\t\t\t\t\t\t\t\t\t\tcontextData = JSON.parse(JSON.stringify(initialContextData));\n\t\t\t\t\t\t\t\t\t\t\tcontextEditorText = JSON.stringify(initialContextData, null, 2);\n\t\t\t\t\t\t\t\t\t\t\thasEditedContext = false;\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\tclass=\"text-[11px] px-2 py-1 rounded border border-gray-300 text-gray-600 hover:bg-gray-50\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{$t.translate?.term_correction?.restore_context}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t
\n\n\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{#each dictionaries as dict}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{$t.translate?.term_correction?.submit_correction}\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t
\n\n\t\t\t\n\t\t\t{:else if uxState === 'submitting'}\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t

{$t.translate?.term_correction?.submitting}

\n\t\t\t\t
\n\n\t\t\t\n\t\t\t{:else if uxState === 'conflict_detected'}\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.term_correction?.conflict_detected}

\n\t\t\t\t\t\t

\n\t\t\t\t\t\t\t{$t.translate?.term_correction?.conflict_description.replace('{source}', conflictInfo?.source_term || '').replace('{existing}', conflictInfo?.existing_target_term || '')}\n\t\t\t\t\t\t

\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t
\n\n\t\t\t\n\t\t\t{:else if uxState === 'submitted'}\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t

{$t.translate?.term_correction?.submitted}

\n\t\t\t\t\t

{submitResult?.message || ''}

\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t{/if}\n\t\t
\n\t
\n{/if}\n\n" + "body": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\tlet uxState = $state('closed');\n\tlet correctedTarget = $state('');\n\tlet dictionaries = $state([]);\n\tlet selectedDictId = $state('');\n\tlet conflictInfo = $state(null);\n\tlet submitResult = $state(null);\n\n\t// Context state\n\tlet contextData = $state(null);\n\tlet contextUsageNotes = $state('');\n\tlet hasEditedContext = $state(false);\n\tlet showContextEditor = $state(false);\n\tlet contextEditorText = $state('');\n\n\t$effect(() => {\n\t\tif (initialContextData) {\n\t\t\tcontextData = JSON.parse(JSON.stringify(initialContextData));\n\t\t\tcontextEditorText = JSON.stringify(initialContextData, null, 2);\n\t\t}\n\t\tif (initialUsageNotes) {\n\t\t\tcontextUsageNotes = initialUsageNotes;\n\t\t}\n\t});\n\n\t$effect(() => {\n\t\tif (sourceTerm && incorrectTarget) {\n\t\t\tuxState = 'selecting';\n\t\t\tloadDictionaries();\n\t\t}\n\t});\n\n\tasync function loadDictionaries() {\n\t\ttry {\n\t\t\tconst result = await dictionaryApi.fetchDictionaries({ page_size: 100 });\n\t\t\tdictionaries = Array.isArray(result) ? result : (result?.items || []);\n\t\t\tif (dictionaries.length === 1) {\n\t\t\t\tselectedDictId = dictionaries[0].id;\n\t\t\t}\n\t\t\tuxState = dictionaries.length > 0 ? 'editing' : 'selecting';\n\t\t} catch (err) {\n\t\t\taddToast(_('translate.term_correction.dict_load_failed'), 'error');\n\t\t\tuxState = 'editing';\n\t\t}\n\t}\n\n\tasync function handleSubmit() {\n\t\tif (!selectedDictId || !correctedTarget.trim()) return;\n\t\tuxState = 'submitting';\n\t\ttry {\n\t\t\tconst payload = {\n\t\t\t\tsource_term: sourceTerm,\n\t\t\t\tincorrect_target_term: incorrectTarget,\n\t\t\t\tcorrected_target_term: correctedTarget.trim(),\n\t\t\t\tdictionary_id: selectedDictId,\n\t\t\t\torigin_run_id: runId || undefined,\n\t\t\t\torigin_row_key: rowKey || undefined,\n\t\t\t};\n\t\t\tif (contextData) {\n\t\t\t\tpayload.context_data = contextData;\n\t\t\t}\n\t\t\tif (contextUsageNotes) {\n\t\t\t\tpayload.usage_notes = contextUsageNotes;\n\t\t\t}\n\t\t\tconst result = await submitCorrection(payload);\n\t\t\tif (result.action === 'conflict_detected') {\n\t\t\t\tconflictInfo = result.conflict;\n\t\t\t\tuxState = 'conflict_detected';\n\t\t\t} else if (result.action === 'created' || result.action === 'updated') {\n\t\t\t\tsubmitResult = result;\n\t\t\t\tuxState = 'submitted';\n\t\t\t\taddToast(result.message || _('translate.term_correction.submit_success'), 'success');\n\t\t\t\tonSubmitted(result);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || _('translate.term_correction.submit_failed'), 'error');\n\t\t\tuxState = 'editing';\n\t\t}\n\t}\n\n\tasync function handleConflictOverwrite() {\n\t\ttry {\n\t\t\tconst result = await submitCorrection({\n\t\t\t\tsource_term: sourceTerm,\n\t\t\t\tincorrect_target_term: incorrectTarget,\n\t\t\t\tcorrected_target_term: correctedTarget.trim(),\n\t\t\t\tdictionary_id: selectedDictId,\n\t\t\t\torigin_run_id: runId || undefined,\n\t\t\t\torigin_row_key: rowKey || undefined,\n\t\t\t});\n\t\t\tsubmitResult = result;\n\t\t\tuxState = 'submitted';\n\t\t\taddToast(result.message || _('translate.term_correction.overwrite_success'), 'success');\n\t\t\tonSubmitted(result);\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || _('translate.term_correction.overwrite_failed'), 'error');\n\t\t\tuxState = 'conflict_detected';\n\t\t}\n\t}\n\n\tfunction handleConflictKeep() {\n\t\tuxState = 'submitted';\n\t\taddToast(_('translate.term_correction.keep_success'), 'info');\n\t\tonSubmitted({ action: 'kept' });\n\t}\n\n\tfunction handleClose() {\n\t\tuxState = 'closed';\n\t\tonClose();\n\t}\n\n\n{#if uxState !== 'closed'}\n\t
\n\t\t
e.stopPropagation()}>\n\t\t\t\n\t\t\t
\n\t\t\t\t

{$t.translate?.term_correction?.title}

\n\t\t\t\t\n\t\t\t
\n\n\t\t\t\n\t\t\t{#if uxState === 'selecting'}\n\t\t\t\t

{$t.translate?.term_correction?.loading_dictionaries}

\n\n\t\t\t\n\t\t\t{:else if uxState === 'editing'}\n\t\t\t\t
\n\t\t\t\t\t{#if sourceLanguage || targetLanguage}\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{$t.translate?.term_correction?.language_pair} {sourceLanguage || $t.translate?.term_correction?.detected} → {targetLanguage || languageCode}\n\t\t\t\t\t\t
\n\t\t\t\t\t{/if}\n\n\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\t { showContextEditor = !showContextEditor; }}\n\t\t\t\t\t\t\tclass=\"w-full flex items-center justify-between px-3 py-2 text-xs font-medium text-gray-600 bg-gray-50 hover:bg-gray-100 transition-colors\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t📋\n\t\t\t\t\t\t\t\t{$t.translate?.term_correction?.context_from_source}\n\t\t\t\t\t\t\t\t{#if contextData}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{hasEditedContext ? '✏️ ' + $t.translate?.term_correction?.edited_badge : '🤖 ' + $t.translate?.term_correction?.auto_badge}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t{#if showContextEditor}\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t{#if contextData}\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t{JSON.stringify(contextData, null, 2)}\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t {\n\t\t\t\t\t\t\t\t\t\t\t\tcontextEditorText = JSON.stringify(contextData, null, 2);\n\t\t\t\t\t\t\t\t\t\t\t\tshowContextEditor = true;\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\tclass=\"text-[11px] px-2 py-1 rounded border border-gray-300 text-gray-600 hover:bg-gray-50\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.term_correction?.edit_context}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t {\n\t\t\t\t\t\t\t\t\t\t\t\tcontextData = null;\n\t\t\t\t\t\t\t\t\t\t\t\thasEditedContext = true;\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\tclass=\"text-[11px] px-2 py-1 rounded border border-red-200 text-red-600 hover:bg-red-50\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.term_correction?.remove_context}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t

{$t.translate?.term_correction?.no_context}

\n\t\t\t\t\t\t\t\t\t {\n\t\t\t\t\t\t\t\t\t\t\tcontextData = JSON.parse(JSON.stringify(initialContextData));\n\t\t\t\t\t\t\t\t\t\t\tcontextEditorText = JSON.stringify(initialContextData, null, 2);\n\t\t\t\t\t\t\t\t\t\t\thasEditedContext = false;\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\tclass=\"text-[11px] px-2 py-1 rounded border border-gray-300 text-gray-600 hover:bg-gray-50\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{$t.translate?.term_correction?.restore_context}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t
\n\n\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{#each dictionaries as dict}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{$t.translate?.term_correction?.submit_correction}\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t
\n\n\t\t\t\n\t\t\t{:else if uxState === 'submitting'}\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t

{$t.translate?.term_correction?.submitting}

\n\t\t\t\t
\n\n\t\t\t\n\t\t\t{:else if uxState === 'conflict_detected'}\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.term_correction?.conflict_detected}

\n\t\t\t\t\t\t

\n\t\t\t\t\t\t\t{$t.translate?.term_correction?.conflict_description.replace('{source}', conflictInfo?.source_term || '').replace('{existing}', conflictInfo?.existing_target_term || '')}\n\t\t\t\t\t\t

\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t
\n\n\t\t\t\n\t\t\t{:else if uxState === 'submitted'}\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t

{$t.translate?.term_correction?.submitted}

\n\t\t\t\t\t

{submitResult?.message || ''}

\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t{/if}\n\t\t
\n\t
\n{/if}\n\n" }, { "contract_id": "TranslationMetricsDashboard", "contract_type": "Component", "file_path": "frontend/src/lib/components/translate/TranslationMetricsDashboard.svelte", "start_line": 1, - "end_line": 192, + "end_line": 198, "tier": "TIER_2", "complexity": 3, "metadata": { "COMPLEXITY": 3, - "LAYER": "UI", - "PURPOSE": "Admin metrics dashboard for translation — per-job run counts, success/failure ratio," + "PURPOSE": "Admin metrics dashboard for translation — per-job run counts, success/failure ratio,", + "UX_FEEDBACK": "Spinner during load; card grid for totals; table for per-job breakdown", + "UX_RECOVERY": "Retry button on error", + "UX_STATE": "empty -> No metrics data available" }, - "relations": [], - "schema_warnings": [ + "relations": [ { - "code": "tag_not_for_contract_type", - "tag": "LAYER", - "message": "@LAYER is not allowed for contract type 'Component'", - "detail": { - "actual_type": "Component", - "allowed_types": [ - "Module", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "LAYER", - "message": "@LAYER is forbidden for contract type 'Component' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Component" - } - }, - { - "code": "missing_required_tag", - "tag": "RELATION", - "message": "@RELATION is required for contract type 'Component' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Component" - } - }, - { - "code": "missing_required_tag", - "tag": "UX_STATE", - "message": "@UX_STATE is required for contract type 'Component' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Component" - } + "source_id": "TranslationMetricsDashboard", + "relation_type": "DEPENDS_ON", + "target_id": "TranslateApi", + "target_ref": "[TranslateApi]" } ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "\n\n\n\n\n
\n \n
\n
\n

{$t.translate?.metrics?.title}

\n

{$t.translate?.metrics?.subtitle}

\n
\n \n \n \n \n {$t.translate?.metrics?.refresh}\n \n
\n\n \n {#if uxState === 'loading'}\n
\n {#each Array(3) as _}\n
\n {/each}\n
\n\n \n {:else if uxState === 'error'}\n
\n

{errorMessage}

\n \n {$t.translate?.common?.retry}\n \n
\n\n \n {:else if uxState === 'empty'}\n
\n \n \n \n

{$t.translate?.metrics?.no_data}

\n
\n\n \n {:else if uxState === 'loaded'}\n \n
\n
\n

{$t.translate?.metrics?.total_runs}

\n

{totalRuns}

\n
\n
\n

{$t.translate?.metrics?.success_rate}

\n

{successRate}%

\n
\n
\n

{$t.translate?.metrics?.failed_runs}

\n

{failedRuns}

\n
\n
\n

{$t.translate?.metrics?.total_records}

\n

{totalRecords.toLocaleString()}

\n
\n
\n

{$t.translate?.metrics?.total_tokens}

\n

{totalTokens.toLocaleString()}

\n
\n
\n

{$t.translate?.metrics?.total_cost}

\n

${totalCost.toFixed(2)}

\n
\n
\n\n \n
\n
\n

{$t.translate?.metrics?.runs_per_job}

\n
\n
\n \n \n \n \n \n \n \n \n \n \n \n \n {#each metrics as m}\n \n \n \n \n \n \n \n \n {/each}\n \n
{$t.translate?.metrics?.job}{$t.translate?.metrics?.runs}{$t.translate?.metrics?.successful}{$t.translate?.metrics?.failed}{$t.translate?.metrics?.tokens}{$t.translate?.metrics?.cost}
{m.job_name || m.job_id}{m.total_runs || 0}{m.successful_runs || 0}{m.failed_runs || 0}{(m.total_tokens || 0).toLocaleString()}${(m.total_cost || 0).toFixed(2)}
\n
\n
\n\n \n {#if avgLatency !== null}\n
\n

{$t.translate?.metrics?.avg_latency}

\n

{avgLatency}s

\n
\n {/if}\n {/if}\n
\n\n" + "body": "\n\n\n\n\n\n\n\n\n\n\n
\n \n
\n
\n

{$t.translate?.metrics?.title}

\n

{$t.translate?.metrics?.subtitle}

\n
\n \n \n \n \n {$t.translate?.metrics?.refresh}\n \n
\n\n \n {#if uxState === 'loading'}\n
\n {#each Array(3) as _}\n
\n {/each}\n
\n\n \n {:else if uxState === 'error'}\n
\n

{errorMessage}

\n \n {$t.translate?.common?.retry}\n \n
\n\n \n {:else if uxState === 'empty'}\n
\n \n \n \n

{$t.translate?.metrics?.no_data}

\n
\n\n \n {:else if uxState === 'loaded'}\n \n
\n
\n

{$t.translate?.metrics?.total_runs}

\n

{totalRuns}

\n
\n
\n

{$t.translate?.metrics?.success_rate}

\n

{successRate}%

\n
\n
\n

{$t.translate?.metrics?.failed_runs}

\n

{failedRuns}

\n
\n
\n

{$t.translate?.metrics?.total_records}

\n

{totalRecords.toLocaleString()}

\n
\n
\n

{$t.translate?.metrics?.total_tokens}

\n

{totalTokens.toLocaleString()}

\n
\n
\n

{$t.translate?.metrics?.total_cost}

\n

${totalCost.toFixed(2)}

\n
\n
\n\n \n
\n
\n

{$t.translate?.metrics?.runs_per_job}

\n
\n
\n \n \n \n \n \n \n \n \n \n \n \n \n {#each metrics as m}\n \n \n \n \n \n \n \n \n {/each}\n \n
{$t.translate?.metrics?.job}{$t.translate?.metrics?.runs}{$t.translate?.metrics?.successful}{$t.translate?.metrics?.failed}{$t.translate?.metrics?.tokens}{$t.translate?.metrics?.cost}
{m.job_name || m.job_id}{m.total_runs || 0}{m.successful_runs || 0}{m.failed_runs || 0}{(m.total_tokens || 0).toLocaleString()}${(m.total_cost || 0).toFixed(2)}
\n
\n
\n\n \n {#if avgLatency !== null}\n
\n

{$t.translate?.metrics?.avg_latency}

\n

{avgLatency}s

\n
\n {/if}\n {/if}\n
\n\n" }, { "contract_id": "TranslationPreview", "contract_type": "Component", "file_path": "frontend/src/lib/components/translate/TranslationPreview.svelte", "start_line": 1, - "end_line": 531, + "end_line": 549, "tier": "TIER_2", "complexity": 3, "metadata": { "COMPLEXITY": 3, - "LAYER": "UI", "POST": "User can preview, approve/edit/reject per-language rows, and accept the session to gate full execution.", "PRE": "jobId is a valid translation job ID.", "PURPOSE": "Multi-language translation preview with dynamic per-language columns, approve/edit/reject, cost estimate, and accept gate.", @@ -88497,8 +87568,8 @@ { "source_id": "TranslationPreview", "relation_type": "DEPENDS_ON", - "target_id": "TranslateApi", - "target_ref": "[TranslateApi]" + "target_id": "api_module", + "target_ref": "[api_module]" }, { "source_id": "TranslationPreview", @@ -88508,28 +87579,6 @@ } ], "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "LAYER", - "message": "@LAYER is not allowed for contract type 'Component'", - "detail": { - "actual_type": "Component", - "allowed_types": [ - "Module", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "LAYER", - "message": "@LAYER is forbidden for contract type 'Component' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Component" - } - }, { "code": "tag_forbidden_by_complexity", "tag": "POST", @@ -88551,22 +87600,21 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "\n\n\n\n\n
\n\t\n\t
\n\t\t

{$t.translate?.preview?.title}

\n\t\t{#if uxState === 'preview_loaded'}\n\t\t\t\n\t\t\t\t{session?.status === 'APPLIED' ? $t.translate?.preview?.accepted_badge : $t.translate?.preview?.active_badge}\n\t\t\t\n\t\t{/if}\n\t
\n\n\t\n\t{#if uxState === 'idle'}\n\t\t
\n\t\t\t

\n\t\t\t\t{$t.translate?.preview?.title} — {$t.translate?.preview?.sample_size} {sampleSize}\n\t\t\t

\n\t\t\t
\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t{sampleSize}\n\t\t\t
\n\t\t\t{#if sampleSize > 30}\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{($t.translate?.preview?.cost_warning) || 'Large sample size may incur higher costs'}\n\t\t\t\t
\n\t\t\t{/if}\n\t\t\t\n\t\t\t\t{$t.translate?.preview?.run_preview}\n\t\t\t\n\t\t
\n\n\t\n\t{:else if uxState === 'loading'}\n\t\t
\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t{$t.translate?.preview?.running_preview}\n\t\t\t
\n\t\t\t
\n\t\t\t\t{#each Array(3) as _}\n\t\t\t\t\t
\n\t\t\t\t{/each}\n\t\t\t
\n\t\t
\n\n\t\n\t{:else if uxState === 'preview_error'}\n\t\t
\n\t\t\t

{errorMessage}

\n\t\t\t
\n\t\t\t\t\n\t\t\t\t\t{$t.translate?.preview?.retry_preview}\n\t\t\t\t\n\t\t\t\t\n\t\t\t
\n\t\t
\n\n\t\n\t{:else if uxState === 'preview_loaded'}\n\t\t\n\t\t{#if costEstimate}\n\t\t\t
\n\t\t\t\t

{$t.translate?.preview?.cost_estimate}

\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t{$t.translate?.preview?.sample_rows}\n\t\t\t\t\t\t{costEstimate.sample_size}\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t{$t.translate?.preview?.sample_tokens}\n\t\t\t\t\t\t{costEstimate.sample_total_tokens?.toLocaleString()}\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t{$t.translate?.preview?.sample_cost}\n\t\t\t\t\t\t${costEstimate.sample_cost?.toFixed(6)}\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t{$t.translate?.preview?.est_total_cost}\n\t\t\t\t\t\t${costEstimate.estimated_cost?.toFixed(6)}\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\n\t\t\t\t

\n\t\t\t\t\t{$t.translate?.preview?.across_languages?.replace('{count}', costEstimate.num_languages || targetLanguages.length || 1)}\n\t\t\t\t

\n\t\t\t\t\n\t\t\t\t{#if costEstimate.warning}\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t{costEstimate.warning}\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\t\t\t
\n\t\t{/if}\n\n\t\t\n\t\t
\n\t\t\t
\n\t\t\t\t{$t.translate?.preview?.rows_count?.replace('{count}', records.length)}\n\t\t\t\t{$t.translate?.preview?.approved_count?.replace('{count}', approvedCount)}\n\t\t\t\t{$t.translate?.preview?.rejected_count?.replace('{count}', rejectedCount)}\n\t\t\t\t{#if pendingCount > 0}\n\t\t\t\t\t{$t.translate?.preview?.pending_count?.replace('{count}', pendingCount)}\n\t\t\t\t{/if}\n\t\t\t\t{#if targetLanguages.length > 0}\n\t\t\t\t\t{$t.translate?.preview?.languages_count?.replace('{count}', targetLanguages.length)}\n\t\t\t\t{/if}\n\t\t\t
\n\t\t\t
\n\t\t\t\t{#if pendingCount > 0}\n\t\t\t\t\t\n\t\t\t\t\t\t{$t.translate?.preview?.approve_all}\n\t\t\t\t\t\n\t\t\t\t{/if}\n\t\t\t\t\n\t\t\t\t\t{$t.translate?.preview?.re_run}\n\t\t\t\t\n\t\t\t
\n\t\t
\n\n\t\t\n\t\t
\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t{#each targetLanguages as lang}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t{#each records as row, idx}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{#each targetLanguages as lang}\n\t\t\t\t\t\t\t\t{@const langKey = `${row.id}_${lang}`}\n\t\t\t\t\t\t\t\t{@const langVal = getLangValue(row, lang)}\n\t\t\t\t\t\t\t\t{@const langStatus = getLangStatus(row, lang)}\n\t\t\t\t\t\t\t\t{@const isEditing = editingCells[langKey]}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t{/each}\n\t\t\t\t\n\t\t\t
#{$t.translate?.preview?.table_source}{$t.translate?.preview?.detected_language}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t{lang}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
{$t.translate?.preview?.table_status}
{idx + 1}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t{row.source_sql || $t.translate?.preview?.empty_placeholder}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{getDetectedLang(row)}\n\t\t\t\t\t\t\t\t{#if getDetectedLang(row) === 'und'}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{#if isEditing}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t saveLangEdit(row.id, lang)}\n\t\t\t\t\t\t\t\t\t\t\t\tclass=\"px-2 py-0.5 text-xs bg-blue-600 text-white rounded hover:bg-blue-700\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.preview?.save_edit}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t cancelLangEdit(row.id, lang)}\n\t\t\t\t\t\t\t\t\t\t\t\tclass=\"px-2 py-0.5 text-xs border border-gray-300 text-gray-600 rounded hover:bg-gray-50\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.preview?.cancel_edit}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t{langVal || $t.translate?.preview?.pending_placeholder}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t{#if langStatus !== 'approved' && langStatus !== 'edited'}\n\t\t\t\t\t\t\t\t\t\t\t\t approveRow(jobId, row.id, lang)}\n\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"px-1.5 py-0.5 text-xs bg-green-100 text-green-700 rounded hover:bg-green-200 transition-colors\"\n\t\t\t\t\t\t\t\t\t\t\t\t\ttitle={$t.translate?.preview?.approve}\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.preview?.approve}\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t\t startLangEdit(row.id, lang)}\n\t\t\t\t\t\t\t\t\t\t\t\tclass=\"px-1.5 py-0.5 text-xs bg-blue-100 text-blue-700 rounded hover:bg-blue-200 transition-colors\"\n\t\t\t\t\t\t\t\t\t\t\t\ttitle={$t.translate?.preview?.edit}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.preview?.edit}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t{#if langStatus !== 'rejected'}\n\t\t\t\t\t\t\t\t\t\t\t\t rejectRow(jobId, row.id, lang)}\n\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"px-1.5 py-0.5 text-xs bg-red-100 text-red-700 rounded hover:bg-red-200 transition-colors\"\n\t\t\t\t\t\t\t\t\t\t\t\t\ttitle={$t.translate?.preview?.reject}\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.preview?.reject}\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{row.status}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t{#if row.status !== 'APPROVED'}\n\t\t\t\t\t\t\t\t\t\t\t handleApprove(row.id)}\n\t\t\t\t\t\t\t\t\t\t\t\tclass=\"px-1.5 py-0.5 text-xs bg-green-100 text-green-700 rounded hover:bg-green-200 transition-colors\"\n\t\t\t\t\t\t\t\t\t\t\t\ttitle={$t.translate?.preview?.approve_all}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.preview?.approve}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t{#if row.status !== 'REJECTED'}\n\t\t\t\t\t\t\t\t\t\t\t handleReject(row.id)}\n\t\t\t\t\t\t\t\t\t\t\t\tclass=\"px-1.5 py-0.5 text-xs bg-red-100 text-red-700 rounded hover:bg-red-200 transition-colors\"\n\t\t\t\t\t\t\t\t\t\t\t\ttitle={$t.translate?.preview?.reject}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.preview?.reject}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
\n\t\t
\n\n\t\t\n\t\t
\n\t\t\t
\n\t\t\t\t

{$t.translate?.preview?.quality_gate}

\n\t\t\t\t

\n\t\t\t\t\t{isAllApproved ? $t.translate?.preview?.quality_gate_ready : $t.translate?.preview?.quality_gate_pending}\n\t\t\t\t

\n\t\t\t
\n\t\t\t\n\t\t\t\t{isAccepting ? $t.translate?.preview?.accepting : $t.translate?.preview?.accept_preview}\n\t\t\t\n\t\t
\n\n\t\n\t{:else if uxState === 'accepted'}\n\t\t
\n\t\t\t
\n\t\t\t

{$t.translate?.preview?.accepted_title}

\n\t\t\t

\n\t\t\t\t{$t.translate?.preview?.accepted_body}\n\t\t\t

\n\t\t\t\n\t\t\t\t{$t.translate?.preview?.run_preview_again}\n\t\t\t\n\t\t
\n\t{/if}\n
\n\n" + "body": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\tlet uxState = $state('idle');\n\tlet session = $state(null);\n\tlet records = $state([]);\n\tlet targetLanguages = $state([]);\n\tlet costEstimate = $state(null);\n\tlet errorMessage = $state('');\n\tlet sampleSize = $state(10);\n\tlet isAccepting = $state(false);\n\n\t// Per-language editing state: { `${rowId}_${langCode}`: true }\n\tlet editingCells = $state({});\n\tlet editValues = $state({});\n\n\t// Derived\n\tlet approvedCount = $derived(records.filter(r => r.status === 'APPROVED').length);\n\tlet rejectedCount = $derived(records.filter(r => r.status === 'REJECTED').length);\n\tlet pendingCount = $derived(records.filter(r => r.status === 'PENDING').length);\n\tlet isAllApproved = $derived(pendingCount === 0 && records.length > 0);\n\n\tfunction getRowStatusLabel(status) {\n\t\tconst labels = {\n\t\t\tAPPROVED: $t.translate?.preview?.status_approved || 'Approved',\n\t\t\tREJECTED: $t.translate?.preview?.status_rejected || 'Rejected',\n\t\t\tPENDING: $t.translate?.preview?.status_pending || 'Pending',\n\t\t};\n\t\treturn labels[status] || status;\n\t}\n\n\t/** Get language status for a record and language code */\n\tfunction getLangStatus(record, langCode) {\n\t\tconst lang = (record.languages || []).find(l => l.language_code === langCode);\n\t\treturn lang ? lang.status : 'pending';\n\t}\n\n\t/** Get translated value for a record and language code */\n\tfunction getLangValue(record, langCode) {\n\t\tconst lang = (record.languages || []).find(l => l.language_code === langCode);\n\t\treturn lang ? (lang.user_edit || lang.final_value || lang.translated_value || '') : '';\n\t}\n\n\t/** Get detected language for a record */\n\tfunction getDetectedLang(record) {\n\t\tif (record.source_language_detected && record.source_language_detected !== 'und') {\n\t\t\treturn record.source_language_detected;\n\t\t}\n\t\tconst langs = record.languages || [];\n\t\tfor (const l of langs) {\n\t\t\tif (l.source_language_detected && l.source_language_detected !== 'und') {\n\t\t\t\treturn l.source_language_detected;\n\t\t\t}\n\t\t}\n\t\treturn 'und';\n\t}\n\n\t/** @returns {Promise} */\n\tasync function handlePreview() {\n\t\tuxState = 'loading';\n\t\terrorMessage = '';\n\t\ttry {\n\t\t\tconst result = await fetchPreview(jobId, sampleSize, environmentId);\n\t\t\tsession = result;\n\t\t\trecords = (result.records || []).map(r => ({ ...r, _isEdited: false }));\n\t\t\ttargetLanguages = result.target_languages || [];\n\t\t\tcostEstimate = result.cost_estimate || null;\n\t\t\tuxState = 'preview_loaded';\n\t\t\taddToast($t.translate?.preview?.preview_loaded?.replace('{count}', records.length), 'success');\n\t\t} catch (err) {\n\t\t\terrorMessage = err?.message || $t.translate?.preview?.preview_failed;\n\t\t\tuxState = 'preview_error';\n\t\t\taddToast(errorMessage, 'error');\n\t\t}\n\t}\n\n\t/** @param {string} rowId */\n\tasync function handleApprove(rowId) {\n\t\ttry {\n\t\t\tconst updated = await approveRow(jobId, rowId);\n\t\t\trecords = records.map(r => r.id === rowId ? {\n\t\t\t\t...r,\n\t\t\t\tstatus: updated.status || 'APPROVED',\n\t\t\t\ttarget_sql: updated.target_sql || r.target_sql,\n\t\t\t\tlanguages: updated.languages || r.languages,\n\t\t\t\t_isEdited: false\n\t\t\t} : r);\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || $t.translate?.preview?.approve_failed, 'error');\n\t\t}\n\t}\n\n\t/** @param {string} rowId */\n\tasync function handleReject(rowId) {\n\t\ttry {\n\t\t\tconst updated = await rejectRow(jobId, rowId);\n\t\t\trecords = records.map(r => r.id === rowId ? {\n\t\t\t\t...r,\n\t\t\t\tstatus: updated.status || 'REJECTED',\n\t\t\t\tlanguages: updated.languages || r.languages,\n\t\t\t\t_isEdited: false\n\t\t\t} : r);\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || $t.translate?.preview?.reject_failed, 'error');\n\t\t}\n\t}\n\n\t/** @param {string} rowId @param {string} langCode */\n\tasync function handleApproveLanguage(rowId, langCode) {\n\t\ttry {\n\t\t\tconst updated = await approveRow(jobId, rowId, langCode);\n\t\t\trecords = records.map(r => r.id === rowId ? {\n\t\t\t\t...r,\n\t\t\t\tstatus: updated.status || r.status,\n\t\t\t\ttarget_sql: updated.target_sql || r.target_sql,\n\t\t\t\tlanguages: updated.languages || r.languages,\n\t\t\t\t_isEdited: false\n\t\t\t} : r);\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || $t.translate?.preview?.approve_failed, 'error');\n\t\t}\n\t}\n\n\t/** @param {string} rowId @param {string} langCode */\n\tasync function handleRejectLanguage(rowId, langCode) {\n\t\ttry {\n\t\t\tconst updated = await rejectRow(jobId, rowId, langCode);\n\t\t\trecords = records.map(r => r.id === rowId ? {\n\t\t\t\t...r,\n\t\t\t\tstatus: updated.status || r.status,\n\t\t\t\tlanguages: updated.languages || r.languages,\n\t\t\t\t_isEdited: false\n\t\t\t} : r);\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || $t.translate?.preview?.reject_failed, 'error');\n\t\t}\n\t}\n\n\t/** @param {string} rowId @param {string} langCode */\n\tfunction startLangEdit(rowId, langCode) {\n\t\tconst key = `${rowId}_${langCode}`;\n\t\teditingCells = { ...editingCells, [key]: true };\n\t\teditValues = { ...editValues, [key]: getLangValue(records.find(r => r.id === rowId), langCode) };\n\t}\n\n\t/** @param {string} rowId @param {string} langCode */\n\tasync function saveLangEdit(rowId, langCode) {\n\t\tconst key = `${rowId}_${langCode}`;\n\t\tconst value = (editValues[key] || '').trim();\n\t\tif (!value) return;\n\t\ttry {\n\t\t\tconst updated = await editRow(jobId, rowId, value, langCode);\n\t\t\trecords = records.map(r =>\n\t\t\t\tr.id === rowId\n\t\t\t\t\t? {\n\t\t\t\t\t\t...r,\n\t\t\t\t\t\tstatus: updated.status || r.status,\n\t\t\t\t\t\ttarget_sql: updated.target_sql || r.target_sql,\n\t\t\t\t\t\tlanguages: updated.languages || r.languages,\n\t\t\t\t\t\t_isEdited: true\n\t\t\t\t\t}\n\t\t\t\t\t: r\n\t\t\t);\n\t\t\tconst newEditing = { ...editingCells };\n\t\t\tdelete newEditing[key];\n\t\t\teditingCells = newEditing;\n\t\t\tconst newValues = { ...editValues };\n\t\t\tdelete newValues[key];\n\t\t\teditValues = newValues;\n\t\t\taddToast($t.translate?.preview?.row_updated, 'success');\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || $t.translate?.preview?.edit_failed, 'error');\n\t\t}\n\t}\n\n\t/** @param {string} rowId @param {string} langCode */\n\tfunction cancelLangEdit(rowId, langCode) {\n\t\tconst key = `${rowId}_${langCode}`;\n\t\tconst newEditing = { ...editingCells };\n\t\tdelete newEditing[key];\n\t\teditingCells = newEditing;\n\t\tconst newValues = { ...editValues };\n\t\tdelete newValues[key];\n\t\teditValues = newValues;\n\t}\n\n\tasync function handleBulkApprove() {\n\t\tfor (const row of records) {\n\t\t\tif (row.status === 'PENDING') {\n\t\t\t\tawait handleApprove(row.id);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync function handleAccept() {\n\t\tisAccepting = true;\n\t\ttry {\n\t\t\tconst result = await acceptPreview(jobId);\n\t\t\tuxState = 'accepted';\n\t\t\tonAccept();\n\t\t\taddToast($t.translate?.preview?.accepted_body, 'success');\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || $t.translate?.preview?.accept_failed, 'error');\n\t\t} finally {\n\t\t\tisAccepting = false;\n\t\t}\n\t}\n\n\n
\n\t\n\t
\n\t\t

{$t.translate?.preview?.title}

\n\t\t{#if uxState === 'preview_loaded'}\n\t\t\t\n\t\t\t\t{session?.status === 'APPLIED' ? $t.translate?.preview?.accepted_badge : $t.translate?.preview?.active_badge}\n\t\t\t\n\t\t{/if}\n\t
\n\n\t\n\t{#if uxState === 'idle'}\n\t\t
\n\t\t\t

\n\t\t\t\t{$t.translate?.preview?.title} — {$t.translate?.preview?.sample_size} {sampleSize}\n\t\t\t

\n\t\t\t
\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t{sampleSize}\n\t\t\t
\n\t\t\t{#if sampleSize > 30}\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{($t.translate?.preview?.cost_warning) || 'Large sample size may incur higher costs'}\n\t\t\t\t
\n\t\t\t{/if}\n\t\t\t\n\t\t\t\t{$t.translate?.preview?.run_preview}\n\t\t\t\n\t\t
\n\n\t\n\t{:else if uxState === 'loading'}\n\t\t
\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t{$t.translate?.preview?.running_preview}\n\t\t\t
\n\t\t\t
\n\t\t\t\t{#each Array(3) as _}\n\t\t\t\t\t
\n\t\t\t\t{/each}\n\t\t\t
\n\t\t
\n\n\t\n\t{:else if uxState === 'preview_error'}\n\t\t
\n\t\t\t

{errorMessage}

\n\t\t\t
\n\t\t\t\t\n\t\t\t\t\t{$t.translate?.preview?.retry_preview}\n\t\t\t\t\n\t\t\t\t\n\t\t\t
\n\t\t
\n\n\t\n\t{:else if uxState === 'preview_loaded'}\n\t\t\n\t\t{#if costEstimate}\n\t\t\t
\n\t\t\t\t

{$t.translate?.preview?.cost_estimate}

\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t{$t.translate?.preview?.sample_rows}\n\t\t\t\t\t\t{costEstimate.sample_size}\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t{$t.translate?.preview?.sample_tokens}\n\t\t\t\t\t\t{costEstimate.sample_total_tokens?.toLocaleString()}\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t{$t.translate?.preview?.sample_cost}\n\t\t\t\t\t\t${costEstimate.sample_cost?.toFixed(6)}\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t{$t.translate?.preview?.est_total_cost}\n\t\t\t\t\t\t${costEstimate.estimated_cost?.toFixed(6)}\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\n\t\t\t\t

\n\t\t\t\t\t{$t.translate?.preview?.across_languages?.replace('{count}', costEstimate.num_languages || targetLanguages.length || 1)}\n\t\t\t\t

\n\t\t\t\t\n\t\t\t\t{#if costEstimate.warning}\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t{costEstimate.warning}\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\t\t\t
\n\t\t{/if}\n\n\t\t\n\t\t
\n\t\t\t
\n\t\t\t\t{$t.translate?.preview?.rows_count?.replace('{count}', records.length)}\n\t\t\t\t{$t.translate?.preview?.approved_count?.replace('{count}', approvedCount)}\n\t\t\t\t{$t.translate?.preview?.rejected_count?.replace('{count}', rejectedCount)}\n\t\t\t\t{#if pendingCount > 0}\n\t\t\t\t\t{$t.translate?.preview?.pending_count?.replace('{count}', pendingCount)}\n\t\t\t\t{/if}\n\t\t\t\t{#if targetLanguages.length > 0}\n\t\t\t\t\t{$t.translate?.preview?.languages_count?.replace('{count}', targetLanguages.length)}\n\t\t\t\t{/if}\n\t\t\t
\n\t\t\t
\n\t\t\t\t{#if pendingCount > 0}\n\t\t\t\t\t\n\t\t\t\t\t\t{$t.translate?.preview?.approve_all}\n\t\t\t\t\t\n\t\t\t\t{/if}\n\t\t\t\t\n\t\t\t\t\t{$t.translate?.preview?.re_run}\n\t\t\t\t\n\t\t\t
\n\t\t
\n\n\t\t\n\t\t
\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t{#each targetLanguages as lang}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t{#each records as row, idx}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{#each targetLanguages as lang}\n\t\t\t\t\t\t\t\t{@const langKey = `${row.id}_${lang}`}\n\t\t\t\t\t\t\t\t{@const langVal = getLangValue(row, lang)}\n\t\t\t\t\t\t\t\t{@const langStatus = getLangStatus(row, lang)}\n\t\t\t\t\t\t\t\t{@const isEditing = editingCells[langKey]}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t{/each}\n\t\t\t\t\n\t\t\t
#{$t.translate?.preview?.table_source}{$t.translate?.preview?.detected_language}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t{lang}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
{$t.translate?.preview?.table_status}
{idx + 1}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t{row.source_sql || $t.translate?.preview?.empty_placeholder}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{getDetectedLang(row)}\n\t\t\t\t\t\t\t\t{#if getDetectedLang(row) === 'und'}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{#if isEditing}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t saveLangEdit(row.id, lang)}\n\t\t\t\t\t\t\t\t\t\t\t\tclass=\"px-2 py-0.5 text-xs bg-blue-600 text-white rounded hover:bg-blue-700\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.preview?.save_edit}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t cancelLangEdit(row.id, lang)}\n\t\t\t\t\t\t\t\t\t\t\t\tclass=\"px-2 py-0.5 text-xs border border-gray-300 text-gray-600 rounded hover:bg-gray-50\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.preview?.cancel_edit}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t{langVal || $t.translate?.preview?.pending_placeholder}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t{#if langStatus !== 'approved' && langStatus !== 'edited'}\n\t\t\t\t\t\t\t\t\t\t\t\t handleApproveLanguage(row.id, lang)}\n\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"px-1.5 py-0.5 text-xs bg-green-100 text-green-700 rounded hover:bg-green-200 transition-colors\"\n\t\t\t\t\t\t\t\t\t\t\t\t\ttitle={$t.translate?.preview?.approve}\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.preview?.approve}\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t\t startLangEdit(row.id, lang)}\n\t\t\t\t\t\t\t\t\t\t\t\tclass=\"px-1.5 py-0.5 text-xs bg-blue-100 text-blue-700 rounded hover:bg-blue-200 transition-colors\"\n\t\t\t\t\t\t\t\t\t\t\t\ttitle={$t.translate?.preview?.edit}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.preview?.edit}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t{#if langStatus !== 'rejected'}\n\t\t\t\t\t\t\t\t\t\t\t\t handleRejectLanguage(row.id, lang)}\n\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"px-1.5 py-0.5 text-xs bg-red-100 text-red-700 rounded hover:bg-red-200 transition-colors\"\n\t\t\t\t\t\t\t\t\t\t\t\t\ttitle={$t.translate?.preview?.reject}\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.preview?.reject}\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{getRowStatusLabel(row.status)}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t{#if row.status !== 'APPROVED'}\n\t\t\t\t\t\t\t\t\t\t\t handleApprove(row.id)}\n\t\t\t\t\t\t\t\t\t\t\t\tclass=\"px-1.5 py-0.5 text-xs bg-green-100 text-green-700 rounded hover:bg-green-200 transition-colors\"\n\t\t\t\t\t\t\t\t\t\t\t\ttitle={$t.translate?.preview?.approve_all}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.preview?.approve}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t{#if row.status !== 'REJECTED'}\n\t\t\t\t\t\t\t\t\t\t\t handleReject(row.id)}\n\t\t\t\t\t\t\t\t\t\t\t\tclass=\"px-1.5 py-0.5 text-xs bg-red-100 text-red-700 rounded hover:bg-red-200 transition-colors\"\n\t\t\t\t\t\t\t\t\t\t\t\ttitle={$t.translate?.preview?.reject}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.preview?.reject}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
\n\t\t
\n\n\t\t\n\t\t
\n\t\t\t
\n\t\t\t\t

{$t.translate?.preview?.quality_gate}

\n\t\t\t\t

\n\t\t\t\t\t{isAllApproved ? $t.translate?.preview?.quality_gate_ready : $t.translate?.preview?.quality_gate_pending}\n\t\t\t\t

\n\t\t\t
\n\t\t\t\n\t\t\t\t{isAccepting ? $t.translate?.preview?.accepting : $t.translate?.preview?.accept_preview}\n\t\t\t\n\t\t
\n\n\t\n\t{:else if uxState === 'accepted'}\n\t\t
\n\t\t\t
\n\t\t\t

{$t.translate?.preview?.accepted_title}

\n\t\t\t

\n\t\t\t\t{$t.translate?.preview?.accepted_body}\n\t\t\t

\n\t\t\t\n\t\t\t\t{$t.translate?.preview?.run_preview_again}\n\t\t\t\n\t\t
\n\t{/if}\n
\n\n" }, { "contract_id": "TranslationRunGlobalIndicator", "contract_type": "Component", "file_path": "frontend/src/lib/components/translate/TranslationRunGlobalIndicator.svelte", "start_line": 1, - "end_line": 139, + "end_line": 203, "tier": "TIER_2", "complexity": 3, "metadata": { "COMPLEXITY": 3, - "LAYER": "UI", - "PURPOSE": "Persistent mini progress indicator for translation runs, rendered in root layout.", - "UX_FEEDBACK": "Click banner navigates to the translation run page", - "UX_STATE": "failed -> Red bar + \"Failed\" banner (auto-hides after 8s)" + "PURPOSE": "Persistent rich progress panel for active translation runs, rendered in root layout.", + "UX_FEEDBACK": "Rich stats during active run; compact auto-dismiss for terminal states", + "UX_STATE": "cancelled -> Compact gray banner with auto-dismiss after 8s" }, "relations": [ { @@ -88576,45 +87624,21 @@ "target_ref": "[translationRunStore]" } ], - "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "LAYER", - "message": "@LAYER is not allowed for contract type 'Component'", - "detail": { - "actual_type": "Component", - "allowed_types": [ - "Module", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "LAYER", - "message": "@LAYER is forbidden for contract type 'Component' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Component" - } - } - ], + "schema_warnings": [], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "\n\n\n\n\n\n\n\n\n\n\n{#if show}\n\t\n\t\t\n\t\t
\n\t\t\t\n\t\t
\n\t\t\n\t\t
\n\t\t\t{label}\n\n\t\t\t{#if uxState === 'running' || uxState === 'inserting'}\n\t\t\t\t\n\t\t\t\t\t{runState.current?.successfulRecords || 0}/{runState.current?.totalRecords || 0}\n\t\t\t\t\n\t\t\t\t{#if (runState.current?.failedRecords || 0) > 0}\n\t\t\t\t\t\n\t\t\t\t\t\t{$t.translate?.run?.failed || 'Failed'}: {runState.current?.failedRecords}\n\t\t\t\t\t\n\t\t\t\t{/if}\n\t\t\t\t\n\t\t\t\t\t▶ {$t.common?.open || 'Open'}\n\t\t\t\t\n\t\t\t{:else if uxState === 'partial'}\n\t\t\t\t\n\t\t\t\t\t{runState.current?.successfulRecords || 0}/{runState.current?.totalRecords || 0}\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t▶ {$t.common?.open || 'Open'}\n\t\t\t\t\n\t\t\t{:else}\n\t\t\t\t\n\t\t\t\t\t▶ {$t.common?.open || 'Open'}\n\t\t\t\t\n\t\t\t{/if}\n\t\t
\n\t
\n{/if}\n\n" + "body": "\n\n\n\n\n\n\n\n\n\n\n\n{#if show}\n\t\n\t\t{#if isActive}\n\t\t\t\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{label}\n\t\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{$t.common?.open || 'Open'}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{isCancelling\n\t\t\t\t\t\t\t\t\t? ($t.translate?.run?.cancelling || 'Cancelling...')\n\t\t\t\t\t\t\t\t\t: ($t.translate?.run?.cancel || 'Cancel')}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\n\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\n\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{($t.translate?.run?.total || 'Total')}\n\t\t\t\t\t\t\t{totalRecords}\n\t\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{($t.translate?.run?.success || 'OK')}\n\t\t\t\t\t\t\t{successfulRecords}\n\t\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{($t.translate?.run?.failed || 'Fail')}\n\t\t\t\t\t\t\t{failedRecords}\n\t\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{($t.translate?.run?.skipped || 'Skip')}\n\t\t\t\t\t\t\t{skippedRecords}\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t
\n\t\t{:else}\n\t\t\t\n\t\t\t\n\t\t\t\t
\n\t\t\t\t\t{#if uxState === 'completed'}\n\t\t\t\t\t\t\n\t\t\t\t\t{:else if uxState === 'partial' || uxState === 'failed'}\n\t\t\t\t\t\t\n\t\t\t\t\t{:else}\n\t\t\t\t\t\t\n\t\t\t\t\t{/if}\n\t\t\t\t\t{label}\n\t\t\t\t\t{#if uxState === 'partial'}\n\t\t\t\t\t\t{successfulRecords}/{totalRecords}\n\t\t\t\t\t{/if}\n\t\t\t\t
\n\t\t\t\t\n\t\t\t\t\t▶ {$t.common?.open || 'Open'}\n\t\t\t\t\n\t\t\t
\n\t\t{/if}\n\t
\n{/if}\n\n" }, { "contract_id": "TranslationRunProgress", "contract_type": "Component", "file_path": "frontend/src/lib/components/translate/TranslationRunProgress.svelte", "start_line": 1, - "end_line": 320, + "end_line": 309, "tier": "TIER_2", "complexity": 3, "metadata": { "COMPLEXITY": 3, - "LAYER": "UI", "POST": "Real-time progress display with two-phase (translation + insert) and state transitions.", "PRE": "runId is a valid translation run ID.", "PURPOSE": "WebSocket-driven progress bar with batch counter, success/failure/skip counts, two-phase display, and cancel button.", @@ -88626,8 +87650,8 @@ { "source_id": "TranslationRunProgress", "relation_type": "DEPENDS_ON", - "target_id": "TranslateApi", - "target_ref": "[TranslateApi]" + "target_id": "api_module", + "target_ref": "[api_module]" }, { "source_id": "TranslationRunProgress", @@ -88637,28 +87661,6 @@ } ], "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "LAYER", - "message": "@LAYER is not allowed for contract type 'Component'", - "detail": { - "actual_type": "Component", - "allowed_types": [ - "Module", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "LAYER", - "message": "@LAYER is forbidden for contract type 'Component' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Component" - } - }, { "code": "tag_forbidden_by_complexity", "tag": "POST", @@ -88680,23 +87682,23 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "\n\n\n\n\n
\n\t{#if uxState === 'idle'}\n\t\t
\n\t\t\t

{$t.translate?.run?.loading}

\n\t\t
\n\n\t{:else if isRunning}\n\t\t
\n\t\t\t\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t{uxState === 'inserting' ? $t.translate?.run?.insert_phase : $t.translate?.run?.translate_phase}\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\n\t\t\t\t\t{isCancelling ? $t.translate?.run?.cancelling : $t.translate?.run?.cancel}\n\t\t\t\t\n\t\t\t
\n\n\t\t\t\n\t\t\t
\n\t\t\t\t\n\t\t\t
\n\n\t\t\t\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.total}\n\t\t\t\t\t

{totalRecords}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.success}\n\t\t\t\t\t

{successfulRecords}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.failed}\n\t\t\t\t\t

{failedRecords}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.skipped}\n\t\t\t\t\t

{skippedRecords}

\n\t\t\t\t
\n\t\t\t
\n\n\t\t\t\n\t\t\t

\n\t\t\t\t{$t.translate?.run?.batches_progress?.replace('{count}', batchCount).replace('{pct}', progressPct)}\n\t\t\t

\n\t\t
\n\n\t\n\t{:else if uxState === 'completed'}\n\t\t
\n\t\t\t
\n\t\t\t\t\n\t\t\t\t{$t.translate?.run?.completed}\n\t\t\t
\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.total}\n\t\t\t\t\t

{successfulRecords} / {totalRecords}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.skipped}\n\t\t\t\t\t

{skippedRecords}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.insert_status?.replace(':', '')}\n\t\t\t\t\t

{insertStatus || $t.translate?.run?.insert_completed}

\n\t\t\t\t
\n\t\t\t
\n\t\t
\n\n\t\n\t{:else if uxState === 'partial'}\n\t\t
\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t{$t.translate?.run?.completed_with_errors}\n\t\t\t\t
\n\t\t\t\t\n\t\t\t\t\t{$t.translate?.run?.retry_failed}\n\t\t\t\t\n\t\t\t
\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.success}\n\t\t\t\t\t

{successfulRecords}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.failed}\n\t\t\t\t\t

{failedRecords}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.skipped}\n\t\t\t\t\t

{skippedRecords}

\n\t\t\t\t
\n\t\t\t
\n\t\t
\n\n\t\n\t{:else if uxState === 'failed'}\n\t\t
\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t{$t.translate?.run?.translation_failed}\n\t\t\t\t
\n\t\t\t\t\n\t\t\t\t\t{$t.translate?.common?.retry}\n\t\t\t\t\n\t\t\t
\n\t\t\t

{status?.error_message || $t.translate?.common?.unknown}

\n\t\t
\n\n\t\n\t{:else if uxState === 'insert_failed'}\n\t\t
\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t{$t.translate?.run?.insert_failed}\n\t\t\t\t
\n\t\t\t\t\n\t\t\t\t\t{$t.translate?.run?.retry_insert}\n\t\t\t\t\n\t\t\t
\n\t\t\t

\n\t\t\t\t{$t.translate?.run?.completed} ({successfulRecords}) — {$t.translate?.run?.insert_failed}\n\t\t\t

\n\t\t
\n\n\t\n\t{:else if uxState === 'cancelled'}\n\t\t
\n\t\t\t
\n\t\t\t\t\n\t\t\t\t{$t.translate?.run?.cancelled}\n\t\t\t
\n\t\t
\n\t{/if}\n
\n\n" + "body": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\t */\n\tlet uxState = $state('idle');\n\tlet status = $state(null);\n\tlet pollingInterval = $state(null);\n\tlet isCancelling = $state(false);\n\tlet pollingStarted = $state(false);\n\t// Safety net: stop polling after 300 attempts (10 min at 2s interval)\n\t// to prevent infinite spinner if the run gets stuck.\n\tlet pollCount = $state(0);\n\tconst MAX_POLLS = 300;\n\n\t// Derived\n\tlet totalRecords = $derived(status?.total_records || 0);\n\tlet successfulRecords = $derived(status?.successful_records || 0);\n\tlet failedRecords = $derived(status?.failed_records || 0);\n\tlet skippedRecords = $derived(status?.skipped_records || 0);\n\tlet progressPct = $derived.by(() => {\n\t\tif (totalRecords === 0) return 0;\n\t\treturn Math.round(((successfulRecords + failedRecords + skippedRecords) / totalRecords) * 100);\n\t});\n\tlet batchCount = $derived(status?.batch_count || 0);\n\tlet insertStatus = $derived(status?.insert_status || null);\n\n\tlet isRunning = $derived(uxState === 'running' || uxState === 'inserting');\n\n\t// Use onMount instead of $effect because $effect cleanup can fire\n\t// unexpectedly during re-renders in Svelte 5, stopping the polling\n\t// interval while leaving uxState as 'running' — the spinner keeps\n\t// spinning forever with no further polls. onMount/onDestroy gives\n\t// deterministic lifecycle: start when the component appears, stop\n\t// only when it is destroyed (currentRunId → null).\n\tonMount(() => {\n\t\tif (runId) {\n\t\t\tpollingStarted = true;\n\t\t\tstartPolling();\n\t\t}\n\t\treturn () => {\n\t\t\tstopPolling();\n\t\t};\n\t});\n\n\tfunction startPolling() {\n\t\tstopPolling();\n\t\tpollingInterval = setInterval(pollStatus, 2000);\n\t\tpollStatus();\n\t}\n\n\tfunction stopPolling() {\n\t\tif (pollingInterval) {\n\t\t\tclearInterval(pollingInterval);\n\t\t\tpollingInterval = null;\n\t\t}\n\t}\n\n\t/** @returns {Promise} */\n\tasync function pollStatus() {\n\t\t// Safety net: stop polling after MAX_POLLS attempts\n\t\tpollCount++;\n\t\tif (pollCount > MAX_POLLS) {\n\t\t\tconsole.warn('[TranslationRunProgress] Max polls reached, stopping');\n\t\t\tstopPolling();\n\t\t\tuxState = 'failed';\n\t\t\tonComplete({ status: 'TIMEOUT', error_message: 'Translation run timed out' });\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tconst data = await fetchRunStatus(runId);\n\t\t\tstatus = data;\n\n\t\t\t// Determine state from status\n\t\t\tconst s = data?.status;\n\t\t\tconst insertS = data?.insert_status;\n\n\t\t\tif (s === 'PENDING' || s === 'RUNNING') {\n\t\t\t\tif (insertS === 'started' || insertS === 'pending' || insertS === 'running') {\n\t\t\t\t\tuxState = 'inserting';\n\t\t\t\t} else {\n\t\t\t\t\tuxState = 'running';\n\t\t\t\t}\n\t\t\t} else if (s === 'COMPLETED') {\n\t\t\t\tif (insertS === 'failed' || insertS === 'timeout') {\n\t\t\t\t\tuxState = 'insert_failed';\n\t\t\t\t} else if (data.failed_records > 0) {\n\t\t\t\t\tuxState = 'partial';\n\t\t\t\t} else {\n\t\t\t\t\tuxState = 'completed';\n\t\t\t\t}\n\t\t\t\tstopPolling();\n\t\t\t\tonComplete(data);\n\t\t\t} else if (s === 'FAILED') {\n\t\t\t\tuxState = 'failed';\n\t\t\t\tstopPolling();\n\t\t\t\tonComplete(data);\n\t\t\t} else if (s === 'CANCELLED') {\n\t\t\t\tuxState = 'cancelled';\n\t\t\t\tstopPolling();\n\t\t\t\tonComplete(data);\n\t\t\t} else {\n\t\t\t\t// Unknown status — log and keep polling\n\t\t\t\tconsole.warn('[TranslationRunProgress] Unknown status:', s);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.warn('[TranslationRunProgress] Poll error:', err);\n\t\t}\n\t}\n\n\t/** @returns {Promise} */\n\tasync function handleCancel() {\n\t\tisCancelling = true;\n\t\ttry {\n\t\t\tawait cancelRun(runId);\n\t\t\tuxState = 'cancelled';\n\t\t\tstopPolling();\n\t\t\t// Notify the parent page that the run is complete so it resets\n\t\t\t// isRunning and hides the emit-processing UI. Without this, the\n\t\t\t// page-level isRunning stays `true` and the store's independent\n\t\t\t// polling (translationRunStore) triggers a SECOND onComplete\n\t\t\t// callback, causing duplicate toasts and state thrashing.\n\t\t\tonComplete({ status: 'CANCELLED', error_message: null });\n\t\t\taddToast($t.translate?.run?.run_cancelled, 'info');\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || $t.translate?.run?.cancel_failed, 'error');\n\t\t} finally {\n\t\t\tisCancelling = false;\n\t\t}\n\t}\n\n\n
\n\t{#if uxState === 'idle'}\n\t\t
\n\t\t\t

{$t.translate?.run?.loading}

\n\t\t
\n\n\t{:else if isRunning}\n\t\t
\n\t\t\t\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t{uxState === 'inserting' ? $t.translate?.run?.insert_phase : $t.translate?.run?.translate_phase}\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\n\t\t\t\t\t{isCancelling ? $t.translate?.run?.cancelling : $t.translate?.run?.cancel}\n\t\t\t\t\n\t\t\t
\n\n\t\t\t\n\t\t\t
\n\t\t\t\t\n\t\t\t
\n\n\t\t\t\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.total}\n\t\t\t\t\t

{totalRecords}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.success}\n\t\t\t\t\t

{successfulRecords}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.failed}\n\t\t\t\t\t

{failedRecords}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.skipped}\n\t\t\t\t\t

{skippedRecords}

\n\t\t\t\t
\n\t\t\t
\n\n\t\t\t\n\t\t\t

\n\t\t\t\t{$t.translate?.run?.batches_progress?.replace('{count}', batchCount).replace('{pct}', progressPct)}\n\t\t\t

\n\t\t
\n\n\t\n\t{:else if uxState === 'completed'}\n\t\t
\n\t\t\t
\n\t\t\t\t\n\t\t\t\t{$t.translate?.run?.completed}\n\t\t\t
\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.total}\n\t\t\t\t\t

{successfulRecords} / {totalRecords}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.skipped}\n\t\t\t\t\t

{skippedRecords}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.insert_status?.replace(':', '')}\n\t\t\t\t\t

{insertStatus || $t.translate?.run?.insert_completed}

\n\t\t\t\t
\n\t\t\t
\n\t\t
\n\n\t\n\t{:else if uxState === 'partial'}\n\t\t
\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t{$t.translate?.run?.completed_with_errors}\n\t\t\t\t
\n\t\t\t\t\n\t\t\t\t\t{$t.translate?.run?.retry_failed}\n\t\t\t\t\n\t\t\t
\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.success}\n\t\t\t\t\t

{successfulRecords}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.failed}\n\t\t\t\t\t

{failedRecords}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{$t.translate?.run?.skipped}\n\t\t\t\t\t

{skippedRecords}

\n\t\t\t\t
\n\t\t\t
\n\t\t
\n\n\t\n\t{:else if uxState === 'failed'}\n\t\t
\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t{$t.translate?.run?.translation_failed}\n\t\t\t\t
\n\t\t\t\t\n\t\t\t\t\t{$t.translate?.common?.retry}\n\t\t\t\t\n\t\t\t
\n\t\t\t

{status?.error_message || $t.translate?.common?.unknown}

\n\t\t
\n\n\t\n\t{:else if uxState === 'insert_failed'}\n\t\t
\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t{$t.translate?.run?.insert_failed}\n\t\t\t\t
\n\t\t\t\t\n\t\t\t\t\t{$t.translate?.run?.retry_insert}\n\t\t\t\t\n\t\t\t
\n\t\t\t

\n\t\t\t\t{$t.translate?.run?.completed} ({successfulRecords}) — {$t.translate?.run?.insert_failed}\n\t\t\t

\n\t\t
\n\n\t\n\t{:else if uxState === 'cancelled'}\n\t\t
\n\t\t\t
\n\t\t\t\t\n\t\t\t\t{$t.translate?.run?.cancelled}\n\t\t\t
\n\t\t
\n\t{/if}\n
\n\n" }, { "contract_id": "TranslationRunResult", "contract_type": "Component", "file_path": "frontend/src/lib/components/translate/TranslationRunResult.svelte", "start_line": 1, - "end_line": 510, + "end_line": 603, "tier": "TIER_2", "complexity": 4, "metadata": { "COMPLEXITY": "4", - "LAYER": "UI", "POST": "Results displayed with actions for retry, SQL audit, and Superset reference.", "PRE": "runId is a valid completed/failed/pending run.", "PURPOSE": "Run result display with statistics, insert status badge, Superset query reference, SQL audit block, and retry buttons.", "TASK": "connect_orphaned_components", + "TYPE": "{'completed'|'partial'|'failed'|'insert_failed'}", "UX_FEEDBACK": "Tabular statistics; click to copy Superset query ID; collapsible SQL block.", "UX_RECOVERY": "Retry failed batches; retry insert.", "UX_STATE": "insert_failed -> Insert phase failed, retry-insert available" @@ -88717,8 +87719,8 @@ { "source_id": "TranslationRunResult", "relation_type": "DEPENDS_ON", - "target_id": "TranslateApi", - "target_ref": "[TranslateApi]" + "target_id": "api_module", + "target_ref": "[api_module]" }, { "source_id": "TranslationRunResult", @@ -88728,34 +87730,18 @@ } ], "schema_warnings": [ - { - "code": "tag_not_for_contract_type", - "tag": "LAYER", - "message": "@LAYER is not allowed for contract type 'Component'", - "detail": { - "actual_type": "Component", - "allowed_types": [ - "Module", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "LAYER", - "message": "@LAYER is forbidden for contract type 'Component' at C4", - "detail": { - "actual_complexity": 4, - "contract_type": "Component" - } - }, { "code": "unknown_tag", "tag": "TASK", "message": "@TASK is not defined in axiom_config.yaml tags", "detail": null }, + { + "code": "unknown_tag", + "tag": "TYPE", + "message": "@TYPE is not defined in axiom_config.yaml tags", + "detail": null + }, { "code": "missing_required_tag", "tag": "SIDE_EFFECT", @@ -88768,7 +87754,7 @@ ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\t{#if !status}\n\t\t
\n\t\t\t

{$t.translate?.run?.loading_result}

\n\t\t
\n\t{:else}\n\t\t
\n\t\t\t\n\t\t\t
\n\t\t\t\t

{$t.translate?.run?.result_title}

\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t{#if uxState === 'failed' || uxState === 'partial'}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{isRetrying ? $t.translate?.run?.retrying : $t.translate?.run?.retry_failed}\n\t\t\t\t\t\t\n\t\t\t\t\t{/if}\n\t\t\t\t\t{#if uxState === 'insert_failed'}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{isRetryingInsert ? $t.translate?.run?.retrying_insert : $t.translate?.run?.retry_insert}\n\t\t\t\t\t\t\n\t\t\t\t\t{/if}\n\t\t\t\t\t showBulkReplace = true}\n\t\t\t\t\t\tclass=\"px-3 py-1.5 text-xs bg-indigo-600 text-white rounded hover:bg-indigo-700 transition-colors\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{$t.translate?.run?.bulk_replace || 'Bulk Replace'}\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t
\n\n\t\t\t\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t

{$t.translate?.run?.total_records}

\n\t\t\t\t\t

{status.total_records || 0}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t

{$t.translate?.run?.success}

\n\t\t\t\t\t

{status.successful_records || 0}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t

{$t.translate?.run?.failed}

\n\t\t\t\t\t

{status.failed_records || 0}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t

{$t.translate?.run?.skipped}

\n\t\t\t\t\t

{status.skipped_records || 0}

\n\t\t\t\t
\n\t\t\t
\n\n\t\t\t\n\t\t\t{#if status.language_stats && status.language_stats.length > 0}\n\t\t\t\t
\n\t\t\t\t\t

{$t.translate?.run?.per_language ?? 'Per-Language Statistics'}

\n\t\t\t\t\t
\n\t\t\t\t\t\t{#each status.language_stats as lang}\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t

{lang.language_code}

\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t{lang.translated_rows}\n\t\t\t\t\t\t\t\t\t{#if lang.failed_rows > 0}\n\t\t\t\t\t\t\t\t\t\t{lang.failed_rows}\n\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t{#if lang.skipped_rows > 0}\n\t\t\t\t\t\t\t\t\t\t{lang.skipped_rows}\n\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t{lang.total_rows}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t{/if}\n\n\t\t\t\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t{$t.translate?.run?.run_id}\n\t\t\t\t\t\t{status.id}\n\t\t\t\t\t\t copyToClipboard(status.id)}\n\t\t\t\t\t\t\tclass=\"ml-1 text-blue-500 hover:text-blue-700 text-xs\"\n\t\t\t\t\t\t\ttitle={$t.translate?.run?.copy_id}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{$t.translate?.run?.copy_id}\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t{$t.translate?.run?.insert_status}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{insertStatusBadge.label}\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t{#if status.superset_execution_id}\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{$t.translate?.run?.superset_query}\n\t\t\t\t\t\t\t{status.superset_execution_id}\n\t\t\t\t\t\t\t copyToClipboard(status.superset_execution_id)}\n\t\t\t\t\t\t\t\tclass=\"ml-1 text-blue-500 hover:text-blue-700 text-xs\"\n\t\t\t\t\t\t\t\ttitle={$t.translate?.run?.copy_id}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{$t.translate?.run?.copy_id}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t{/if}\n\t\t\t\t\t{#if status.error_message}\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{$t.translate?.run?.error_label?.replace('{error}', status.error_message)}\n\t\t\t\t\t\t
\n\t\t\t\t\t{/if}\n\t\t\t\t
\n\t\t\t
\n\n\t\t\t\n\t\t\t
\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{$t.translate?.run?.sql_audit?.replace('{count}', sqlAuditLines.length)}\n\t\t\t\t\n\n\t\t\t\t{#if showSqlAudit}\n\t\t\t\t\t
\n\t\t\t\t\t\t{#if sqlAuditLines.length === 0}\n\t\t\t\t\t\t\t

{$t.translate?.run?.no_sql_audit}

\n\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t{#each sqlAuditLines as line, idx}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t{idx + 1}. {line}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\t\t\t
\n\n\t\t\t\n\t\t\t{#if status.event_invariants}\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t{$t.translate?.run?.event_invariants}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{status.event_invariants.invariant_valid ? $t.translate?.run?.valid : $t.translate?.run?.violated}\n\t\t\t\t\t\t\n\t\t\t\t\t\t|\n\t\t\t\t\t\t{$t.translate?.run?.superset_query_id_label} {status.event_invariants.has_run_started ? $t.translate?.run?.started_yes : $t.translate?.run?.started_no}\n\t\t\t\t\t\t|\n\t\t\t\t\t\t{$t.translate?.run?.terminal_events?.replace('{count}', status.event_invariants.terminal_event_count)}\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t{/if}\n\n\t\t\t\n\t\t\t{#if records.length > 0}\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t showRecords = !showRecords}\n\t\t\t\t\t\t\tclass=\"flex items-center gap-2 text-sm text-gray-700 hover:text-gray-900\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{$t.translate?.run?.records_title || 'Translation Records'} ({records.length})\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\n\t\t\t\t\t{#if showRecords}\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{#each targetLanguages as lang}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\t\t\t{#if targetLanguages.length === 0}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{#each records as row, idx}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t{#if targetLanguages.length > 0}\n\t\t\t\t\t\t\t\t\t\t\t\t{#each targetLanguages as lang}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{@const langData = (row.languages || []).find(l => l.language_code === lang)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{@const cellValue = langData?.final_value || langData?.translated_value || ''}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{@const detectedSource = langData?.source_language_detected || row.source_language_detected || ''}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
#{$t.translate?.preview?.table_source || 'Source'}\n\t\t\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t{lang}\n\t\t\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t
{$t.translate?.preview?.translation || 'Translation'}{$t.translate?.preview?.table_status || 'Status'}{$t.translate?.preview?.table_actions || 'Actions'}
{idx + 1}\n\t\t\t\t\t\t\t\t\t\t\t\t{row.source_sql || row.source_object_name || '—'}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t{row.status}\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst firstLang = row.languages?.[0] || {};\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcorrectionPopupData = {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsourceTerm: row.source_sql || row.source_object_name || '',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tincorrectTarget: firstLang?.final_value || firstLang?.translated_value || '',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsourceLanguage: firstLang?.source_language_detected || row.source_language_detected || '',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttargetLanguage: targetLanguages[0] || '',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\trunId,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\trowKey: row.id\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"px-2 py-0.5 text-[10px] bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttitle=\"Submit Correction\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.run?.correct || 'Correct'}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst firstLang = row.languages?.[0] || {};\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst item = {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsourceTerm: row.source_sql || row.source_object_name || '',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tincorrectTarget: firstLang?.final_value || firstLang?.translated_value || '',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\trowKey: row.id\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst exists = bulkCorrectionItems.some(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ti => i.sourceTerm === item.sourceTerm && i.incorrectTarget === item.incorrectTarget\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (!exists) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tbulkCorrectionItems = [...bulkCorrectionItems, item];\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"px-2 py-0.5 text-[10px] bg-purple-600 text-white rounded hover:bg-purple-700 transition-colors\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttitle=\"Collect for bulk correction\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.run?.collect || 'Collect'}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t{/if}\n\t\t\t\t
\n\t\t\t{/if}\n\t\t
\n\t{/if}\n
\n\n\n correctionPopupData = null}\n\tonSubmitted={() => { correctionPopupData = null; loadData(); onRefresh(); }}\n/>\n\n showBulkReplace = false}\n\tonApplied={(count) => { showBulkReplace = false; loadData(); onRefresh(); }}\n/>\n\n bulkCorrectionItems = []}\n\tonSubmitted={() => { bulkCorrectionItems = []; loadData(); onRefresh(); }}\n/>\n\n" + "body": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\t */\n\n\timport { t } from '$lib/i18n';\n\timport { addToast } from '$lib/toasts.js';\n\timport {\n\t\tfetchRunStatus,\n\t\tfetchRunRecords,\n\t\tretryFailedBatches,\n\t\tretryInsert,\n\t\tfetchRunBatches\n\t} from '$lib/api/translate.js';\n\timport CorrectionCell from './CorrectionCell.svelte';\n\timport TermCorrectionPopup from './TermCorrectionPopup.svelte';\n\timport BulkReplaceModal from './BulkReplaceModal.svelte';\n\n\t/** @type {{ runId: string, onRefresh: Function }} */\n\tlet { runId, onRefresh = () => {} } = $props();\n\n\t/**\n\t * @type {'completed'|'partial'|'failed'|'insert_failed'}\n\t */\n\tlet uxState = $state('completed');\n\tlet status = $state(null);\n\tlet records = $state([]);\n\tlet batches = $state([]);\n\tlet showRecords = $state(false);\n\tlet showSqlAudit = $state(false);\n\tlet isRetrying = $state(false);\n\tlet isRetryingInsert = $state(false);\n\tlet sqlAuditLines = $state([]);\n\tlet targetLanguages = $state([]);\n\tlet correctionPopupData = $state(null);\n\tlet showBulkReplace = $state(false);\n\n\t// Pagination & filter state\n\tlet currentPage = $state(1);\n\tlet pageSize = $state(25);\n\tlet totalRecords = $state(0);\n\tlet statusFilter = $state('');\n\n\tlet totalPages = $derived(totalRecords > 0 ? Math.ceil(totalRecords / pageSize) : 1);\n\tlet recordStart = $derived(totalRecords > 0 ? (currentPage - 1) * pageSize + 1 : 0);\n\tlet recordEnd = $derived(Math.min(currentPage * pageSize, totalRecords));\n\n\tlet visiblePages = $derived.by(() => {\n\t\tif (totalPages <= 7) {\n\t\t\treturn Array.from({ length: totalPages }, (_, i) => i + 1);\n\t\t}\n\t\tconst half = 3;\n\t\tlet start = Math.max(1, currentPage - half);\n\t\tlet end = Math.min(totalPages, currentPage + half);\n\t\tif (start === 1) end = Math.min(totalPages, start + 6);\n\t\tif (end === totalPages) start = Math.max(1, end - 6);\n\t\tconst pages = [];\n\t\tfor (let p = start; p <= end; p++) pages.push(p);\n\t\treturn pages;\n\t});\n\n\tconst STATUS_FILTERS = [\n\t\t{ value: '', labelKey: 'translate.run.filter_all', label: 'All' },\n\t\t{ value: 'FAILED', labelKey: 'translate.run.translation_failed', label: 'Failed' },\n\t\t{ value: 'SUCCESS', labelKey: 'translate.run.success', label: 'Success' },\n\t\t{ value: 'SKIPPED', labelKey: 'translate.run.skipped', label: 'Skipped' },\n\t];\n\n\tfunction getRunStatusLabel(value) {\n\t\tconst labels = {\n\t\t\tCOMPLETED: $t.translate?.run?.completed || 'Completed',\n\t\t\tFAILED: $t.translate?.run?.translation_failed || 'Failed',\n\t\t\tRUNNING: $t.translate?.history?.status_running || 'Running',\n\t\t\tPENDING: $t.translate?.history?.status_pending || 'Pending',\n\t\t\tCANCELLED: $t.translate?.run?.cancelled || 'Cancelled',\n\t\t};\n\t\treturn labels[value] || value;\n\t}\n\n\t// Derived\n\tlet insertStatusBadge = $derived.by(() => {\n\t\tconst s = status?.insert_status;\n\t\tif (!s || s === 'success') return { label: $t.translate?.run?.success, class: 'bg-green-100 text-green-700' };\n\t\tif (s === 'failed' || s === 'timeout') return { label: $t.translate?.run?.failed, class: 'bg-red-100 text-red-700' };\n\t\treturn { label: s, class: 'bg-yellow-100 text-yellow-700' };\n\t});\n\n\t$effect(() => {\n\t\tif (runId) {\n\t\t\tloadData();\n\t\t}\n\t});\n\n\t// Reload records when page, filter, or table visibility changes\n\tlet recordsLoadKey = $derived(showRecords ? `${currentPage}-${statusFilter}-${pageSize}-${runId}` : null);\n\t$effect(() => {\n\t\tif (recordsLoadKey) {\n\t\t\tloadRecords();\n\t\t}\n\t});\n\n\t/** @returns {Promise} */\n\tasync function loadData() {\n\t\ttry {\n\t\t\tconst [statusData, batchesData] = await Promise.all([\n\t\t\t\tfetchRunStatus(runId),\n\t\t\t\tfetchRunBatches(runId),\n\t\t\t]);\n\t\t\tstatus = statusData;\n\t\t\tbatches = Array.isArray(batchesData) ? batchesData : [];\n\n\t\t\t// Extract target languages from language_stats\n\t\t\tif (statusData.language_stats && statusData.language_stats.length > 0) {\n\t\t\t\ttargetLanguages = statusData.language_stats.map(l => l.language_code);\n\t\t\t}\n\n\t\t\t// Determine state\n\t\t\tconst s = statusData.status;\n\t\t\tconst insertS = statusData.insert_status;\n\t\t\tif (s === 'COMPLETED' && insertS === 'failed') {\n\t\t\t\tuxState = 'insert_failed';\n\t\t\t} else if (s === 'COMPLETED' && (statusData.failed_records || 0) > 0) {\n\t\t\t\tuxState = 'partial';\n\t\t\t} else if (s === 'FAILED') {\n\t\t\t\tuxState = 'failed';\n\t\t\t} else {\n\t\t\t\tuxState = 'completed';\n\t\t\t}\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || $t.translate?.run?.load_failed, 'error');\n\t\t}\n\t}\n\n\t/** @returns {Promise} */\n\tasync function loadRecords() {\n\t\ttry {\n\t\t\tconst recordsData = await fetchRunRecords(runId, {\n\t\t\t\tpage: currentPage,\n\t\t\t\tpage_size: pageSize,\n\t\t\t\tstatus: statusFilter || undefined\n\t\t\t});\n\t\t\trecords = recordsData?.items || [];\n\t\t\ttotalRecords = recordsData?.total || 0;\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || $t.translate?.run?.load_failed, 'error');\n\t\t}\n\t}\n\n\t/** @param {number} page */\n\tfunction goToPage(page) {\n\t\tif (page < 1 || page > totalPages) return;\n\t\tcurrentPage = page;\n\t}\n\n\t/** @param {string} filterValue */\n\tfunction setFilter(filterValue) {\n\t\tstatusFilter = filterValue;\n\t\tcurrentPage = 1;\n\t}\n\n\t/** @returns {Promise} */\n\tasync function handleRetry() {\n\t\tisRetrying = true;\n\t\ttry {\n\t\t\tawait retryFailedBatches(runId);\n\t\t\taddToast($t.translate?.run?.retry_success, 'success');\n\t\t\tawait loadData();\n\t\t\tonRefresh();\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || $t.translate?.run?.retry_failed_msg, 'error');\n\t\t} finally {\n\t\t\tisRetrying = false;\n\t\t}\n\t}\n\n\t/** @returns {Promise} */\n\tasync function handleRetryInsert() {\n\t\tisRetryingInsert = true;\n\t\ttry {\n\t\t\tawait retryInsert(runId);\n\t\t\taddToast($t.translate?.run?.insert_retry_success, 'success');\n\t\t\tawait loadData();\n\t\t\tonRefresh();\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || $t.translate?.run?.insert_retry_failed_msg, 'error');\n\t\t} finally {\n\t\t\tisRetryingInsert = false;\n\t\t}\n\t}\n\n\t/** @param {string} text */\n\tfunction copyToClipboard(text) {\n\t\tnavigator.clipboard.writeText(text).then(() => {\n\t\t\taddToast($t.translate?.run?.copy_success, 'success');\n\t\t}).catch(() => {\n\t\t\taddToast($t.translate?.run?.copy_failed, 'error');\n\t\t});\n\t}\n\n\t/** @returns {Promise} */\n\tasync function toggleSqlAudit() {\n\t\tshowSqlAudit = !showSqlAudit;\n\t\tif (showSqlAudit && sqlAuditLines.length === 0) {\n\t\t\t// Load all records with successful translation for SQL audit\n\t\t\ttry {\n\t\t\t\tconst allRecords = await fetchRunRecords(runId, { page_size: 500, status: 'SUCCESS' });\n\t\t\t\tconst items = allRecords?.items || [];\n\t\t\t\tsqlAuditLines = items.slice(0, 20).map(r => r.target_sql).filter(Boolean);\n\t\t\t} catch (err) {\n\t\t\t\tsqlAuditLines = [$t.translate?.run?.no_sql_audit];\n\t\t\t}\n\t\t}\n\t}\n\n\n
\n\t{#if !status}\n\t\t
\n\t\t\t

{$t.translate?.run?.loading_result}

\n\t\t
\n\t{:else}\n\t\t
\n\t\t\t\n\t\t\t
\n\t\t\t\t

{$t.translate?.run?.result_title}

\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t{#if uxState === 'failed' || uxState === 'partial'}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{isRetrying ? $t.translate?.run?.retrying : $t.translate?.run?.retry_failed}\n\t\t\t\t\t\t\n\t\t\t\t\t{/if}\n\t\t\t\t\t{#if uxState === 'insert_failed'}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{isRetryingInsert ? $t.translate?.run?.retrying_insert : $t.translate?.run?.retry_insert}\n\t\t\t\t\t\t\n\t\t\t\t\t{/if}\n\t\t\t\t
\n\t\t\t
\n\n\t\t\t\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t

{$t.translate?.run?.total_records}

\n\t\t\t\t\t

{status.total_records || 0}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t

{$t.translate?.run?.success}

\n\t\t\t\t\t

{status.successful_records || 0}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t

{$t.translate?.run?.failed}

\n\t\t\t\t\t

{status.failed_records || 0}

\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t

{$t.translate?.run?.skipped}

\n\t\t\t\t\t

{status.skipped_records || 0}

\n\t\t\t\t
\n\t\t\t
\n\n\t\t\t\n\t\t\t{#if status.language_stats && status.language_stats.length > 0}\n\t\t\t\t
\n\t\t\t\t\t

{$t.translate?.run?.per_language ?? 'Per-Language Statistics'}

\n\t\t\t\t\t
\n\t\t\t\t\t\t{#each status.language_stats as lang}\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t

{lang.language_code}

\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t{lang.translated_rows}\n\t\t\t\t\t\t\t\t\t{#if lang.failed_rows > 0}\n\t\t\t\t\t\t\t\t\t\t{lang.failed_rows}\n\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t{#if lang.skipped_rows > 0}\n\t\t\t\t\t\t\t\t\t\t{lang.skipped_rows}\n\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t{lang.total_rows}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t{/if}\n\n\t\t\t\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t{$t.translate?.run?.run_id}\n\t\t\t\t\t\t{status.id}\n\t\t\t\t\t\t copyToClipboard(status.id)}\n\t\t\t\t\t\t\tclass=\"ml-1 text-blue-500 hover:text-blue-700 text-xs\"\n\t\t\t\t\t\t\ttitle={$t.translate?.run?.copy_id}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{$t.translate?.run?.copy_id}\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t{$t.translate?.run?.status_label || 'Статус'}\n\t\t\t\t\t\t{getRunStatusLabel(status.status)}\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t{$t.translate?.run?.insert_status}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{insertStatusBadge.label}\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t{#if status.superset_execution_id}\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{$t.translate?.run?.superset_query}\n\t\t\t\t\t\t\t{status.superset_execution_id}\n\t\t\t\t\t\t\t copyToClipboard(status.superset_execution_id)}\n\t\t\t\t\t\t\t\tclass=\"ml-1 text-blue-500 hover:text-blue-700 text-xs\"\n\t\t\t\t\t\t\t\ttitle={$t.translate?.run?.copy_id}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{$t.translate?.run?.copy_id}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t{/if}\n\t\t\t\t\t{#if status.error_message}\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{$t.translate?.run?.error_label?.replace('{error}', status.error_message)}\n\t\t\t\t\t\t
\n\t\t\t\t\t{/if}\n\t\t\t\t
\n\t\t\t
\n\n\t\t\t\n\t\t\t
\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{$t.translate?.run?.sql_audit?.replace('{count}', sqlAuditLines.length)}\n\t\t\t\t\n\n\t\t\t\t{#if showSqlAudit}\n\t\t\t\t\t
\n\t\t\t\t\t\t{#if sqlAuditLines.length === 0}\n\t\t\t\t\t\t\t

{$t.translate?.run?.no_sql_audit}

\n\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t{#each sqlAuditLines as line, idx}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t{idx + 1}. {line}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\t\t\t
\n\n\t\t\t\n\t\t\t{#if status.event_invariants}\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t{$t.translate?.run?.event_invariants}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{status.event_invariants.invariant_valid ? $t.translate?.run?.valid : $t.translate?.run?.violated}\n\t\t\t\t\t\t\n\t\t\t\t\t\t|\n\t\t\t\t\t\t{$t.translate?.run?.superset_query_id_label} {status.event_invariants.has_run_started ? $t.translate?.run?.started_yes : $t.translate?.run?.started_no}\n\t\t\t\t\t\t|\n\t\t\t\t\t\t{$t.translate?.run?.terminal_events?.replace('{count}', status.event_invariants.terminal_event_count)}\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t{/if}\n\n\t\t\t\n\t\t\t{#if status && status.total_records > 0}\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t {\n\t\t\t\t\t\t\t\tshowRecords = !showRecords;\n\t\t\t\t\t\t\t\tif (showRecords) { currentPage = 1; statusFilter = ''; }\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tclass=\"flex items-center gap-2 text-sm text-gray-700 hover:text-gray-900\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{$t.translate?.run?.records_title || 'Translation Records'}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t({totalRecords > 0 ? `${recordStart}–${recordEnd} / ${totalRecords}` : status.total_records})\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\n\t\t\t\t\t\t{#if showRecords}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t{#each STATUS_FILTERS as f}\n\t\t\t\t\t\t\t\t\t setFilter(f.value)}\n\t\t\t\t\t\t\t\t\t\tclass=\"px-2 py-0.5 text-[11px] rounded-full border transition-colors\n\t\t\t\t\t\t\t\t\t\t\t{statusFilter === f.value\n\t\t\t\t\t\t\t\t\t\t\t\t? 'bg-blue-600 text-white border-blue-600'\n\t\t\t\t\t\t\t\t\t\t\t\t: 'text-gray-500 border-gray-300 hover:bg-gray-100'}\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{$t.translate?.run?.[f.labelKey] || f.label}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t
\n\n\t\t\t\t\t{#if showRecords}\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{#each targetLanguages as lang}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\t\t\t{#if targetLanguages.length === 0}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{#each records as row, idx}\n\t\t\t\t\t\t\t\t\t\t{@const globalIdx = (currentPage - 1) * pageSize + idx + 1}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t{#if targetLanguages.length > 0}\n\t\t\t\t\t\t\t\t\t\t\t\t{#if row.languages && row.languages.length > 0}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{#each targetLanguages as lang}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{@const langData = (row.languages || []).find(l => l.language_code === lang)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{@const cellValue = langData?.final_value || langData?.translated_value || ''}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{@const detectedSource = langData?.source_language_detected || row.source_language_detected || ''}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t\t{:else}\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
#{$t.translate?.preview?.table_source || 'Source'}\n\t\t\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t{lang}\n\t\t\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t
{$t.translate?.preview?.translation || 'Translation'}{$t.translate?.preview?.table_status || 'Status'}{$t.translate?.preview?.table_actions || 'Actions'}
{globalIdx}\n\t\t\t\t\t\t\t\t\t\t\t\t{row.source_sql || row.source_object_name || '—'}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.run?.translation_failed || 'Translation failed'}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t{row.status}\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t{#if row.languages && row.languages.length > 0}\n\t\t\t\t\t\t\t\t\t\t\t\t\t {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst firstLang = row.languages?.[0] || {};\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcorrectionPopupData = {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsourceTerm: row.source_sql || row.source_object_name || '',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tincorrectTarget: firstLang?.final_value || firstLang?.translated_value || '',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsourceLanguage: firstLang?.source_language_detected || row.source_language_detected || '',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttargetLanguage: targetLanguages[0] || '',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\trunId,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\trowKey: row.id\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclass=\"px-2 py-0.5 text-[10px] bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttitle=\"Submit Correction\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{$t.translate?.run?.correct || 'Correct'}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t
\n\n\t\t\t\t\t\t\n\t\t\t\t\t\t{#if totalPages > 1}\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{$t.translate?.run?.records_title || 'Records'}: {recordStart}–{recordEnd} / {totalRecords}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t goToPage(currentPage - 1)}\n\t\t\t\t\t\t\t\t\t\tdisabled={currentPage <= 1}\n\t\t\t\t\t\t\t\t\t\tclass=\"px-2 py-1 text-xs border border-gray-300 rounded hover:bg-gray-100 disabled:opacity-30 disabled:cursor-default transition-colors\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t‹\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{#each visiblePages as page}\n\t\t\t\t\t\t\t\t\t\t goToPage(page)}\n\t\t\t\t\t\t\t\t\t\t\tclass=\"px-2 py-1 text-xs border rounded transition-colors\n\t\t\t\t\t\t\t\t\t\t\t\t{page === currentPage\n\t\t\t\t\t\t\t\t\t\t\t\t\t? 'bg-blue-600 text-white border-blue-600'\n\t\t\t\t\t\t\t\t\t\t\t\t\t: 'border-gray-300 text-gray-600 hover:bg-gray-100'}\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{page}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\t\t goToPage(currentPage + 1)}\n\t\t\t\t\t\t\t\t\t\tdisabled={currentPage >= totalPages}\n\t\t\t\t\t\t\t\t\t\tclass=\"px-2 py-1 text-xs border border-gray-300 rounded hover:bg-gray-100 disabled:opacity-30 disabled:cursor-default transition-colors\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t›\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t{/if}\n\t\t\t\t
\n\t\t\t{/if}\n\t\t
\n\t{/if}\n
\n\n\n correctionPopupData = null}\n\tonSubmitted={() => { correctionPopupData = null; loadData(); onRefresh(); }}\n/>\n\n showBulkReplace = false}\n\tonApplied={(count) => { showBulkReplace = false; loadData(); onRefresh(); }}\n/>\n\n" }, { "contract_id": "BulkReplaceModalTests", @@ -93239,24 +92225,16 @@ "contract_type": "Store", "file_path": "frontend/src/lib/stores/translationRun.js", "start_line": 1, - "end_line": 209, + "end_line": 195, "tier": "TIER_2", "complexity": 3, "metadata": { "COMPLEXITY": 3, - "INVARIANT": "Store is writable so page components can also set initial state.", + "PROPERTY": "{boolean} isActive - Derived: true when polling is active", "PURPOSE": "Global store for active translation run progress — survives page navigation.", - "TYPEDEF": "{'idle'|'running'|'inserting'|'completed'|'partial'|'failed'|'cancelled'} UxState", - "UX_STATE": "cancelled -> Run cancelled" + "TYPEDEF": "{Object} TranslationRunState" }, - "relations": [ - { - "source_id": "TranslationRunStore", - "relation_type": "DEPENDS_ON", - "target_id": "TranslateApi", - "target_ref": "[TranslateApi]" - } - ], + "relations": [], "schema_warnings": [ { "code": "tag_not_for_contract_type", @@ -93285,30 +92263,10 @@ } }, { - "code": "tag_not_for_contract_type", - "tag": "INVARIANT", - "message": "@INVARIANT is not allowed for contract type 'Store'", - "detail": { - "actual_type": "Store", - "allowed_types": [ - "Module", - "Function", - "Class", - "Component", - "Block", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "INVARIANT", - "message": "@INVARIANT is forbidden for contract type 'Store' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Store" - } + "code": "unknown_tag", + "tag": "PROPERTY", + "message": "@PROPERTY is not defined in axiom_config.yaml tags", + "detail": null }, { "code": "tag_not_for_contract_type", @@ -93342,47 +92300,18 @@ "tag": "TYPEDEF", "message": "@TYPEDEF is not defined in axiom_config.yaml tags", "detail": null - }, - { - "code": "tag_not_for_contract_type", - "tag": "UX_STATE", - "message": "@UX_STATE is not allowed for contract type 'Store'", - "detail": { - "actual_type": "Store", - "allowed_types": [ - "Component" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "UX_STATE", - "message": "@UX_STATE is forbidden for contract type 'Store' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Store" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "RELATION", - "message": "@RELATION is forbidden for contract type 'Store' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Store" - } } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "// #region TranslationRunStore [C:3] [TYPE Store] [SEMANTICS translate, run, progress, polling, store]\n// @BRIEF Global store for active translation run progress — survives page navigation.\n// @RELATION DEPENDS_ON -> [TranslateApi]\n// @UX_STATE idle -> No active run\n// @UX_STATE running -> Translation phase in progress\n// @UX_STATE inserting -> Insert phase in progress\n// @UX_STATE completed -> Run completed\n// @UX_STATE partial -> Completed with errors\n// @UX_STATE failed -> Run failed\n// @UX_STATE cancelled -> Run cancelled\n// @INVARIANT Polling stops when run reaches a terminal state (completed/failed/cancelled).\n// @INVARIANT Store is writable so page components can also set initial state.\n\nimport { writable, derived } from 'svelte/store';\nimport { fetchRunStatus } from '$lib/api/translate.js';\n\n/**\n * @typedef {'idle'|'running'|'inserting'|'completed'|'partial'|'failed'|'cancelled'} UxState\n */\n\n/**\n * @typedef {Object} TranslationRunState\n * @property {string|null} runId - Active translation run ID\n * @property {UxState} uxState - Current UX state\n * @property {Object|null} status - Raw status data from API\n * @property {number} totalRecords\n * @property {number} successfulRecords\n * @property {number} failedRecords\n * @property {number} skippedRecords\n * @property {number} progressPct - 0-100\n * @property {string|null} insertStatus\n * @property {number} batchCount\n * @property {string|null} jobId - The job this run belongs to (for navigation)\n * @property {boolean} isFullRun\n * @property {boolean} isActive - Derived: true when polling is active\n */\n\nconst initialState = {\n\trunId: null,\n\tuxState: 'idle',\n\tstatus: null,\n\ttotalRecords: 0,\n\tsuccessfulRecords: 0,\n\tfailedRecords: 0,\n\tskippedRecords: 0,\n\tprogressPct: 0,\n\tinsertStatus: null,\n\tbatchCount: 0,\n\tjobId: null,\n\tisFullRun: false,\n};\n\n/** @type {import('svelte/store').Writable} */\nexport const translationRunStore = writable(initialState);\n\n/** Derived: true when a run is actively being polled */\nexport const isTranslationActive = derived(\n\ttranslationRunStore,\n\t($store) => $store.uxState === 'running' || $store.uxState === 'inserting'\n);\n\n/** Derived: true when run has finished */\nexport const isTranslationFinished = derived(\n\ttranslationRunStore,\n\t($store) =>\n\t\t$store.uxState === 'completed' ||\n\t\t$store.uxState === 'partial' ||\n\t\t$store.uxState === 'failed' ||\n\t\t$store.uxState === 'cancelled'\n);\n\n// Internal polling state (not reactive)\nlet _pollingInterval = null;\nlet _pollCount = 0;\nconst MAX_POLLS = 300;\nlet _onCompleteCallback = null;\n\n/**\n * Clear the onComplete callback without stopping polling.\n * Used by page components when they unmount — the store keeps polling\n * so the global indicator still works, but the page callback is detached.\n */\nexport function clearOnCompleteCallback() {\n\t_onCompleteCallback = null;\n}\n\n/**\n * Start polling for a translation run.\n * @param {string} runId\n * @param {Object} [options]\n * @param {string} [options.jobId] - Job ID for navigation\n * @param {boolean} [options.isFullRun]\n * @param {Function} [options.onComplete] - Called when run reaches terminal state\n */\nexport function startTranslationRun(runId, options = {}) {\n\tif (!runId) return;\n\n\tstopTranslationRun();\n\n\ttranslationRunStore.set({\n\t\t...initialState,\n\t\trunId,\n\t\tuxState: 'running',\n\t\tjobId: options.jobId || null,\n\t\tisFullRun: options.isFullRun || false,\n\t});\n\n\t_onCompleteCallback = options.onComplete || null;\n\t_pollCount = 0;\n\t_pollingInterval = setInterval(pollStatus, 2000);\n\tpollStatus();\n}\n\n/**\n * Stop polling without clearing state (run may persist).\n */\nexport function stopTranslationRun() {\n\tif (_pollingInterval) {\n\t\tclearInterval(_pollingInterval);\n\t\t_pollingInterval = null;\n\t}\n}\n\n/**\n * Reset store to idle.\n */\nexport function resetTranslationRun() {\n\tstopTranslationRun();\n\ttranslationRunStore.set(initialState);\n\t_onCompleteCallback = null;\n}\n\n/**\n * Manually set the run state (used by page component for lifecycle hooks).\n * @param {Partial} state\n */\nexport function updateTranslationRunState(state) {\n\ttranslationRunStore.update(prev => ({ ...prev, ...state }));\n}\n\n/** @returns {Promise} */\nasync function pollStatus() {\n\t_pollCount++;\n\tif (_pollCount > MAX_POLLS) {\n\t\tconsole.warn('[translationRunStore] Max polls reached, stopping');\n\t\tstopTranslationRun();\n\t\ttranslationRunStore.update(s => ({ ...s, uxState: 'failed' }));\n\t\tif (_onCompleteCallback) _onCompleteCallback({ status: 'TIMEOUT', error_message: 'Translation run timed out' });\n\t\treturn;\n\t}\n\n\tlet currentState;\n\ttranslationRunStore.subscribe(s => { currentState = s; })();\n\tif (!currentState || !currentState.runId) {\n\t\tstopTranslationRun();\n\t\treturn;\n\t}\n\n\ttry {\n\t\tconst data = await fetchRunStatus(currentState.runId);\n\t\tif (!data) return;\n\n\t\tconst s = data?.status;\n\t\tconst insertS = data?.insert_status;\n\n\t\tlet newUxState = currentState.uxState;\n\n\t\tif (s === 'PENDING' || s === 'RUNNING') {\n\t\t\tnewUxState = (insertS === 'started' || insertS === 'pending' || insertS === 'running')\n\t\t\t\t? 'inserting' : 'running';\n\t\t} else if (s === 'COMPLETED') {\n\t\t\tnewUxState = (insertS === 'failed' || insertS === 'timeout') ? 'insert_failed'\n\t\t\t\t: (data.failed_records > 0) ? 'partial' : 'completed';\n\t\t\tstopTranslationRun();\n\t\t} else if (s === 'FAILED') {\n\t\t\tnewUxState = 'failed';\n\t\t\tstopTranslationRun();\n\t\t} else if (s === 'CANCELLED') {\n\t\t\tnewUxState = 'cancelled';\n\t\t\tstopTranslationRun();\n\t\t}\n\n\t\tconst total = data?.total_records || 0;\n\t\tconst pct = total > 0\n\t\t\t? Math.round(((data.successful_records + data.failed_records + data.skipped_records) / total) * 100)\n\t\t\t: 0;\n\n\t\ttranslationRunStore.update(prev => ({\n\t\t\t...prev,\n\t\t\tuxState: newUxState,\n\t\t\tstatus: data,\n\t\t\ttotalRecords: total,\n\t\t\tsuccessfulRecords: data?.successful_records || 0,\n\t\t\tfailedRecords: data?.failed_records || 0,\n\t\t\tskippedRecords: data?.skipped_records || 0,\n\t\t\tprogressPct: pct,\n\t\t\tinsertStatus: data?.insert_status || null,\n\t\t\tbatchCount: data?.batch_count || 0,\n\t\t}));\n\n\t\t// Fire completion callback if terminal\n\t\tif (newUxState !== 'running' && newUxState !== 'inserting') {\n\t\t\tif (_onCompleteCallback) _onCompleteCallback(data);\n\t\t}\n\t} catch (err) {\n\t\tconsole.warn('[translationRunStore] Poll error:', err);\n\t}\n}\n// #endregion TranslationRunStore\n" + "body": "// #region TranslationRunStore [C:3] [TYPE Store] [SEMANTICS translate, run, progress, polling, store]\n// @BRIEF Global store for active translation run progress — survives page navigation.\n// @TYPEDEF {'idle'|'running'|'inserting'|'completed'|'partial'|'failed'|'cancelled'} UxState\n\n */\n\n/**\n * @typedef {Object} TranslationRunState\n * @property {string|null} runId - Active translation run ID\n * @property {UxState} uxState - Current UX state\n * @property {Object|null} status - Raw status data from API\n * @property {number} totalRecords\n * @property {number} successfulRecords\n * @property {number} failedRecords\n * @property {number} skippedRecords\n * @property {number} progressPct - 0-100\n * @property {string|null} insertStatus\n * @property {number} batchCount\n * @property {string|null} jobId - The job this run belongs to (for navigation)\n * @property {boolean} isFullRun\n * @property {boolean} isActive - Derived: true when polling is active\n */\n\nconst initialState = {\n\trunId: null,\n\tuxState: 'idle',\n\tstatus: null,\n\ttotalRecords: 0,\n\tsuccessfulRecords: 0,\n\tfailedRecords: 0,\n\tskippedRecords: 0,\n\tprogressPct: 0,\n\tinsertStatus: null,\n\tbatchCount: 0,\n\tjobId: null,\n\tisFullRun: false,\n};\n\n/** @type {import('svelte/store').Writable} */\nexport const translationRunStore = writable(initialState);\n\n/** Derived: true when a run is actively being polled */\nexport const isTranslationActive = derived(\n\ttranslationRunStore,\n\t($store) => $store.uxState === 'running' || $store.uxState === 'inserting'\n);\n\n/** Derived: true when run has finished */\nexport const isTranslationFinished = derived(\n\ttranslationRunStore,\n\t($store) =>\n\t\t$store.uxState === 'completed' ||\n\t\t$store.uxState === 'partial' ||\n\t\t$store.uxState === 'failed' ||\n\t\t$store.uxState === 'cancelled'\n);\n\n// Internal polling state (not reactive)\nlet _pollingInterval = null;\nlet _pollCount = 0;\nconst MAX_POLLS = 300;\nlet _onCompleteCallback = null;\n\n/**\n * Clear the onComplete callback without stopping polling.\n * Used by page components when they unmount — the store keeps polling\n * so the global indicator still works, but the page callback is detached.\n */\nexport function clearOnCompleteCallback() {\n\t_onCompleteCallback = null;\n}\n\n/**\n * Start polling for a translation run.\n * @param {string} runId\n * @param {Object} [options]\n * @param {string} [options.jobId] - Job ID for navigation\n * @param {boolean} [options.isFullRun]\n * @param {Function} [options.onComplete] - Called when run reaches terminal state\n */\nexport function startTranslationRun(runId, options = {}) {\n\tif (!runId) return;\n\n\tstopTranslationRun();\n\n\ttranslationRunStore.set({\n\t\t...initialState,\n\t\trunId,\n\t\tuxState: 'running',\n\t\tjobId: options.jobId || null,\n\t\tisFullRun: options.isFullRun || false,\n\t});\n\n\t_onCompleteCallback = options.onComplete || null;\n\t_pollCount = 0;\n\t_pollingInterval = setInterval(pollStatus, 2000);\n\tpollStatus();\n}\n\n/**\n * Stop polling without clearing state (run may persist).\n */\nexport function stopTranslationRun() {\n\tif (_pollingInterval) {\n\t\tclearInterval(_pollingInterval);\n\t\t_pollingInterval = null;\n\t}\n}\n\n/**\n * Reset store to idle.\n */\nexport function resetTranslationRun() {\n\tstopTranslationRun();\n\ttranslationRunStore.set(initialState);\n\t_onCompleteCallback = null;\n}\n\n/**\n * Manually set the run state (used by page component for lifecycle hooks).\n * @param {Partial} state\n */\nexport function updateTranslationRunState(state) {\n\ttranslationRunStore.update(prev => ({ ...prev, ...state }));\n}\n\n/** @returns {Promise} */\nasync function pollStatus() {\n\t_pollCount++;\n\tif (_pollCount > MAX_POLLS) {\n\t\tconsole.warn('[translationRunStore] Max polls reached, stopping');\n\t\tstopTranslationRun();\n\t\ttranslationRunStore.update(s => ({ ...s, uxState: 'failed' }));\n\t\tif (_onCompleteCallback) _onCompleteCallback({ status: 'TIMEOUT', error_message: 'Translation run timed out' });\n\t\treturn;\n\t}\n\n\tlet currentState;\n\ttranslationRunStore.subscribe(s => { currentState = s; })();\n\tif (!currentState || !currentState.runId) {\n\t\tstopTranslationRun();\n\t\treturn;\n\t}\n\n\ttry {\n\t\tconst data = await fetchRunStatus(currentState.runId);\n\t\tif (!data) return;\n\n\t\tconst s = data?.status;\n\t\tconst insertS = data?.insert_status;\n\n\t\tlet newUxState = currentState.uxState;\n\n\t\tif (s === 'PENDING' || s === 'RUNNING') {\n\t\t\tnewUxState = (insertS === 'started' || insertS === 'pending' || insertS === 'running')\n\t\t\t\t? 'inserting' : 'running';\n\t\t} else if (s === 'COMPLETED') {\n\t\t\tnewUxState = (insertS === 'failed' || insertS === 'timeout') ? 'insert_failed'\n\t\t\t\t: (data.failed_records > 0) ? 'partial' : 'completed';\n\t\t\tstopTranslationRun();\n\t\t} else if (s === 'FAILED') {\n\t\t\tnewUxState = 'failed';\n\t\t\tstopTranslationRun();\n\t\t} else if (s === 'CANCELLED') {\n\t\t\tnewUxState = 'cancelled';\n\t\t\tstopTranslationRun();\n\t\t}\n\n\t\tconst total = data?.total_records || 0;\n\t\tconst pct = total > 0\n\t\t\t? Math.round(((data.successful_records + data.failed_records + data.skipped_records) / total) * 100)\n\t\t\t: 0;\n\n\t\ttranslationRunStore.update(prev => ({\n\t\t\t...prev,\n\t\t\tuxState: newUxState,\n\t\t\tstatus: data,\n\t\t\ttotalRecords: total,\n\t\t\tsuccessfulRecords: data?.successful_records || 0,\n\t\t\tfailedRecords: data?.failed_records || 0,\n\t\t\tskippedRecords: data?.skipped_records || 0,\n\t\t\tprogressPct: pct,\n\t\t\tinsertStatus: data?.insert_status || null,\n\t\t\tbatchCount: data?.batch_count || 0,\n\t\t}));\n\n\t\t// Fire completion callback if terminal\n\t\tif (newUxState !== 'running' && newUxState !== 'inserting') {\n\t\t\tif (_onCompleteCallback) _onCompleteCallback(data);\n\t\t}\n\t} catch (err) {\n\t\tconsole.warn('[translationRunStore] Poll error:', err);\n\t}\n}\n// #endregion TranslationRunStore\n" }, { "contract_id": "frontend/src/lib/stores/translationRun.js::clearOnCompleteCallback", "contract_type": "Function", "file_path": "frontend/src/lib/stores/translationRun.js", - "start_line": 78, - "end_line": 83, + "start_line": 64, + "end_line": 69, "tier": "TIER_1", "complexity": 1, "metadata": {}, @@ -93396,8 +92325,8 @@ "contract_id": "frontend/src/lib/stores/translationRun.js::startTranslationRun", "contract_type": "Function", "file_path": "frontend/src/lib/stores/translationRun.js", - "start_line": 87, - "end_line": 95, + "start_line": 73, + "end_line": 81, "tier": "TIER_1", "complexity": 1, "metadata": {}, @@ -93411,8 +92340,8 @@ "contract_id": "frontend/src/lib/stores/translationRun.js::stopTranslationRun", "contract_type": "Function", "file_path": "frontend/src/lib/stores/translationRun.js", - "start_line": 114, - "end_line": 117, + "start_line": 100, + "end_line": 103, "tier": "TIER_1", "complexity": 1, "metadata": {}, @@ -93426,8 +92355,8 @@ "contract_id": "frontend/src/lib/stores/translationRun.js::resetTranslationRun", "contract_type": "Function", "file_path": "frontend/src/lib/stores/translationRun.js", - "start_line": 124, - "end_line": 127, + "start_line": 110, + "end_line": 113, "tier": "TIER_1", "complexity": 1, "metadata": {}, @@ -93441,8 +92370,8 @@ "contract_id": "frontend/src/lib/stores/translationRun.js::updateTranslationRunState", "contract_type": "Function", "file_path": "frontend/src/lib/stores/translationRun.js", - "start_line": 133, - "end_line": 137, + "start_line": 119, + "end_line": 123, "tier": "TIER_1", "complexity": 1, "metadata": {}, @@ -93456,8 +92385,8 @@ "contract_id": "frontend/src/lib/stores/translationRun.js::pollStatus", "contract_type": "Function", "file_path": "frontend/src/lib/stores/translationRun.js", - "start_line": 141, - "end_line": 142, + "start_line": 127, + "end_line": 128, "tier": "TIER_1", "complexity": 1, "metadata": {}, @@ -103107,31 +102036,15 @@ "contract_type": "Page", "file_path": "frontend/src/routes/translate/+page.svelte", "start_line": 1, - "end_line": 301, + "end_line": 282, "tier": "TIER_2", "complexity": 3, "metadata": { "COMPLEXITY": 3, - "LAYER": "UI", - "POST": "Renders job list with status badges and navigation to config.", - "PRE": "Valid auth context before fetching job list.", - "PURPOSE": "Translation job list page showing all jobs with status and schedule indicators.", - "UX_STATE": "error -> Shows error message with retry button" + "PURPOSE": "Translation job list page showing all jobs with status badges and schedule indicators.", + "TYPE": "{string} idle | loading | empty | populated | error" }, - "relations": [ - { - "source_id": "TranslateJobList", - "relation_type": "CALLS", - "target_id": "TranslateApi", - "target_ref": "[TranslateApi]" - }, - { - "source_id": "TranslateJobList", - "relation_type": "DEPENDS_ON", - "target_id": "TranslateApi", - "target_ref": "[TranslateApi]" - } - ], + "relations": [], "schema_warnings": [ { "code": "tag_not_for_contract_type", @@ -103159,76 +102072,6 @@ "contract_type": "Page" } }, - { - "code": "tag_not_for_contract_type", - "tag": "LAYER", - "message": "@LAYER is not allowed for contract type 'Page'", - "detail": { - "actual_type": "Page", - "allowed_types": [ - "Module", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "LAYER", - "message": "@LAYER is forbidden for contract type 'Page' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Page" - } - }, - { - "code": "tag_not_for_contract_type", - "tag": "POST", - "message": "@POST is not allowed for contract type 'Page'", - "detail": { - "actual_type": "Page", - "allowed_types": [ - "Module", - "Function", - "Class", - "Component", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "POST", - "message": "@POST is forbidden for contract type 'Page' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Page" - } - }, - { - "code": "tag_not_for_contract_type", - "tag": "PRE", - "message": "@PRE is not allowed for contract type 'Page'", - "detail": { - "actual_type": "Page", - "allowed_types": [ - "Module", - "Function", - "Class", - "Component", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "PRE", - "message": "@PRE is forbidden for contract type 'Page' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Page" - } - }, { "code": "tag_not_for_contract_type", "tag": "PURPOSE", @@ -103257,73 +102100,30 @@ } }, { - "code": "tag_not_for_contract_type", - "tag": "UX_STATE", - "message": "@UX_STATE is not allowed for contract type 'Page'", - "detail": { - "actual_type": "Page", - "allowed_types": [ - "Component" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "UX_STATE", - "message": "@UX_STATE is forbidden for contract type 'Page' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Page" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "RELATION", - "message": "@RELATION is forbidden for contract type 'Page' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Page" - } + "code": "unknown_tag", + "tag": "TYPE", + "message": "@TYPE is not defined in axiom_config.yaml tags", + "detail": null } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "\n\n\n\n\n\n\n\n\n\n\n
\n
\n
\n

{$t.translate?.jobs?.title}

\n

\n {$t.translate?.jobs?.subtitle}\n

\n
\n \n \n \n \n {$t.translate?.jobs?.new_job}\n \n
\n\n \n
\n {#each statusPills as pill}\n filterByStatus(pill.value)}\n class=\"px-3 py-1.5 text-sm rounded-full border transition-colors\n {statusFilter === pill.value\n ? 'bg-blue-50 border-blue-300 text-blue-700'\n : 'bg-white border-gray-200 text-gray-600 hover:border-gray-300'}\"\n >\n {pill.label}\n ({pill.count})\n \n {/each}\n
\n\n \n {#if isLoading}\n
\n {#each Array(5) as _}\n
\n {/each}\n
\n\n \n {:else if uxState === 'error'}\n
\n

{error || $t.translate?.jobs?.an_error_occurred}

\n \n {$t.translate?.common?.retry}\n \n
\n\n \n {:else if uxState === 'empty'}\n
\n \n \n \n {#if statusFilter}\n

{$t.translate?.jobs?.no_jobs_filtered.replace('{status}', statusFilter)}

\n filterByStatus('')}\n class=\"text-blue-600 hover:text-blue-700 text-sm\"\n >\n {$t.translate?.jobs?.clear_filter}\n \n {:else}\n

{$t.translate?.jobs?.no_jobs}

\n \n {$t.translate?.jobs?.create_job}\n \n {/if}\n
\n\n \n {:else if uxState === 'populated'}\n
\n {#each jobs as job}\n navigateToConfig(job.id)}\n class=\"bg-white border border-gray-200 rounded-lg p-4 hover:shadow-md hover:border-gray-300 transition-all cursor-pointer\"\n >\n
\n
\n
\n

{job.name}

\n \n {job.status}\n \n
\n {#if job.description}\n

{job.description}

\n {/if}\n
\n {#if job.source_dialect && job.target_dialect}\n {job.source_dialect} → {job.target_dialect}\n {/if}\n\t\t\t\t{#if job.target_languages?.length > 0}\n\t\t\t\t
\n\t\t\t\t {#each job.target_languages as lang}\n\t\t\t\t {lang}\n\t\t\t\t {/each}\n\t\t\t\t
\n\t\t\t\t{:else if job.target_language}\n\t\t\t\t {job.target_language}\n\t\t\t\t{/if}\n {#if job.translation_column}\n {$t.translate?.jobs?.column_label.replace('{column}', job.translation_column)}\n {/if}\n {#if job.created_by}\n {$t.translate?.jobs?.by_label.replace('{by}', job.created_by)}\n {/if}\n {#if job.updated_at}\n {$t.translate?.jobs?.updated_label.replace('{date}', new Date(job.updated_at).toLocaleDateString())}\n {/if}\n
\n
\n
e.stopPropagation()}>\n handleDuplicate(job.id)}\n class=\"p-2 text-gray-400 hover:text-blue-600 rounded-lg hover:bg-blue-50 transition-colors\"\n title={$t.translate?.jobs?.duplicate}\n >\n \n \n \n \n {#if showDeleteConfirm === job.id}\n
\n handleDelete(job.id)}\n class=\"px-2 py-1 text-xs bg-red-600 text-white rounded hover:bg-red-700\"\n >\n {$t.translate?.jobs?.confirm_delete}\n \n (showDeleteConfirm = null)}\n class=\"px-2 py-1 text-xs bg-gray-200 text-gray-700 rounded hover:bg-gray-300\"\n >\n {$t.translate?.jobs?.cancel_delete}\n \n
\n {:else}\n (showDeleteConfirm = job.id)}\n class=\"p-2 text-gray-400 hover:text-red-600 rounded-lg hover:bg-red-50 transition-colors\"\n title={$t.translate?.common?.delete}\n >\n \n \n \n \n {/if}\n
\n
\n
\n {/each}\n
\n {/if}\n
\n\n\n" + "body": "\n\n\n */\n\n import { onMount } from 'svelte';\n import { goto } from '$app/navigation';\n import { t, _ } from '$lib/i18n';\n import { addToast } from '$lib/toasts.js';\n import { fetchJobs, deleteJob, duplicateJob } from '$lib/api/translate.js';\n\n /** @type {string} idle | loading | empty | populated | error */\n let uxState = $state('idle');\n let jobs = $state([]);\n let error = $state(null);\n let isLoading = $state(true);\n let showDeleteConfirm = $state(null);\n let statusFilter = $state('');\n let currentPage = $state(1);\n let pageSize = $state(20);\n\n // Count jobs by status for filter pills\n let statusCounts = $derived.by(() => {\n const counts = { DRAFT: 0, READY: 0, RUNNING: 0, COMPLETED: 0, FAILED: 0, CANCELLED: 0 };\n for (const job of jobs) {\n if (counts[job.status] !== undefined) counts[job.status]++;\n }\n return counts;\n });\n\n let statusPills = $derived([\n { label: 'All', value: '', count: jobs.length },\n { label: $t.translate?.jobs?.status_draft, value: 'DRAFT', count: statusCounts.DRAFT },\n { label: $t.translate?.jobs?.status_ready, value: 'READY', count: statusCounts.READY },\n { label: $t.translate?.jobs?.status_running, value: 'RUNNING', count: statusCounts.RUNNING },\n { label: $t.translate?.jobs?.status_completed, value: 'COMPLETED', count: statusCounts.COMPLETED },\n { label: $t.translate?.jobs?.status_failed, value: 'FAILED', count: statusCounts.FAILED },\n ]);\n\n onMount(() => {\n loadJobs();\n });\n\n /** @returns {Promise} */\n async function loadJobs() {\n isLoading = true;\n uxState = 'loading';\n error = null;\n try {\n const result = await fetchJobs({ page: currentPage, page_size: pageSize, status: statusFilter || undefined });\n jobs = Array.isArray(result) ? result : (result?.results || result?.items || []);\n uxState = jobs.length === 0 ? 'empty' : 'populated';\n } catch (err) {\n error = err?.message || $t.translate?.jobs?.load_failed;\n uxState = 'error';\n } finally {\n isLoading = false;\n }\n }\n\n /** @param {string} status */\n function filterByStatus(status) {\n statusFilter = status;\n currentPage = 1;\n loadJobs();\n }\n\n /** @param {string} jobId */\n function navigateToConfig(jobId) {\n goto(`/translate/${jobId}`);\n }\n\n function navigateToCreate() {\n goto('/translate/new');\n }\n\n /** @param {string} jobId */\n async function handleDuplicate(jobId) {\n try {\n const result = await duplicateJob(jobId);\n addToast(`${_('translate.jobs.job_duplicated').replace('{name}', result.name)}`, 'success');\n loadJobs();\n } catch (err) {\n addToast(err?.message || _('translate.jobs.duplicate_failed'), 'error');\n }\n }\n\n /** @param {string} jobId */\n async function handleDelete(jobId) {\n try {\n await deleteJob(jobId);\n addToast(_('translate.jobs.job_deleted'), 'success');\n showDeleteConfirm = null;\n loadJobs();\n } catch (err) {\n addToast(err?.message || _('translate.jobs.delete_failed'), 'error');\n showDeleteConfirm = null;\n }\n }\n\n /** @param {string} status */\n function getStatusBadgeClass(status) {\n const map = {\n DRAFT: 'bg-gray-100 text-gray-700',\n READY: 'bg-blue-100 text-blue-700',\n RUNNING: 'bg-yellow-100 text-yellow-700',\n COMPLETED: 'bg-green-100 text-green-700',\n FAILED: 'bg-red-100 text-red-700',\n CANCELLED: 'bg-gray-100 text-gray-500',\n };\n return map[status] || 'bg-gray-100 text-gray-700';\n }\n\n\n
\n
\n
\n

{$t.translate?.jobs?.title}

\n

\n {$t.translate?.jobs?.subtitle}\n

\n
\n \n \n \n \n {$t.translate?.jobs?.new_job}\n \n
\n\n \n
\n {#each statusPills as pill}\n filterByStatus(pill.value)}\n class=\"px-3 py-1.5 text-sm rounded-full border transition-colors\n {statusFilter === pill.value\n ? 'bg-blue-50 border-blue-300 text-blue-700'\n : 'bg-white border-gray-200 text-gray-600 hover:border-gray-300'}\"\n >\n {pill.label}\n ({pill.count})\n \n {/each}\n
\n\n \n {#if isLoading}\n
\n {#each Array(5) as _}\n
\n {/each}\n
\n\n \n {:else if uxState === 'error'}\n
\n

{error || $t.translate?.jobs?.an_error_occurred}

\n \n {$t.translate?.common?.retry}\n \n
\n\n \n {:else if uxState === 'empty'}\n
\n \n \n \n {#if statusFilter}\n

{$t.translate?.jobs?.no_jobs_filtered.replace('{status}', statusFilter)}

\n filterByStatus('')}\n class=\"text-blue-600 hover:text-blue-700 text-sm\"\n >\n {$t.translate?.jobs?.clear_filter}\n \n {:else}\n

{$t.translate?.jobs?.no_jobs}

\n \n {$t.translate?.jobs?.create_job}\n \n {/if}\n
\n\n \n {:else if uxState === 'populated'}\n
\n {#each jobs as job}\n navigateToConfig(job.id)}\n class=\"bg-white border border-gray-200 rounded-lg p-4 hover:shadow-md hover:border-gray-300 transition-all cursor-pointer\"\n >\n
\n
\n
\n

{job.name}

\n \n {job.status}\n \n
\n {#if job.description}\n

{job.description}

\n {/if}\n
\n {#if job.source_dialect && job.target_dialect}\n {job.source_dialect} → {job.target_dialect}\n {/if}\n\t\t\t\t{#if job.target_languages?.length > 0}\n\t\t\t\t
\n\t\t\t\t {#each job.target_languages as lang}\n\t\t\t\t {lang}\n\t\t\t\t {/each}\n\t\t\t\t
\n\t\t\t\t{:else if job.target_language}\n\t\t\t\t {job.target_language}\n\t\t\t\t{/if}\n {#if job.translation_column}\n {$t.translate?.jobs?.column_label.replace('{column}', job.translation_column)}\n {/if}\n {#if job.created_by}\n {$t.translate?.jobs?.by_label.replace('{by}', job.created_by)}\n {/if}\n {#if job.updated_at}\n {$t.translate?.jobs?.updated_label.replace('{date}', new Date(job.updated_at).toLocaleDateString())}\n {/if}\n
\n
\n
e.stopPropagation()}>\n handleDuplicate(job.id)}\n class=\"p-2 text-gray-400 hover:text-blue-600 rounded-lg hover:bg-blue-50 transition-colors\"\n title={$t.translate?.jobs?.duplicate}\n >\n \n \n \n \n {#if showDeleteConfirm === job.id}\n
\n handleDelete(job.id)}\n class=\"px-2 py-1 text-xs bg-red-600 text-white rounded hover:bg-red-700\"\n >\n {$t.translate?.jobs?.confirm_delete}\n \n (showDeleteConfirm = null)}\n class=\"px-2 py-1 text-xs bg-gray-200 text-gray-700 rounded hover:bg-gray-300\"\n >\n {$t.translate?.jobs?.cancel_delete}\n \n
\n {:else}\n (showDeleteConfirm = job.id)}\n class=\"p-2 text-gray-400 hover:text-red-600 rounded-lg hover:bg-red-50 transition-colors\"\n title={$t.translate?.common?.delete}\n >\n \n \n \n \n {/if}\n
\n
\n
\n {/each}\n
\n {/if}\n
\n\n\n" }, { "contract_id": "TranslationJobConfig", "contract_type": "Page", "file_path": "frontend/src/routes/translate/[id]/+page.svelte", "start_line": 1, - "end_line": 1364, + "end_line": 1381, "tier": "TIER_2", "complexity": 4, "metadata": { "COMPLEXITY": 4, - "LAYER": "Page", - "PURPOSE": "Translation job configuration page with datasource selector, column mapping, target table config,", - "UX_STATE": "datasource_unavailable -> Selected datasource cannot be reached" + "PURPOSE": "Translation job configuration page with datasource selector, column mapping, target table config, LLM provider, and dictionary attachment.", + "TYPE": "{string} idle | loading | configured | saving | validation_error | datasource_unavailable" }, - "relations": [ - { - "source_id": "TranslationJobConfig", - "relation_type": "DEPENDS_ON", - "target_id": "ScheduleConfig", - "target_ref": "[ScheduleConfig]" - }, - { - "source_id": "TranslationJobConfig", - "relation_type": "CALLS", - "target_id": "TranslateApi", - "target_ref": "[TranslateApi]" - }, - { - "source_id": "TranslationJobConfig", - "relation_type": "CALLS", - "target_id": "api_module", - "target_ref": "[api_module]" - } - ], + "relations": [], "schema_warnings": [ { "code": "tag_not_for_contract_type", @@ -103351,45 +102151,6 @@ "contract_type": "Page" } }, - { - "code": "tag_not_for_contract_type", - "tag": "LAYER", - "message": "@LAYER is not allowed for contract type 'Page'", - "detail": { - "actual_type": "Page", - "allowed_types": [ - "Module", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "LAYER", - "message": "@LAYER is forbidden for contract type 'Page' at C4", - "detail": { - "actual_complexity": 4, - "contract_type": "Page" - } - }, - { - "code": "invalid_enum_value", - "tag": "LAYER", - "message": "@LAYER value 'Page' is not in allowed enum", - "detail": { - "allowed": [ - "Core", - "Domain", - "API", - "UI", - "Service", - "Infrastructure", - "Plugin" - ], - "value": "Page" - } - }, { "code": "tag_not_for_contract_type", "tag": "PURPOSE", @@ -103418,61 +102179,30 @@ } }, { - "code": "tag_not_for_contract_type", - "tag": "UX_STATE", - "message": "@UX_STATE is not allowed for contract type 'Page'", - "detail": { - "actual_type": "Page", - "allowed_types": [ - "Component" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "UX_STATE", - "message": "@UX_STATE is forbidden for contract type 'Page' at C4", - "detail": { - "actual_complexity": 4, - "contract_type": "Page" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "RELATION", - "message": "@RELATION is forbidden for contract type 'Page' at C4", - "detail": { - "actual_complexity": 4, - "contract_type": "Page" - } + "code": "unknown_tag", + "tag": "TYPE", + "message": "@TYPE is not defined in axiom_config.yaml tags", + "detail": null } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n
\n \n
\n
\n

\n {isNewJob ? $t.translate?.config?.new_title : $t.translate?.config?.edit_title}\n

\n {#if !isNewJob && existingJob}\n

{$t.translate?.config?.id_label.replace('{id}', existingJob.id)}

\n {/if}\n
\n
\n goto('/translate')}\n class=\"px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors\"\n >\n {$t.translate?.config?.cancel}\n \n \n {isSaving ? $t.translate?.config?.saving : $t.translate?.config?.save}\n \n
\n
\n\n \n {#if warnings.length > 0}\n
\n

{$t.translate?.config?.warnings_title}

\n
    \n {#each warnings as w}\n
  • {w}
  • \n {/each}\n
\n
\n {/if}\n\n \n {#if uxState === 'loading'}\n
\n {#each Array(6) as _}\n
\n {/each}\n
\n\n \n {:else if uxState === 'error'}\n
\n

{error || $t.translate?.common?.unknown_error}

\n goto('/translate')}\n class=\"px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors\"\n >\n {$t.translate?.config?.back_to_jobs}\n \n
\n\n \n {:else if uxState === 'datasource_unavailable'}\n
\n

\n {$t.translate?.config?.datasource_unavailable}\n

\n
\n\n \n {:else if uxState === 'configured' || uxState === 'saving' || uxState === 'validation_error' || uxState === 'idle'}\n \n
\n \n
\n\n \n
\n
\n \n
\n

{$t.translate?.config?.basic_info}

\n
\n
\n \n \n {#if validationErrors.name}\n

{validationErrors.name}

\n {/if}\n
\n
\n \n \n
\n
\n
\n\n \n
\n

{$t.translate?.config?.datasource}

\n
\n
\n \n \n \n {#each environments as env}\n \n {/each}\n \n
\n
\n \n searchDatasources('')}\n onblur={() => setTimeout(() => (showDatasourceDropdown = false), 150)}\n class=\"w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n placeholder={$t.translate?.config?.datasource_search_placeholder || 'Search datasets...'}\n />\n {#if datasourceLoading}\n
\n {/if}\n {#if showDatasourceDropdown}\n
\n {#each datasourceList as ds}\n selectDatasource(ds)}\n class=\"w-full text-left px-3 py-2 text-sm hover:bg-blue-50 border-b border-gray-100 last:border-b-0\"\n >\n {ds.table_name}\n {ds.schema}\n {ds.database_name} · {ds.database_dialect}\n \n {/each}\n
\n {/if}\n
\n {#if databaseDialect}\n
\n \n {$t.translate?.config?.detected_dialect.replace('{dialect}', databaseDialect)}\n \n
\n {/if}\n
\n\n {#if isColumnsLoading}\n
\n {/if}\n\n {#if columnList.length > 0}\n
\n \n
\n {#each columnList as col}\n
\n {col.name}\n {#if col.type}\n ({col.type})\n {/if}\n {#if isVirtual(col.name)}\n {$t.translate?.config?.virtual}\n {/if}\n
\n {/each}\n
\n
\n {/if}\n
\n\n \n
\n

{$t.translate?.config?.column_mapping}

\n\n \n
\n \n \n \n {#each columnList as col}\n \n {/each}\n \n {#if validationErrors.translationColumn}\n

{validationErrors.translationColumn}

\n {/if}\n
\n\n \n
\n
\n \n \n
\n
\n \n \n
\n
\n\n \n
\n
\n \n {#if sourceKeyCols.length > 0}\n { sourceKeyCols = []; targetKeyCols = []; }}\n class=\"text-xs text-red-600 hover:text-red-700\"\n >\n {$t.translate?.config?.clear_all}\n \n {/if}\n
\n\n {#if columnList.length === 0}\n
\n {\n sourceKeyCols = [...sourceKeyCols, ''];\n targetKeyCols = [...targetKeyCols, ''];\n }}\n class=\"px-3 py-1 text-xs border border-dashed border-gray-300 rounded text-gray-500 hover:border-blue-300 hover:text-blue-600\"\n >\n {$t.translate?.config?.add_key_column}\n \n
\n {:else}\n
\n {#each columnList as col}\n toggleSourceKeyCol(col.name)}\n class=\"px-2.5 py-1 text-xs rounded-full border transition-colors\n {sourceKeyCols.includes(col.name)\n ? 'bg-blue-100 border-blue-300 text-blue-700'\n : 'bg-white border-gray-200 text-gray-600 hover:border-gray-300'}\"\n title={isVirtual(col.name) ? $t.translate?.config?.virtual_column_warning.replace('{col}', col.name) : ''}\n >\n {col.name}\n {#if isVirtual(col.name)}\n *\n {/if}\n \n {/each}\n
\n {/if}\n\n {#if sourceKeyCols.length > 0}\n
\n {#each sourceKeyCols as srcCol, idx}\n
\n \n \n updateTargetKeyCol(idx, e.target.value)}\n class=\"flex-1 px-3 py-1.5 border border-gray-300 rounded text-sm font-mono focus:ring-2 focus:ring-blue-500\"\n />\n {\n sourceKeyCols = sourceKeyCols.filter((_, i) => i !== idx);\n targetKeyCols = targetKeyCols.filter((_, i) => i !== idx);\n }}\n class=\"p-1 text-gray-400 hover:text-red-500\"\n >\n \n \n \n \n
\n {/each}\n
\n {/if}\n {#if validationErrors.targetKeyCols}\n

{validationErrors.targetKeyCols}

\n {/if}\n
\n\n \n
\n \n {#if columnList.length === 0}\n

{$t.translate?.config?.select_datasource_hint}

\n {:else}\n
\n {#each columnList as col}\n toggleContextColumn(col.name)}\n class=\"px-2.5 py-1 text-xs rounded-full border transition-colors\n {contextColumns.includes(col.name)\n ? 'bg-purple-100 border-purple-300 text-purple-700'\n : 'bg-white border-gray-200 text-gray-600 hover:border-gray-300'}\"\n >\n {col.name}\n {#if isVirtual(col.name)}\n *\n {/if}\n \n {/each}\n
\n {/if}\n
\n
\n\n \n
\n

{$t.translate?.config?.target_table_title}

\n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n \n {#each databases as db}\n \n {/each}\n \n {#if databasesLoading}\n

{$t.translate?.config?.loading_databases}

\n {:else if !environmentId}\n

{$t.translate?.config?.select_environment}

\n {:else}\n

{$t.translate?.config?.target_database_hint}

\n {/if}\n
\n
\n\n \n
\n

Target Column Mapping

\n

Configure which columns receive translated data, language codes, source text, and detected source language during INSERT.

\n
\n
\n \n \n

{$t.translate?.config?.target_column_hint}

\n
\n
\n \n \n

{$t.translate?.config?.target_language_column_hint}

\n
\n
\n \n \n

{$t.translate?.config?.target_source_column_hint}

\n
\n
\n \n \n

{$t.translate?.config?.target_source_language_column_hint}

\n
\n
\n
\n
\n\n \n
\n

{$t.translate?.config?.llm_settings}

\n
\n
\n \n \n
\n
\n \n {#if targetLanguages.length === 0}\n

Select at least one target language

\n {/if}\n
\n
\n \n \n
\n
\n \n \n
\n
\n \n
\n \n
\n\n \n
\n \n
\n
\n\n \n
\n

{$t.translate?.config?.terminology_dictionaries}

\n {#if availableDictionaries.length === 0}\n

\n {$t.translate?.config?.no_dictionaries}\n

\n {:else}\n
\n {#each availableDictionaries as dict}\n \n {/each}\n
\n {/if}\n
\n
\n\n
\n\n \n
\n
\n \n
\n
\n\n \n
\n {#if !isNewJob && existingJob}\n
\n

{$t.translate?.preview?.title}

\n \n
\n {:else}\n
\n

{$t.translate?.config?.save} {$t.translate?.config?.basic_info?.toLowerCase?.() || 'Save the job first'}

\n
\n {/if}\n
\n\n \n
\n {#if !isNewJob && existingJob}\n
\n

{$t.translate?.config?.run_translation}

\n\n \n
\n {$t.translate?.config?.status}:\n \n {status || 'DRAFT'}\n \n {#if status === 'DRAFT'}\n {\n try {\n await updateJob(jobId, { status: 'READY' });\n status = 'READY';\n addToast($t.translate?.config?.job_updated, 'success');\n } catch (e) {\n addToast(e?.message || 'Failed to update status', 'error');\n }\n }}\n class=\"ml-auto px-3 py-1 text-xs bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors\"\n >\n Mark as READY\n \n {/if}\n
\n\n
\n \n
\n \n
\n
\n
\n \n \n \n
\n
\n

{$t.translate?.config?.run_incremental}

\n

{$t.translate?.config?.run_incremental_desc}

\n handleTriggerRun(false)}\n disabled={isRunning || status === 'DRAFT'}\n class=\"mt-3 px-5 py-1.5 text-sm font-medium bg-green-600 text-white rounded-lg hover:bg-green-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n {isRunning && !isFullRun ? $t.translate?.config?.running : $t.translate?.config?.run_translation}\n \n
\n
\n
\n\n \n
\n
\n
\n \n \n \n
\n
\n

{$t.translate?.config?.run_full}

\n

{$t.translate?.config?.run_full_desc}

\n handleTriggerRun(true)}\n disabled={isRunning || status === 'DRAFT'}\n class=\"mt-3 px-5 py-1.5 text-sm font-medium bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n {isRunning && isFullRun ? $t.translate?.config?.running : $t.translate?.config?.full_translate}\n \n
\n
\n
\n
\n\n {#if runError}\n
\n

{runError}

\n
\n {/if}\n\n {#if currentRunId}\n \n {/if}\n\n {#if completedRuns.length > 0}\n
\n
\n

{$t.translate?.config?.recent_runs}

\n showPageBulkReplace = true}\n class=\"px-3 py-1.5 text-xs bg-indigo-600 text-white rounded hover:bg-indigo-700 transition-colors\"\n >\n {$t.translate?.run?.bulk_replace || 'Bulk Replace'}\n \n
\n
\n {#each completedRuns as run}\n \n {/each}\n
\n
\n {/if}\n
\n
\n {:else}\n
\n

{$t.translate?.config?.save} {$t.translate?.config?.basic_info?.toLowerCase?.() || 'Save the job first'}

\n
\n {/if}\n
\n {/if}\n
\n\n showPageBulkReplace = false}\n\tonApplied={(count) => { showPageBulkReplace = false; loadRunHistory(); }}\n/>\n\n" + "body": "\n\n\n * LLM provider selection, target language, prompt settings, and dictionary attachment.\n * @LAYER UI\n * @RELATION DEPENDS_ON -> [TranslateApi]\n * @RELATION DEPENDS_ON -> [api_module]\n * @PRE Route param id may be \"new\" for create mode or a valid job UUID for edit mode.\n * @POST Job is created or updated with all configuration persisted.\n *\n * @UX_STATE idle -> Initial state before loading\n * @UX_STATE loading -> Fetching job data (edit mode) or datasource metadata\n * @UX_STATE configured -> Form is ready with loaded data\n * @UX_STATE saving -> Save operation in progress\n * @UX_STATE validation_error -> Form validation failure\n * @UX_STATE datasource_unavailable -> Selected datasource cannot be reached\n *\n * @UX_REACTIVITY columnList is $derived from selected datasource\n */\n\n import { onMount, onDestroy } from 'svelte';\n import { goto } from '$app/navigation';\n import { page } from '$app/state';\n import { t, _ } from '$lib/i18n';\n import { addToast } from '$lib/toasts.js';\n import { api } from '$lib/api.js';\n import {\n fetchJobs,\n createJob,\n updateJob,\n fetchDatasourceColumns,\n fetchDatasources,\n } from '$lib/api/translate.js';\n import MultiSelect from '$lib/components/ui/MultiSelect.svelte';\n import TranslationPreview from '$lib/components/translate/TranslationPreview.svelte';\n import TranslationRunProgress from '$lib/components/translate/TranslationRunProgress.svelte';\n import TranslationRunResult from '$lib/components/translate/TranslationRunResult.svelte';\n import ScheduleConfig from '$lib/components/translate/ScheduleConfig.svelte';\n\timport { triggerRun, fetchRunHistory, cancelRun } from '$lib/api/translate.js';\n\timport BulkReplaceModal from '$lib/components/translate/BulkReplaceModal.svelte';\n\timport { fromStore } from 'svelte/store';\n\timport {\n\t\ttranslationRunStore,\n\t\tstartTranslationRun,\n\t\tresetTranslationRun,\n\t\tclearOnCompleteCallback,\n\t} from '$lib/stores/translationRun.js';\n\n const LANGUAGE_LABELS = {\n ru: 'Русский',\n en: 'English',\n de: 'Deutsch',\n fr: 'Français',\n es: 'Español',\n it: 'Italiano',\n pt: 'Português',\n zh: '中文',\n ja: '日本語',\n ko: '한국어',\n ar: 'العربية',\n tr: 'Türkçe',\n nl: 'Nederlands',\n pl: 'Polski',\n sv: 'Svenska',\n da: 'Dansk',\n fi: 'Suomi',\n cs: 'Čeština',\n hu: 'Magyar',\n ro: 'Română',\n vi: 'Tiếng Việt',\n th: 'ไทย',\n he: 'עברית',\n id: 'Bahasa Indonesia',\n ms: 'Bahasa Melayu',\n };\n\n const LANGUAGES = Object.entries(LANGUAGE_LABELS).map(([code, name]) => ({ code, name }));\n\n /** @type {string} idle | loading | configured | saving | validation_error | datasource_unavailable */\n let uxState = $state('idle');\n let isNewJob = $derived(page.params.id === 'new');\n let jobId = $derived(page.params.id);\n let existingJob = $state(null);\n let error = $state(null);\n\n // Form state\n let name = $state('');\n let description = $state('');\n let sourceDialect = $state('postgresql');\n let targetDialect = $state('postgresql');\n let sourceDatasourceId = $state('');\n let sourceTable = $state('');\n let targetSchema = $state('');\n let targetTable = $state('');\n let sourceKeyCols = $state([]);\n let targetKeyCols = $state([]);\n let translationColumn = $state('');\n let targetColumn = $state('');\n let targetLanguageColumn = $state('');\n let targetSourceColumn = $state('');\n let targetSourceLanguageColumn = $state('');\n let contextColumns = $state([]);\n let targetLanguages = $state(['en']);\n let includeSourceReference = $state(true);\n let providerId = $state('');\n let batchSize = $state(50);\n let disableReasoning = $state(false);\n let upsertStrategy = $state('MERGE');\n let dictionaryIds = $state([]);\n let status = $state('DRAFT');\n\n // Datasource & env state\n let environmentId = $state('');\n let environments = $state([]);\n let datasourceId = $state('');\n let datasourceSearch = $state('');\n let datasourceList = $state([]);\n let datasourceLoading = $state(false);\n let showDatasourceDropdown = $state(false);\n let availableColumns = $state([]);\n let virtualColumns = $state([]);\n let databaseDialect = $state('');\n let isColumnsLoading = $state(false);\n let llmProviders = $state([]);\n let availableDictionaries = $state([]);\n let targetDatabaseId = $state('');\n let databases = $state([]);\n let databasesLoading = $state(false);\n\n // Tab state\n /** @type {'config'|'preview'|'run'|'schedule'} */\n let activeTab = $state('config');\n let tabs = $derived.by(() => {\n const base = [\n { id: 'config', label: $t.translate?.config?.basic_info || 'Configuration' },\n { id: 'preview', label: $t.translate?.preview?.title || 'Preview' },\n { id: 'run', label: $t.translate?.config?.run_translation || 'Run' },\n ];\n if (!isNewJob && existingJob) {\n base.push({ id: 'schedule', label: $t.translate?.schedule?.tab_label || 'Schedule' });\n }\n return base;\n });\n\n // Derived\n let columnList = $derived(availableColumns);\n let logicalColumns = $derived(availableColumns.filter(c => c.is_physical !== false));\n let virtualColumnNames = $derived(virtualColumns);\n\n let isSaving = $state(false);\n let validationErrors = $state({});\n let warnings = $state([]);\n let pageTitle = $derived.by(() => {\n if (isNewJob) return $t.translate?.config?.new_title || 'New Translation Job';\n const jobName = existingJob?.name || name;\n const base = $t.translate?.config?.edit_title || 'Edit Translation Job';\n return jobName ? `${jobName} | ${base}` : base;\n });\n\n // Run state — using global store to survive page navigation\n let runState = fromStore(translationRunStore);\n let currentRunId = $derived(runState.current?.runId || null);\n let completedRuns = $state([]);\n let isRunning = $state(false);\n let isFullRun = $state(false);\n\tlet runError = $state('');\n\tlet showPageBulkReplace = $state(false);\n\n async function handleTriggerRun(full = false) {\n isRunning = true;\n isFullRun = full;\n runError = '';\n try {\n const run = await triggerRun(jobId, full);\n startTranslationRun(run.id, { jobId, isFullRun: full, onComplete: handleRunComplete });\n addToast(full ? 'Полный перевод запущен (все строки)' : _('translate.config.run_started'), 'success');\n } catch (err) {\n runError = err?.message || _('translate.config.run_failed');\n isRunning = false;\n }\n }\n\n function handleRunComplete(statusData) {\n if (!isRunning) return; // Idempotent: already handled\n isRunning = false;\n // Don't resetTranslationRun() here — the store's own polling detects the\n // terminal state and stops automatically, keeping the terminal UX visible\n // in the global indicator (TranslationRunGlobalIndicator) until auto-dismiss.\n loadRunHistory();\n const statusLabel = statusData?.status || _('translate.run.completed');\n addToast(`${_('translate.run.run_id')} ${statusLabel.toLowerCase()}`, 'info');\n }\n\n async function loadRunHistory() {\n try {\n const data = await fetchRunHistory(jobId, { page_size: 5 });\n completedRuns = data?.items || [];\n } catch (_err) {\n completedRuns = [];\n }\n }\n\n async function handleRetryRun() {\n if (currentRunId) {\n try {\n await cancelRun(currentRunId);\n } catch (_e) { /* ignore */ }\n }\n resetTranslationRun();\n await handleTriggerRun();\n }\n\n async function handleRetryInsert() {\n if (currentRunId) {\n try {\n const result = await api.postApi(`/translate/runs/${currentRunId}/retry-insert`, {});\n addToast(_('translate.config.insert_retry_started'), 'success');\n } catch (err) {\n addToast(err?.message || _('translate.config.insert_retry_failed'), 'error');\n }\n }\n }\n\n onMount(async () => {\n // Load environments first\n try {\n const envs = await api.getEnvironments?.() || [];\n environments = Array.isArray(envs) ? envs : [];\n if (environments.length > 0 && !environmentId) {\n environmentId = environments[0]?.id || '';\n }\n } catch (_e) {}\n\n await loadInitialData();\n if (!isNewJob) {\n await loadJob();\n } else {\n if (environmentId) {\n await loadDatabases();\n }\n uxState = 'configured';\n }\n });\n\n // Clean up store callback when page unmounts — the store keeps\n // polling so the global indicator in the layout still works.\n onDestroy(() => {\n clearOnCompleteCallback();\n });\n\n /** @returns {Promise} */\n async function loadInitialData() {\n try {\n // Load LLM providers\n try {\n const consolidated = await api.getConsolidatedSettings?.() || {};\n llmProviders = consolidated.llm_providers || [];\n // Also try settings endpoint\n if (llmProviders.length === 0 && api.getLlmStatus) {\n const llmStatus = await api.getLlmStatus().catch(() => ({}));\n if (llmStatus?.providers) {\n llmProviders = llmStatus.providers;\n }\n }\n } catch (_e) {\n llmProviders = [];\n }\n\n // Load dictionaries (from available translate dictionaries)\n try {\n const result = await api.fetchApi('/translate/dictionaries').catch(() => ({}));\n availableDictionaries = Array.isArray(result) ? result : (result?.items || []);\n } catch (_e) {\n availableDictionaries = [];\n }\n } catch (err) {\n console.warn('[translate/config] Failed to load some initial data:', err);\n }\n }\n\n /** @returns {Promise} */\n async function loadJob() {\n uxState = 'loading';\n try {\n const jobs = await fetchJobs({ page_size: 100 });\n const jobsArr = Array.isArray(jobs) ? jobs : (jobs?.results || []);\n const job = jobsArr.find(j => j.id === jobId);\n if (!job) {\n // Try direct fetch\n try {\n const directJob = await api.fetchApi(`/translate/jobs/${jobId}`);\n existingJob = directJob;\n } catch (_e) {\n error = _('translate.config.job_not_found').replace('{id}', jobId);\n uxState = 'error';\n return;\n }\n } else {\n existingJob = job;\n }\n\n // Populate form\n const j = existingJob;\n name = j.name || '';\n description = j.description || '';\n sourceDialect = j.source_dialect || 'postgresql';\n targetDialect = j.target_dialect || 'postgresql';\n sourceDatasourceId = j.source_datasource_id || '';\n sourceTable = j.source_table || '';\n targetSchema = j.target_schema || '';\n targetTable = j.target_table || '';\n sourceKeyCols = j.source_key_cols || [];\n targetKeyCols = j.target_key_cols || [];\n translationColumn = j.translation_column || '';\n targetColumn = j.target_column || '';\n targetLanguageColumn = j.target_language_column || '';\n targetSourceColumn = j.target_source_column || '';\n targetSourceLanguageColumn = j.target_source_language_column || '';\n contextColumns = j.context_columns || [];\n targetLanguages = j.target_languages?.length > 0 ? j.target_languages : (j.target_language ? [j.target_language] : ['en']);\n providerId = j.provider_id || '';\n batchSize = j.batch_size || 50;\n disableReasoning = j.disable_reasoning || false;\n upsertStrategy = j.upsert_strategy || 'MERGE';\n dictionaryIds = j.dictionary_ids || [];\n status = j.status || 'DRAFT';\n\n // Restore target database\n if (j.target_database_id) {\n targetDatabaseId = j.target_database_id;\n }\n\n // Load databases for the environment\n if (j.environment_id) {\n await loadDatabases();\n }\n\n // If there's a datasource, load its columns\n if (j.source_datasource_id && environments.length > 0) {\n datasourceId = j.source_datasource_id;\n // Restore the search display from saved table info\n if (j.source_table) {\n const dialect = j.database_dialect || '';\n datasourceSearch = dialect\n ? `${j.source_table} (${dialect})`\n : j.source_table;\n } else {\n datasourceSearch = `Dataset #${j.source_datasource_id}`;\n }\n // Restore environment from stored job, fall back to first available\n if (j.environment_id && environments.some(e => e.id === j.environment_id)) {\n environmentId = j.environment_id;\n } else {\n environmentId = environments[0]?.id || '';\n }\n await loadColumnsForDatasource();\n }\n\n uxState = 'configured';\n // Load run history\n await loadRunHistory();\n } catch (err) {\n error = err?.message || 'Failed to load job';\n uxState = 'error';\n }\n }\n\n /** @returns {Promise} */\n async function loadColumnsForDatasource() {\n if (!datasourceId || !environmentId) {\n availableColumns = [];\n virtualColumns = [];\n return;\n }\n\n isColumnsLoading = true;\n try {\n const result = await fetchDatasourceColumns(parseInt(datasourceId), environmentId);\n if (result) {\n availableColumns = result.columns || [];\n databaseDialect = result.database_dialect || '';\n virtualColumns = availableColumns.filter(c => c.is_physical === false).map(c => c.name);\n }\n } catch (err) {\n uxState = 'datasource_unavailable';\n addToast(`${_('common.error')}: ${err?.message}`, 'error');\n } finally {\n isColumnsLoading = false;\n }\n }\n\n /** Load all datasets (or search) */\n async function searchDatasources(searchTerm = '') {\n if (!environmentId) return;\n datasourceLoading = true;\n try {\n datasourceList = await fetchDatasources(environmentId, searchTerm);\n showDatasourceDropdown = true;\n } catch (err) {\n datasourceList = [];\n } finally {\n datasourceLoading = false;\n }\n }\n\n async function handleDatasourceSearch() {\n await searchDatasources(datasourceSearch);\n }\n\n /** Select a dataset from the dropdown */\n function selectDatasource(ds) {\n datasourceId = String(ds.id);\n datasourceSearch = `${ds.table_name} (${ds.database_name} · ${ds.database_dialect})`;\n showDatasourceDropdown = false;\n availableColumns = [];\n virtualColumns = [];\n sourceKeyCols = [];\n targetKeyCols = [];\n translationColumn = '';\n targetColumn = '';\n targetLanguageColumn = '';\n targetSourceColumn = '';\n targetSourceLanguageColumn = '';\n contextColumns = [];\n databaseDialect = ds.database_dialect || '';\n if (datasourceId && environmentId) {\n loadColumnsForDatasource();\n }\n }\n\n /** @param {Event} event */\n async function handleDatasourceChange(event) {\n const val = event.target.value;\n datasourceId = val;\n availableColumns = [];\n virtualColumns = [];\n // Reset column selections when datasource changes\n sourceKeyCols = [];\n targetKeyCols = [];\n translationColumn = '';\n contextColumns = [];\n\n if (val && environmentId) {\n await loadColumnsForDatasource();\n }\n }\n\n async function loadDatabases() {\n if (!environmentId) {\n databases = [];\n return;\n }\n databasesLoading = true;\n try {\n databases = await api.getEnvironmentDatabases(environmentId) || [];\n } catch (_e) {\n databases = [];\n } finally {\n databasesLoading = false;\n }\n }\n\n /** @param {Event} event */\n async function handleEnvChange(event) {\n const newEnv = event.target.value;\n environmentId = newEnv;\n // Clear search state, but KEEP datasourceId if already loaded from job\n // — just reload columns with the new environment\n datasourceSearch = '';\n datasourceList = [];\n databaseDialect = '';\n targetDatabaseId = '';\n await loadDatabases();\n if (datasourceId) {\n await loadColumnsForDatasource();\n }\n }\n\n /** @param {string} col */\n function toggleContextColumn(col) {\n if (contextColumns.includes(col)) {\n contextColumns = contextColumns.filter(c => c !== col);\n } else {\n contextColumns = [...contextColumns, col];\n }\n }\n\n /** @param {string} col */\n function toggleSourceKeyCol(col) {\n const idx = sourceKeyCols.indexOf(col);\n if (idx >= 0) {\n sourceKeyCols = sourceKeyCols.filter((_, i) => i !== idx);\n // Also remove corresponding target key\n if (targetKeyCols[idx]) {\n targetKeyCols = targetKeyCols.filter((_, i) => i !== idx);\n }\n } else {\n sourceKeyCols = [...sourceKeyCols, col];\n targetKeyCols = [...targetKeyCols, ''];\n }\n }\n\n /** @param {number} idx @param {string} val */\n function updateTargetKeyCol(idx, val) {\n const updated = [...targetKeyCols];\n updated[idx] = val;\n targetKeyCols = updated;\n }\n\n /** @returns {string[]} */\n function validate() {\n const errs = {};\n const warns = [];\n\n if (!name.trim()) {\n errs.name = _('translate.config.name_required');\n }\n\n if (targetLanguages.length === 0) {\n errs.targetLanguages = 'At least one target language is required';\n }\n\n if (!translationColumn) {\n errs.translationColumn = _('translate.config.translation_column_required');\n }\n\n if (sourceKeyCols.length > 0 && sourceKeyCols.some((_, i) => !targetKeyCols[i])) {\n errs.targetKeyCols = _('translate.config.key_mapping_required');\n }\n\n // Warn about virtual key columns\n for (const col of sourceKeyCols) {\n if (virtualColumnNames.includes(col)) {\n warns.push(_('translate.config.virtual_column_warning').replace('{col}', col));\n }\n }\n\n // Check duplicate column mapping\n if (contextColumns.includes(translationColumn)) {\n warns.push(_('translate.config.redundant_column_warning'));\n }\n\n validationErrors = errs;\n warnings = warns;\n return Object.keys(errs);\n }\n\n /** @returns {Promise} */\n async function handleSave() {\n const errs = validate();\n if (errs.length > 0) {\n uxState = 'validation_error';\n return;\n }\n\n isSaving = true;\n uxState = 'saving';\n const payload = {\n name: name.trim(),\n description: description.trim() || null,\n source_dialect: sourceDialect,\n target_dialect: targetDialect,\n source_datasource_id: datasourceId || null,\n source_table: sourceTable || null,\n target_schema: targetSchema || null,\n target_table: targetTable || null,\n source_key_cols: sourceKeyCols,\n target_key_cols: targetKeyCols,\n translation_column: translationColumn || null,\n target_column: targetColumn || null,\n target_language_column: targetLanguageColumn || null,\n target_source_column: targetSourceColumn || null,\n target_source_language_column: targetSourceLanguageColumn || null,\n context_columns: contextColumns,\n target_languages: targetLanguages?.length > 0 ? targetLanguages : null,\n provider_id: providerId || null,\n batch_size: parseInt(batchSize) || 50,\n disable_reasoning: disableReasoning,\n upsert_strategy: upsertStrategy,\n dictionary_ids: dictionaryIds,\n database_dialect: databaseDialect || sourceDialect,\n environment_id: environmentId || null,\n target_database_id: targetDatabaseId || null,\n status: status,\n };\n\n try {\n if (isNewJob) {\n const created = await createJob(payload);\n addToast(_('translate.config.job_created'), 'success');\n goto(`/translate/${created.id}`);\n } else {\n await updateJob(jobId, payload);\n addToast(_('translate.config.job_updated'), 'success');\n uxState = 'configured';\n }\n } catch (err) {\n addToast(err?.message || _('translate.config.save_failed'), 'error');\n uxState = 'validation_error';\n } finally {\n isSaving = false;\n }\n }\n\n /** @param {string} col */\n function isVirtual(col) {\n return virtualColumnNames.includes(col);\n }\n\n function getJobStatusLabel(value) {\n const labels = {\n DRAFT: $t.translate?.config?.status_draft || 'Draft',\n READY: $t.translate?.config?.status_ready || 'Ready',\n ACTIVE: $t.translate?.config?.status_active || 'Active',\n RUNNING: $t.translate?.jobs?.status_running || 'Running',\n COMPLETED: $t.translate?.jobs?.status_completed || 'Completed',\n FAILED: $t.translate?.jobs?.status_failed || 'Failed',\n CANCELLED: $t.translate?.history?.status_cancelled || 'Cancelled',\n };\n return labels[value] || value || ($t.translate?.config?.status_draft || 'Draft');\n }\n\n\n\n {pageTitle}\n\n\n
\n \n
\n
\n

\n {isNewJob ? $t.translate?.config?.new_title : $t.translate?.config?.edit_title}\n

\n {#if !isNewJob && existingJob}\n

{$t.translate?.config?.id_label.replace('{id}', existingJob.id)}

\n {/if}\n
\n
\n goto('/translate')}\n class=\"px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors\"\n >\n {$t.translate?.config?.cancel}\n \n \n {isSaving ? $t.translate?.config?.saving : $t.translate?.config?.save}\n \n
\n
\n\n \n {#if warnings.length > 0}\n
\n

{$t.translate?.config?.warnings_title}

\n
    \n {#each warnings as w}\n
  • {w}
  • \n {/each}\n
\n
\n {/if}\n\n \n {#if uxState === 'loading'}\n
\n {#each Array(6) as _}\n
\n {/each}\n
\n\n \n {:else if uxState === 'error'}\n
\n

{error || $t.translate?.common?.unknown_error}

\n goto('/translate')}\n class=\"px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors\"\n >\n {$t.translate?.config?.back_to_jobs}\n \n
\n\n \n {:else if uxState === 'datasource_unavailable'}\n
\n

\n {$t.translate?.config?.datasource_unavailable}\n

\n
\n\n \n {:else if uxState === 'configured' || uxState === 'saving' || uxState === 'validation_error' || uxState === 'idle'}\n \n
\n \n
\n\n \n
\n
\n \n
\n

{$t.translate?.config?.basic_info}

\n
\n
\n \n \n {#if validationErrors.name}\n

{validationErrors.name}

\n {/if}\n
\n
\n \n \n
\n
\n
\n\n \n
\n

{$t.translate?.config?.datasource}

\n
\n
\n \n \n \n {#each environments as env}\n \n {/each}\n \n
\n
\n \n searchDatasources('')}\n onblur={() => setTimeout(() => (showDatasourceDropdown = false), 150)}\n class=\"w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500\"\n placeholder={$t.translate?.config?.datasource_search_placeholder || 'Search datasets...'}\n />\n {#if datasourceLoading}\n
\n {/if}\n {#if showDatasourceDropdown}\n
\n {#each datasourceList as ds}\n selectDatasource(ds)}\n class=\"w-full text-left px-3 py-2 text-sm hover:bg-blue-50 border-b border-gray-100 last:border-b-0\"\n >\n {ds.table_name}\n {ds.schema}\n {ds.database_name} · {ds.database_dialect}\n \n {/each}\n
\n {/if}\n
\n {#if databaseDialect}\n
\n \n {$t.translate?.config?.detected_dialect.replace('{dialect}', databaseDialect)}\n \n
\n {/if}\n
\n\n {#if isColumnsLoading}\n
\n {/if}\n\n {#if columnList.length > 0}\n
\n \n
\n {#each columnList as col}\n
\n {col.name}\n {#if col.type}\n ({col.type})\n {/if}\n {#if isVirtual(col.name)}\n {$t.translate?.config?.virtual}\n {/if}\n
\n {/each}\n
\n
\n {/if}\n
\n\n \n
\n

{$t.translate?.config?.column_mapping}

\n\n \n
\n \n \n \n {#each columnList as col}\n \n {/each}\n \n {#if validationErrors.translationColumn}\n

{validationErrors.translationColumn}

\n {/if}\n
\n\n \n
\n
\n \n \n
\n
\n \n \n
\n
\n\n \n
\n
\n \n {#if sourceKeyCols.length > 0}\n { sourceKeyCols = []; targetKeyCols = []; }}\n class=\"text-xs text-red-600 hover:text-red-700\"\n >\n {$t.translate?.config?.clear_all}\n \n {/if}\n
\n\n {#if columnList.length === 0}\n
\n {\n sourceKeyCols = [...sourceKeyCols, ''];\n targetKeyCols = [...targetKeyCols, ''];\n }}\n class=\"px-3 py-1 text-xs border border-dashed border-gray-300 rounded text-gray-500 hover:border-blue-300 hover:text-blue-600\"\n >\n {$t.translate?.config?.add_key_column}\n \n
\n {:else}\n
\n {#each columnList as col}\n toggleSourceKeyCol(col.name)}\n class=\"px-2.5 py-1 text-xs rounded-full border transition-colors\n {sourceKeyCols.includes(col.name)\n ? 'bg-blue-100 border-blue-300 text-blue-700'\n : 'bg-white border-gray-200 text-gray-600 hover:border-gray-300'}\"\n title={isVirtual(col.name) ? $t.translate?.config?.virtual_column_warning.replace('{col}', col.name) : ''}\n >\n {col.name}\n {#if isVirtual(col.name)}\n *\n {/if}\n \n {/each}\n
\n {/if}\n\n {#if sourceKeyCols.length > 0}\n
\n {#each sourceKeyCols as srcCol, idx}\n
\n \n \n updateTargetKeyCol(idx, e.target.value)}\n class=\"flex-1 px-3 py-1.5 border border-gray-300 rounded text-sm font-mono focus:ring-2 focus:ring-blue-500\"\n />\n {\n sourceKeyCols = sourceKeyCols.filter((_, i) => i !== idx);\n targetKeyCols = targetKeyCols.filter((_, i) => i !== idx);\n }}\n class=\"p-1 text-gray-400 hover:text-red-500\"\n >\n \n \n \n \n
\n {/each}\n
\n {/if}\n {#if validationErrors.targetKeyCols}\n

{validationErrors.targetKeyCols}

\n {/if}\n
\n\n \n
\n \n {#if columnList.length === 0}\n

{$t.translate?.config?.select_datasource_hint}

\n {:else}\n
\n {#each columnList as col}\n toggleContextColumn(col.name)}\n class=\"px-2.5 py-1 text-xs rounded-full border transition-colors\n {contextColumns.includes(col.name)\n ? 'bg-purple-100 border-purple-300 text-purple-700'\n : 'bg-white border-gray-200 text-gray-600 hover:border-gray-300'}\"\n >\n {col.name}\n {#if isVirtual(col.name)}\n *\n {/if}\n \n {/each}\n
\n {/if}\n
\n
\n\n \n
\n

{$t.translate?.config?.target_table_title}

\n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n \n {#each databases as db}\n \n {/each}\n \n {#if databasesLoading}\n

{$t.translate?.config?.loading_databases}

\n {:else if !environmentId}\n

{$t.translate?.config?.select_environment}

\n {:else}\n

{$t.translate?.config?.target_database_hint}

\n {/if}\n
\n
\n\n \n
\n

{$t.translate?.config?.target_column_mapping_title || 'Target Column Mapping'}

\n

{$t.translate?.config?.target_column_mapping_description || 'Configure which columns receive translated data, language codes, source text, and detected source language during INSERT.'}

\n
\n
\n \n \n

{$t.translate?.config?.target_column_hint}

\n
\n
\n \n \n

{$t.translate?.config?.target_language_column_hint}

\n
\n
\n \n \n

{$t.translate?.config?.target_source_column_hint}

\n
\n
\n \n \n

{$t.translate?.config?.target_source_language_column_hint}

\n
\n
\n
\n
\n\n \n
\n

{$t.translate?.config?.llm_settings}

\n
\n
\n \n \n
\n
\n \n {#if targetLanguages.length === 0}\n

{$t.translate?.config?.target_language_required || 'Select at least one target language'}

\n {/if}\n
\n
\n \n \n
\n
\n \n \n
\n
\n \n
\n \n
\n\n \n
\n \n
\n
\n\n \n
\n

{$t.translate?.config?.terminology_dictionaries}

\n {#if availableDictionaries.length === 0}\n

\n {$t.translate?.config?.no_dictionaries}\n

\n {:else}\n
\n {#each availableDictionaries as dict}\n \n {/each}\n
\n {/if}\n
\n
\n\n
\n\n \n
\n
\n \n
\n
\n\n \n
\n {#if !isNewJob && existingJob}\n
\n

{$t.translate?.preview?.title}

\n \n
\n {:else}\n
\n

{$t.translate?.config?.save_job_first || 'Save the job first'}

\n
\n {/if}\n
\n\n \n
\n {#if !isNewJob && existingJob}\n
\n

{$t.translate?.config?.run_translation}

\n\n \n
\n {$t.translate?.config?.status}:\n \n {getJobStatusLabel(status)}\n \n {#if status === 'DRAFT'}\n {\n try {\n await updateJob(jobId, { status: 'READY' });\n status = 'READY';\n addToast($t.translate?.config?.job_updated, 'success');\n } catch (e) {\n addToast(e?.message || 'Failed to update status', 'error');\n }\n }}\n class=\"ml-auto px-3 py-1 text-xs bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors\"\n >\n {$t.translate?.config?.mark_ready || 'Mark as READY'}\n \n {/if}\n
\n\n
\n \n
\n \n
\n
\n
\n \n \n \n
\n
\n

{$t.translate?.config?.run_incremental}

\n

{$t.translate?.config?.run_incremental_desc}

\n handleTriggerRun(false)}\n disabled={isRunning || status === 'DRAFT'}\n class=\"mt-3 px-5 py-1.5 text-sm font-medium bg-green-600 text-white rounded-lg hover:bg-green-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n {isRunning && !isFullRun ? $t.translate?.config?.running : $t.translate?.config?.run_translation}\n \n
\n
\n
\n\n \n
\n
\n
\n \n \n \n
\n
\n

{$t.translate?.config?.run_full}

\n

{$t.translate?.config?.run_full_desc}

\n handleTriggerRun(true)}\n disabled={isRunning || status === 'DRAFT'}\n class=\"mt-3 px-5 py-1.5 text-sm font-medium bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n {isRunning && isFullRun ? $t.translate?.config?.running : $t.translate?.config?.full_translate}\n \n
\n
\n
\n
\n\n {#if runError}\n
\n

{runError}

\n
\n {/if}\n\n {#if currentRunId}\n \n {/if}\n\n {#if completedRuns.length > 0}\n
\n
\n

{$t.translate?.config?.recent_runs}

\n showPageBulkReplace = true}\n class=\"px-3 py-1.5 text-xs bg-indigo-600 text-white rounded hover:bg-indigo-700 transition-colors\"\n >\n {$t.translate?.run?.bulk_replace || 'Bulk Replace'}\n \n
\n
\n {#each completedRuns as run}\n \n {/each}\n
\n
\n {/if}\n
\n
\n {:else}\n
\n

{$t.translate?.config?.save_job_first || 'Save the job first'}

\n
\n {/if}\n
\n {/if}\n
\n\n showPageBulkReplace = false}\n\tonApplied={(count) => { showPageBulkReplace = false; loadRunHistory(); }}\n/>\n\n" }, { "contract_id": "TranslateHistoryPage", "contract_type": "Page", "file_path": "frontend/src/routes/translate/history/+page.svelte", "start_line": 1, - "end_line": 537, + "end_line": 560, "tier": "TIER_2", "complexity": 3, "metadata": { "COMPLEXITY": 3, - "LAYER": "UI", - "PURPOSE": "Filterable run history page with click-to-expand detail view, metrics summary.", - "UX_STATE": "pruned -> Data older than 90 days; MetricSnapshot referenced" + "PURPOSE": "Page component: routes/translate/history/+page.svelte", + "TYPE": "{'idle'|'loading'|'empty'|'populated'|'detail_open'|'pruned'}" }, - "relations": [ - { - "source_id": "TranslateHistoryPage", - "relation_type": "DEPENDS_ON", - "target_id": "TranslateApi", - "target_ref": "[TranslateApi]" - } - ], + "relations": [], "schema_warnings": [ { "code": "tag_not_for_contract_type", @@ -103500,28 +102230,6 @@ "contract_type": "Page" } }, - { - "code": "tag_not_for_contract_type", - "tag": "LAYER", - "message": "@LAYER is not allowed for contract type 'Page'", - "detail": { - "actual_type": "Page", - "allowed_types": [ - "Module", - "Skill", - "Agent" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "LAYER", - "message": "@LAYER is forbidden for contract type 'Page' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Page" - } - }, { "code": "tag_not_for_contract_type", "tag": "PURPOSE", @@ -103550,38 +102258,15 @@ } }, { - "code": "tag_not_for_contract_type", - "tag": "UX_STATE", - "message": "@UX_STATE is not allowed for contract type 'Page'", - "detail": { - "actual_type": "Page", - "allowed_types": [ - "Component" - ] - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "UX_STATE", - "message": "@UX_STATE is forbidden for contract type 'Page' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Page" - } - }, - { - "code": "tag_forbidden_by_complexity", - "tag": "RELATION", - "message": "@RELATION is forbidden for contract type 'Page' at C3", - "detail": { - "actual_complexity": 3, - "contract_type": "Page" - } + "code": "unknown_tag", + "tag": "TYPE", + "message": "@TYPE is not defined in axiom_config.yaml tags", + "detail": null } ], "anchor_syntax": "region", "tier_source": "AutoCalculated", - "body": "\n\n\n\n\n
\n\t
\n\t\t
\n\t\t\t

{$t.translate?.history?.title}

\n\t\t\t

{$t.translate?.history?.subtitle}

\n\t\t
\n\t\t\n\t
\n\n\t\n\t{#if totalMetric()}\n\t\t
\n\t\t\t
\n\t\t\t\t

{$t.translate?.history?.total_runs}

\n\t\t\t\t

{totalMetric().total_runs}

\n\t\t\t
\n\t\t\t
\n\t\t\t\t

{$t.translate?.history?.successful}

\n\t\t\t\t

{totalMetric().successful_runs}

\n\t\t\t
\n\t\t\t
\n\t\t\t\t

{$t.translate?.history?.failed}

\n\t\t\t\t

{totalMetric().failed_runs}

\n\t\t\t
\n\t\t\t
\n\t\t\t\t

{$t.translate?.history?.records}

\n\t\t\t\t

{totalMetric().total_records}

\n\t\t\t
\n\t\t
\n\t{/if}\n\n\t\n\t
\n\t\t
\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t
\n\t
\n\n\t\n\t{#if isLoading}\n\t\t
\n\t\t\t{#each Array(5) as _}\n\t\t\t\t
\n\t\t\t{/each}\n\t\t
\n\n\t\n\t{:else if uxState === 'empty'}\n\t\t
\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t

{$t.translate?.history?.no_runs}

\n\t\t\t

{$t.translate?.history?.no_runs_hint}

\n\t\t
\n\n\t\n\t{:else if uxState === 'populated' || uxState === 'detail_open'}\n\t\t
\n\t\t\t{#each runs as run}\n\t\t\t\t openDetail(run)}\n\t\t\t\t\tclass=\"bg-white border border-gray-200 rounded-lg p-3 hover:shadow-sm hover:border-gray-300 transition-all cursor-pointer\"\n\t\t\t\t>\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t{getJobName(run.job_id)}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{run.status}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{#if run.trigger_type}\n\t\t\t\t\t\t\t\t\t{run.trigger_type}\n\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t{run.created_at ? new Date(run.created_at).toLocaleString() : ''}\n\t\t\t\t\t\t\t\t{_('translate.history.records_label').replace('{count}', run.total_records || 0)}\n\t\t\t\t\t\t\t\t{_('translate.history.ok_label').replace('{count}', run.successful_records || 0)}\n\t\t\t\t\t\t\t\t{_('translate.history.fail_label').replace('{count}', run.failed_records || 0)}\n\t\t\t\t\t\t\t\t{#if run.created_by}\n\t\t\t\t\t\t\t\t\t{_('translate.history.by_label').replace('{user}', run.created_by)}\n\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{#if run.target_languages && run.target_languages.length > 0}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t{#each run.target_languages as lang}\n\t\t\t\t\t\t\t\t\t\t{lang}\n\t\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t
\n\t\t\t\t\t\t
e.stopPropagation()}>\n\t\t\t\t\t\t\t{#if run.status === 'PENDING' || run.status === 'RUNNING'}\n\t\t\t\t\t\t\t\t handleCancelRun(run.id)}\n\t\t\t\t\t\t\t\t\tdisabled={cancellingRunId === run.id}\n\t\t\t\t\t\t\t\t\tclass=\"px-2 py-1 text-xs bg-red-100 text-red-700 rounded hover:bg-red-200 disabled:opacity-50 transition-colors\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{cancellingRunId === run.id\n\t\t\t\t\t\t\t\t\t\t? ($t.translate?.run?.cancelling || '...')\n\t\t\t\t\t\t\t\t\t\t: ($t.translate?.run?.cancel || 'Cancel')}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t{#if run.status === 'FAILED'}\n\t\t\t\t\t\t\t\t handleRetryRun(run.id)}\n\t\t\t\t\t\t\t\t\tdisabled={retryingRunId === run.id}\n\t\t\t\t\t\t\t\t\tclass=\"px-2 py-1 text-xs bg-amber-100 text-amber-700 rounded hover:bg-amber-200 disabled:opacity-50 transition-colors\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{retryingRunId === run.id\n\t\t\t\t\t\t\t\t\t\t? ($t.translate?.run?.retrying || '...')\n\t\t\t\t\t\t\t\t\t\t: ($t.translate?.run?.retry_failed || 'Retry')}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t{#if run.status === 'COMPLETED' && (run.skipped_records || 0) > 0}\n\t\t\t\t\t\t\t\t handleDownloadSkipped(run.id)}\n\t\t\t\t\t\t\t\t\tclass=\"text-xs text-blue-600 hover:text-blue-700\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{$t.translate?.history?.skipped_csv}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t{/each}\n\t\t
\n\n\t\t\n\t\t
\n\t\t\t

{_('translate.history.showing').replace('{count}', runs.length).replace('{total}', total)}

\n\t\t\t
\n\t\t\t\t { currentPage--; loadRuns(); }}\n\t\t\t\t\tdisabled={currentPage <= 1}\n\t\t\t\t\tclass=\"px-3 py-1.5 text-sm border border-gray-200 rounded-lg disabled:opacity-50\"\n\t\t\t\t>\n\t\t\t\t\t{$t.translate?.history?.previous}\n\t\t\t\t\n\t\t\t\t { currentPage++; loadRuns(); }}\n\t\t\t\t\tdisabled={currentPage * pageSize >= total}\n\t\t\t\t\tclass=\"px-3 py-1.5 text-sm border border-gray-200 rounded-lg disabled:opacity-50\"\n\t\t\t\t>\n\t\t\t\t\t{$t.translate?.history?.next}\n\t\t\t\t\n\t\t\t
\n\t\t
\n\t{/if}\n\n\t\n\t{#if uxState === 'detail_open' && selectedRunDetail}\n\t\t
\n\t\t
\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t

{$t.translate?.history?.run_detail}

\n\t\t\t\t\t\n\t\t\t\t
\n\n\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.history?.status}

\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{selectedRunDetail.status}\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.history?.trigger}

\n\t\t\t\t\t\t

{selectedRunDetail.trigger_type || 'manual'}

\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.history?.started}

\n\t\t\t\t\t\t

{selectedRunDetail.started_at ? new Date(selectedRunDetail.started_at).toLocaleString() : '-'}

\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.history?.completed}

\n\t\t\t\t\t\t

{selectedRunDetail.completed_at ? new Date(selectedRunDetail.completed_at).toLocaleString() : '-'}

\n\t\t\t\t\t
\n\t\t\t\t
\n\n\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t

{selectedRunDetail.total_records || 0}

\n\t\t\t\t\t\t

{$t.translate?.history?.total}

\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t

{selectedRunDetail.successful_records || 0}

\n\t\t\t\t\t\t

{$t.translate?.history?.success}

\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t

{selectedRunDetail.failed_records || 0}

\n\t\t\t\t\t\t

{$t.translate?.history?.failed}

\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t

{selectedRunDetail.skipped_records || 0}

\n\t\t\t\t\t\t

{$t.translate?.history?.skipped}

\n\t\t\t\t\t
\n\t\t\t\t
\n\n\t\t\t\t\n\t\t\t\t{#if selectedRunDetail.language_stats && Object.keys(selectedRunDetail.language_stats).length > 0}\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.run?.per_language}

\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{#each Object.entries(selectedRunDetail.language_stats) as [lang, stats]}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t{lang}\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t{_('translate.run.translated_label').replace('{count}', stats.translated_rows)}\n\t\t\t\t\t\t\t\t\t\t{_('translate.run.failed_label').replace('{count}', stats.failed_rows)}\n\t\t\t\t\t\t\t\t\t\t{_('translate.run.skipped_label').replace('{count}', stats.skipped_rows)}\n\t\t\t\t\t\t\t\t\t\t{_('translate.run.tokens_label').replace('{count}', stats.token_count)}\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t{#if selectedRunDetail.status === 'PENDING' || selectedRunDetail.status === 'RUNNING'}\n\t\t\t\t\t\t handleCancelRun(selectedRunDetail.id)}\n\t\t\t\t\t\t\tdisabled={cancellingRunId === selectedRunDetail.id}\n\t\t\t\t\t\t\tclass=\"px-4 py-2 text-sm bg-red-600 text-white rounded-lg hover:bg-red-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{cancellingRunId === selectedRunDetail.id\n\t\t\t\t\t\t\t\t? ($t.translate?.run?.cancelling || 'Cancelling...')\n\t\t\t\t\t\t\t\t: ($t.translate?.run?.cancel || 'Cancel')}\n\t\t\t\t\t\t\n\t\t\t\t\t{/if}\n\t\t\t\t\t{#if selectedRunDetail.status === 'FAILED'}\n\t\t\t\t\t\t handleRetryRun(selectedRunDetail.id)}\n\t\t\t\t\t\t\tdisabled={retryingRunId === selectedRunDetail.id}\n\t\t\t\t\t\t\tclass=\"px-4 py-2 text-sm bg-amber-600 text-white rounded-lg hover:bg-amber-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{retryingRunId === selectedRunDetail.id\n\t\t\t\t\t\t\t\t? ($t.translate?.run?.retrying || 'Retrying...')\n\t\t\t\t\t\t\t\t: ($t.translate?.run?.retry_failed || 'Retry Failed')}\n\t\t\t\t\t\t\n\t\t\t\t\t{/if}\n\t\t\t\t
\n\n\t\t\t\t\n\t\t\t\t{#if selectedRunDetail.config_snapshot}\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.history?.config_snapshot}

\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
{JSON.stringify(selectedRunDetail.config_snapshot, null, 2)}
\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if selectedRunDetail.config_hash || selectedRunDetail.dict_snapshot_hash}\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.history?.snapshots}

\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{#if selectedRunDetail.config_hash}\n\t\t\t\t\t\t\t\t
Config: {selectedRunDetail.config_hash}
\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t{#if selectedRunDetail.dict_snapshot_hash}\n\t\t\t\t\t\t\t\t
Dict: {selectedRunDetail.dict_snapshot_hash}
\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t{#if selectedRunDetail.key_hash}\n\t\t\t\t\t\t\t\t
Key: {selectedRunDetail.key_hash}
\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if selectedRunDetail.events && selectedRunDetail.events.length > 0}\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.history?.events.replace('{count}', selectedRunDetail.events.length)}

\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{#each selectedRunDetail.events as evt}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t{evt.event_type}\n\t\t\t\t\t\t\t\t\t|\n\t\t\t\t\t\t\t\t\t{evt.created_at ? new Date(evt.created_at).toLocaleString() : ''}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if selectedRunDetail.error_message}\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.history?.error}

\n\t\t\t\t\t\t

{selectedRunDetail.error_message}

\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if selectedRunDetail.superset_execution_id}\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.history?.superset_query_id}

\n\t\t\t\t\t\t

{selectedRunDetail.superset_execution_id}

\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\t\t\t
\n\t\t
\n\t{/if}\n
\n\n" + "body": "\n\n\n\t */\n\timport { onMount } from 'svelte';\n\timport { addToast } from '$lib/toasts.js';\n\timport { t, _ } from '$lib/i18n';\n\timport {\n\t\tfetchAllRuns,\n\t\tfetchRunDetail,\n\t\tfetchAllMetrics,\n\t\tfetchJobs,\n\t\tdownloadSkippedCsv,\n\t\tcancelRun,\n\t\tretryFailedBatches\n\t} from '$lib/api/translate.js';\n\n\t/** @type {'idle'|'loading'|'empty'|'populated'|'detail_open'|'pruned'} */\n\tlet uxState = $state('idle');\n\n\tlet cancellingRunId = $state(null);\n\tlet retryingRunId = $state(null);\n\n\tlet runs = $state([]);\n\tlet total = $state(0);\n\tlet currentPage = $state(1);\n\tlet pageSize = $state(20);\n\tlet selectedRun = $state(null);\n\tlet selectedRunDetail = $state(null);\n\tlet isLoading = $state(false);\n\tlet metrics = $state([]);\n\tlet jobs = $state([]);\n\n\t/** Display-friendly language names keyed by BCP-47 code */\n\tconst LANGUAGE_NAMES = {\n\t\tru: 'Русский',\n\t\ten: 'English',\n\t\tde: 'Deutsch',\n\t\tfr: 'Français',\n\t\tes: 'Español',\n\t\tit: 'Italiano',\n\t\tpt: 'Português',\n\t\tnl: 'Nederlands',\n\t\tpl: 'Polski',\n\t\tcs: 'Čeština',\n\t\tda: 'Dansk',\n\t\tfi: 'Suomi',\n\t\tsv: 'Svenska',\n\t\tnb: 'Norsk Bokmål',\n\t\tuk: 'Українська',\n\t\tja: '日本語',\n\t\tko: '한국어',\n\t\tzh: '中文',\n\t\tar: 'العربية',\n\t\ttr: 'Türkçe',\n\t\tel: 'Ελληνικά',\n\t\tro: 'Română',\n\t\thu: 'Magyar',\n\t\tvi: 'Tiếng Việt',\n\t\tth: 'ไทย',\n\t\the: 'עברית',\n\t};\n\n\tfunction getLanguageName(code) {\n\t\tconst c = String(code);\n\t\treturn LANGUAGE_NAMES[c] || (c.match(/^[a-zA-Z]{2,8}/) ? c : c);\n\t}\n\n\t// Filters\n\tlet filterJobId = $state('');\n\tlet filterStatus = $state('');\n\tlet filterTrigger = $state('');\n\tlet filterDateFrom = $state('');\n\tlet filterDateTo = $state('');\n\n\tonMount(() => {\n\t\tloadRuns();\n\t\tloadMetrics();\n\t\tloadJobs();\n\t});\n\n\tasync function loadRuns() {\n\t\tisLoading = true;\n\t\tuxState = 'loading';\n\t\ttry {\n\t\t\tconst result = await fetchAllRuns({\n\t\t\t\tpage: currentPage,\n\t\t\t\tpage_size: pageSize,\n\t\t\t\tjob_id: filterJobId || undefined,\n\t\t\t\tstatus: filterStatus || undefined,\n\t\t\t\ttrigger_type: filterTrigger || undefined,\n\t\t\t});\n\t\t\truns = result?.items || [];\n\t\t\ttotal = result?.total || 0;\n\t\t\tuxState = runs.length === 0 ? 'empty' : 'populated';\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || _('translate.history.load_failed'), 'error');\n\t\t\tuxState = 'empty';\n\t\t} finally {\n\t\t\tisLoading = false;\n\t\t}\n\t}\n\n\tasync function loadMetrics() {\n\t\ttry {\n\t\t\tmetrics = await fetchAllMetrics();\n\t\t} catch (err) {\n\t\t\t// Non-critical\n\t\t}\n\t}\n\n\tasync function loadJobs() {\n\t\ttry {\n\t\t\tconst result = await fetchJobs({ page_size: 100 });\n\t\t\tjobs = Array.isArray(result) ? result : (result?.items || result?.results || []);\n\t\t} catch (err) {\n\t\t\t// Non-critical\n\t\t}\n\t}\n\n\tasync function openDetail(run) {\n\t\tselectedRun = run;\n\t\tselectedRunDetail = null;\n\t\ttry {\n\t\t\tselectedRunDetail = await fetchRunDetail(run.id);\n\t\t\tuxState = 'detail_open';\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || _('translate.history.load_detail_failed'), 'error');\n\t\t}\n\t}\n\n\tfunction closeDetail() {\n\t\tselectedRun = null;\n\t\tselectedRunDetail = null;\n\t\tuxState = runs.length === 0 ? 'empty' : 'populated';\n\t}\n\n\tfunction applyFilters() {\n\t\tcurrentPage = 1;\n\t\tloadRuns();\n\t}\n\n\tfunction getStatusClass(status) {\n\t\tconst map = {\n\t\t\tPENDING: 'bg-yellow-100 text-yellow-700',\n\t\t\tRUNNING: 'bg-blue-100 text-blue-700',\n\t\t\tCOMPLETED: 'bg-green-100 text-green-700',\n\t\t\tFAILED: 'bg-red-100 text-red-700',\n\t\t\tCANCELLED: 'bg-gray-100 text-gray-500',\n\t\t};\n\t\treturn map[status] || 'bg-gray-100 text-gray-700';\n\t}\n\n\tfunction getJobName(jobId) {\n\t\tconst job = jobs.find(j => j.id === jobId);\n\t\treturn job ? job.name : jobId?.substring(0, 8) + '...';\n\t}\n\n\tasync function handleCancelRun(runId) {\n\t\tcancellingRunId = runId;\n\t\ttry {\n\t\t\tawait cancelRun(runId);\n\t\t\taddToast($t.translate?.run?.run_cancelled || 'Run cancelled', 'success');\n\t\t\t// Refresh the detail panel and list\n\t\t\tif (selectedRunDetail?.id === runId) {\n\t\t\t\tselectedRunDetail = await fetchRunDetail(runId);\n\t\t\t}\n\t\t\tloadRuns();\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || $t.translate?.run?.cancel_failed || 'Failed to cancel run', 'error');\n\t\t} finally {\n\t\t\tcancellingRunId = null;\n\t\t}\n\t}\n\n\tasync function handleRetryRun(runId) {\n\t\tretryingRunId = runId;\n\t\ttry {\n\t\t\tawait retryFailedBatches(runId);\n\t\t\taddToast($t.translate?.run?.retry_success || 'Retry started', 'success');\n\t\t\t// Refresh the detail panel and list\n\t\t\tif (selectedRunDetail?.id === runId) {\n\t\t\t\tselectedRunDetail = await fetchRunDetail(runId);\n\t\t\t}\n\t\t\tloadRuns();\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || $t.translate?.run?.retry_failed_msg || 'Retry failed', 'error');\n\t\t} finally {\n\t\t\tretryingRunId = null;\n\t\t}\n\t}\n\n\tasync function handleDownloadSkipped(runId) {\n\t\ttry {\n\t\t\tawait downloadSkippedCsv(runId);\n\t\t} catch (err) {\n\t\t\taddToast(err?.message || _('translate.history.download_failed'), 'error');\n\t\t}\n\t}\n\n\tfunction totalMetric() {\n\t\tif (!metrics.length) return null;\n\t\tconst agg = {\n\t\t\ttotal_runs: metrics.reduce((s, m) => s + (m.total_runs || 0), 0),\n\t\t\tsuccessful_runs: metrics.reduce((s, m) => s + (m.successful_runs || 0), 0),\n\t\t\tfailed_runs: metrics.reduce((s, m) => s + (m.failed_runs || 0), 0),\n\t\t\ttotal_records: metrics.reduce((s, m) => s + (m.total_records || 0), 0),\n\t\t};\n\t\treturn agg;\n\t}\n\n\n
\n\t
\n\t\t
\n\t\t\t

{$t.translate?.history?.title}

\n\t\t\t

{$t.translate?.history?.subtitle}

\n\t\t
\n\t\t\n\t
\n\n\t\n\t{#if totalMetric()}\n\t\t
\n\t\t\t
\n\t\t\t\t

{$t.translate?.history?.total_runs}

\n\t\t\t\t

{totalMetric().total_runs}

\n\t\t\t
\n\t\t\t
\n\t\t\t\t

{$t.translate?.history?.successful}

\n\t\t\t\t

{totalMetric().successful_runs}

\n\t\t\t
\n\t\t\t
\n\t\t\t\t

{$t.translate?.history?.failed}

\n\t\t\t\t

{totalMetric().failed_runs}

\n\t\t\t
\n\t\t\t
\n\t\t\t\t

{$t.translate?.history?.records}

\n\t\t\t\t

{totalMetric().total_records}

\n\t\t\t
\n\t\t
\n\t{/if}\n\n\t\n\t
\n\t\t
\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t
\n\t
\n\n\t\n\t{#if isLoading}\n\t\t
\n\t\t\t{#each Array(5) as _}\n\t\t\t\t
\n\t\t\t{/each}\n\t\t
\n\n\t\n\t{:else if uxState === 'empty'}\n\t\t
\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t

{$t.translate?.history?.no_runs}

\n\t\t\t

{$t.translate?.history?.no_runs_hint}

\n\t\t
\n\n\t\n\t{:else if uxState === 'populated' || uxState === 'detail_open'}\n\t\t
\n\t\t\t{#each runs as run}\n\t\t\t\t openDetail(run)}\n\t\t\t\t\tclass=\"bg-white border border-gray-200 rounded-lg p-3 hover:shadow-sm hover:border-gray-300 transition-all cursor-pointer\"\n\t\t\t\t>\n\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t{getJobName(run.job_id)}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{run.status}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{#if run.trigger_type}\n\t\t\t\t\t\t\t\t\t{run.trigger_type}\n\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t{run.created_at ? new Date(run.created_at).toLocaleString() : ''}\n\t\t\t\t\t\t\t\t{_('translate.history.records_label').replace('{count}', run.total_records || 0)}\n\t\t\t\t\t\t\t\t{_('translate.history.ok_label').replace('{count}', run.successful_records || 0)}\n\t\t\t\t\t\t\t\t{_('translate.history.fail_label').replace('{count}', run.failed_records || 0)}\n\t\t\t\t\t\t\t\t{#if run.created_by}\n\t\t\t\t\t\t\t\t\t{_('translate.history.by_label').replace('{user}', run.created_by)}\n\t\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{#if run.target_languages && run.target_languages.length > 0}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t{#each run.target_languages as lang}\n\t\t\t\t\t\t\t\t\t\t{lang}\n\t\t\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t
\n\t\t\t\t\t\t
e.stopPropagation()}>\n\t\t\t\t\t\t\t{#if run.status === 'PENDING' || run.status === 'RUNNING'}\n\t\t\t\t\t\t\t\t handleCancelRun(run.id)}\n\t\t\t\t\t\t\t\t\tdisabled={cancellingRunId === run.id}\n\t\t\t\t\t\t\t\t\tclass=\"px-2 py-1 text-xs bg-red-100 text-red-700 rounded hover:bg-red-200 disabled:opacity-50 transition-colors\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{cancellingRunId === run.id\n\t\t\t\t\t\t\t\t\t\t? ($t.translate?.run?.cancelling || '...')\n\t\t\t\t\t\t\t\t\t\t: ($t.translate?.run?.cancel || 'Cancel')}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t{#if run.status === 'FAILED'}\n\t\t\t\t\t\t\t\t handleRetryRun(run.id)}\n\t\t\t\t\t\t\t\t\tdisabled={retryingRunId === run.id}\n\t\t\t\t\t\t\t\t\tclass=\"px-2 py-1 text-xs bg-amber-100 text-amber-700 rounded hover:bg-amber-200 disabled:opacity-50 transition-colors\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{retryingRunId === run.id\n\t\t\t\t\t\t\t\t\t\t? ($t.translate?.run?.retrying || '...')\n\t\t\t\t\t\t\t\t\t\t: ($t.translate?.run?.retry_failed || 'Retry')}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t{#if run.status === 'COMPLETED' && (run.skipped_records || 0) > 0}\n\t\t\t\t\t\t\t\t handleDownloadSkipped(run.id)}\n\t\t\t\t\t\t\t\t\tclass=\"text-xs text-blue-600 hover:text-blue-700\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{$t.translate?.history?.skipped_csv}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t{/each}\n\t\t
\n\n\t\t\n\t\t
\n\t\t\t

{_('translate.history.showing').replace('{count}', runs.length).replace('{total}', total)}

\n\t\t\t
\n\t\t\t\t { currentPage--; loadRuns(); }}\n\t\t\t\t\tdisabled={currentPage <= 1}\n\t\t\t\t\tclass=\"px-3 py-1.5 text-sm border border-gray-200 rounded-lg disabled:opacity-50\"\n\t\t\t\t>\n\t\t\t\t\t{$t.translate?.history?.previous}\n\t\t\t\t\n\t\t\t\t { currentPage++; loadRuns(); }}\n\t\t\t\t\tdisabled={currentPage * pageSize >= total}\n\t\t\t\t\tclass=\"px-3 py-1.5 text-sm border border-gray-200 rounded-lg disabled:opacity-50\"\n\t\t\t\t>\n\t\t\t\t\t{$t.translate?.history?.next}\n\t\t\t\t\n\t\t\t
\n\t\t
\n\t{/if}\n\n\t\n\t{#if uxState === 'detail_open' && selectedRunDetail}\n\t\t
\n\t\t
\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t

{$t.translate?.history?.run_detail}

\n\t\t\t\t\t\n\t\t\t\t
\n\n\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.history?.status}

\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{selectedRunDetail.status}\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.history?.trigger}

\n\t\t\t\t\t\t

{selectedRunDetail.trigger_type || 'manual'}

\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.history?.started}

\n\t\t\t\t\t\t

{selectedRunDetail.started_at ? new Date(selectedRunDetail.started_at).toLocaleString() : '-'}

\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.history?.completed}

\n\t\t\t\t\t\t

{selectedRunDetail.completed_at ? new Date(selectedRunDetail.completed_at).toLocaleString() : '-'}

\n\t\t\t\t\t
\n\t\t\t\t
\n\n\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t

{selectedRunDetail.total_records || 0}

\n\t\t\t\t\t\t

{$t.translate?.history?.total}

\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t

{selectedRunDetail.successful_records || 0}

\n\t\t\t\t\t\t

{$t.translate?.history?.success}

\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t

{selectedRunDetail.failed_records || 0}

\n\t\t\t\t\t\t

{$t.translate?.history?.failed}

\n\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t

{selectedRunDetail.skipped_records || 0}

\n\t\t\t\t\t\t

{$t.translate?.history?.skipped}

\n\t\t\t\t\t
\n\t\t\t\t
\n\n\t\t\t\t\n\t\t\t\t{#if selectedRunDetail.language_stats && (Array.isArray(selectedRunDetail.language_stats) ? selectedRunDetail.language_stats.length : Object.keys(selectedRunDetail.language_stats).length) > 0}\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.run?.per_language}

\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{#each (Array.isArray(selectedRunDetail.language_stats) ? selectedRunDetail.language_stats : Object.entries(selectedRunDetail.language_stats).map(([code, s]) => ({ ...s, language_code: code }))) as stat}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t{getLanguageName(stat.language_code)}\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t{_('translate.run.translated_label').replace('{count}', stat.translated_rows)}\n\t\t\t\t\t\t\t\t\t\t{_('translate.run.failed_label').replace('{count}', stat.failed_rows)}\n\t\t\t\t\t\t\t\t\t\t{_('translate.run.skipped_label').replace('{count}', stat.skipped_rows)}\n\t\t\t\t\t\t\t\t\t\t{_('translate.run.tokens_label').replace('{count}', stat.token_count)}\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t{#if selectedRunDetail.status === 'PENDING' || selectedRunDetail.status === 'RUNNING'}\n\t\t\t\t\t\t handleCancelRun(selectedRunDetail.id)}\n\t\t\t\t\t\t\tdisabled={cancellingRunId === selectedRunDetail.id}\n\t\t\t\t\t\t\tclass=\"px-4 py-2 text-sm bg-red-600 text-white rounded-lg hover:bg-red-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{cancellingRunId === selectedRunDetail.id\n\t\t\t\t\t\t\t\t? ($t.translate?.run?.cancelling || 'Cancelling...')\n\t\t\t\t\t\t\t\t: ($t.translate?.run?.cancel || 'Cancel')}\n\t\t\t\t\t\t\n\t\t\t\t\t{/if}\n\t\t\t\t\t{#if selectedRunDetail.status === 'FAILED'}\n\t\t\t\t\t\t handleRetryRun(selectedRunDetail.id)}\n\t\t\t\t\t\t\tdisabled={retryingRunId === selectedRunDetail.id}\n\t\t\t\t\t\t\tclass=\"px-4 py-2 text-sm bg-amber-600 text-white rounded-lg hover:bg-amber-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{retryingRunId === selectedRunDetail.id\n\t\t\t\t\t\t\t\t? ($t.translate?.run?.retrying || 'Retrying...')\n\t\t\t\t\t\t\t\t: ($t.translate?.run?.retry_failed || 'Retry Failed')}\n\t\t\t\t\t\t\n\t\t\t\t\t{/if}\n\t\t\t\t
\n\n\t\t\t\t\n\t\t\t\t{#if selectedRunDetail.config_snapshot}\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.history?.config_snapshot}

\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
{JSON.stringify(selectedRunDetail.config_snapshot, null, 2)}
\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if selectedRunDetail.config_hash || selectedRunDetail.dict_snapshot_hash}\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.history?.snapshots}

\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{#if selectedRunDetail.config_hash}\n\t\t\t\t\t\t\t\t
Config: {selectedRunDetail.config_hash}
\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t{#if selectedRunDetail.dict_snapshot_hash}\n\t\t\t\t\t\t\t\t
Dict: {selectedRunDetail.dict_snapshot_hash}
\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t\t{#if selectedRunDetail.key_hash}\n\t\t\t\t\t\t\t\t
Key: {selectedRunDetail.key_hash}
\n\t\t\t\t\t\t\t{/if}\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if selectedRunDetail.events && selectedRunDetail.events.length > 0}\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.history?.events.replace('{count}', selectedRunDetail.events.length)}

\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{#each selectedRunDetail.events as evt}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t{evt.event_type}\n\t\t\t\t\t\t\t\t\t|\n\t\t\t\t\t\t\t\t\t{evt.created_at ? new Date(evt.created_at).toLocaleString() : ''}\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{/each}\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if selectedRunDetail.error_message}\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.history?.error}

\n\t\t\t\t\t\t

{selectedRunDetail.error_message}

\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\n\t\t\t\t\n\t\t\t\t{#if selectedRunDetail.superset_execution_id}\n\t\t\t\t\t
\n\t\t\t\t\t\t

{$t.translate?.history?.superset_query_id}

\n\t\t\t\t\t\t

{selectedRunDetail.superset_execution_id}

\n\t\t\t\t\t
\n\t\t\t\t{/if}\n\t\t\t
\n\t\t
\n\t{/if}\n
\n\n" }, { "contract_id": "GitServiceContractTests", @@ -106675,6455 +105360,6456 @@ } ], "file_hashes": { - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_searchsorted.py": 11161416745923343741, - "venv/lib/python3.13/site-packages/pygments/lexers/javascript.py": 16869490851285457857, - "venv/lib/python3.13/site-packages/numpy/f2py/_backends/__init__.py": 4265012785873472600, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_mem_policy.py": 13856626567322091253, - "backend/src/api/routes/__tests__/test_assistant_api.py": 16438212076178324033, - "venv/lib/python3.13/site-packages/pandas/io/formats/info.py": 215303194287834907, - "venv/lib/python3.13/site-packages/keyring/util/__init__.py": 9635016046220094473, - "venv/lib/python3.13/site-packages/_pytest/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/__init__.py": 5933622200264572885, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_style.py": 14810883299259169406, - "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_promote.py": 16601872688404846307, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ndarray.pyi": 14369009813591437391, - "venv/lib/python3.13/site-packages/pip/_internal/utils/compatibility_tags.py": 15862649917149158291, - "venv/lib/python3.13/site-packages/pandas/tests/extension/base/getitem.py": 556339939822508169, - "venv/lib/python3.13/site-packages/anyio/streams/buffered.py": 8916188172110578587, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_slice.py": 9936085512921529417, - "backend/src/services/clean_release/report_builder.py": 6953311294119437848, - "venv/lib/python3.13/site-packages/pydantic/v1/typing.py": 13467331592583800299, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/__init__.py": 9884041726796476720, - "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/windows.py": 16452996247375488034, - "frontend/build/_app/immutable/chunks/CKlo2EnU.js": 1125213830095559337, - "frontend/static/favicon.svg": 6451919037497541980, - "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/caches/__init__.py": 11808051681178127650, - "venv/lib/python3.13/site-packages/_pytest/scope.py": 7603155109542903644, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/__init__.py": 2345997696115514124, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/__init__.py": 15130871412783076140, - "frontend/src/lib/ui/Button.svelte": 921807193049478213, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_formats.py": 13500155167624433622, - "venv/lib/python3.13/site-packages/pygments/formatters/html.py": 1918541918263449443, - "venv/lib/python3.13/site-packages/authlib/integrations/django_client/__init__.py": 14186136918454802843, - "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_xlsxwriter.py": 8445547874832015203, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_freq_attr.py": 17290447066681837965, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arraysetops.pyi": 1782641795267171928, - "venv/lib/python3.13/site-packages/numpy/core/records.py": 12604652690721760437, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_astype.py": 7542068949396266883, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/asyncmy.py": 11808138763443525443, - "venv/lib/python3.13/site-packages/pip/_vendor/distlib/util.py": 3591114320020964752, - "venv/lib/python3.13/site-packages/numpy/random/_examples/numba/extending.py": 16515485226251040454, - "venv/lib/python3.13/site-packages/pygments/lexers/cplint.py": 13990118342267278047, - "frontend/src/app.css": 3020720639702954139, - "venv/lib/python3.13/site-packages/psycopg2/errors.py": 10441360078612452560, - "backend/src/core/utils/matching.py": 12567367681677699487, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame.py": 16757570551941104401, - "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/LICENSE": 16510279186416777136, - "venv/lib/python3.13/site-packages/pycparser/c_ast.py": 5942107079119742, - "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_dict_compat.py": 18196543090455290455, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_indexing.py": 16623126293364224089, - "venv/lib/python3.13/site-packages/pandas/tests/api/test_api.py": 13385690673368400635, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_index_col.py": 17604191644943383567, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/context.py": 1041624619197012753, - "venv/lib/python3.13/site-packages/tzlocal-5.3.1.dist-info/RECORD": 15574202654585730126, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/__init__.py": 3673322722277252961, - "venv/lib/python3.13/site-packages/numpy/_typing/_nested_sequence.py": 7827259347937485408, - "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/RECORD": 16874983218652404911, - "venv/lib/python3.13/site-packages/pygments/styles/monokai.py": 12381683616720952636, - "frontend/src/lib/components/dataset-review/__tests__/source_intake_panel.ux.test.js": 13445861056598482363, - "venv/lib/python3.13/site-packages/pygments/lexers/amdgpu.py": 17249439604111838979, - "frontend/src/lib/components/layout/TaskDrawer.svelte": 6654829127438406248, - "backend/src/api/routes/__tests__/test_dataset_review_api.py": 17381354465400611694, - "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_period.py": 6255181868181182780, - "backend/src/services/clean_release/manifest_builder.py": 17216832960644499305, - "venv/lib/python3.13/site-packages/idna/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/smmap/buf.py": 18231775424238352734, - "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/httpx/_transports/default.py": 8391302827983907910, - "venv/lib/python3.13/site-packages/greenlet/TThreadStateCreator.hpp": 9887867766190459665, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8414/models.py": 3567900447243180991, - "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/utils.py": 2959395751217827103, - "venv/lib/python3.13/site-packages/pip/_internal/operations/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_internal/index/sources.py": 11609272011565024668, - "venv/lib/python3.13/site-packages/cryptography/hazmat/asn1/asn1.py": 8801155055979135092, - "venv/lib/python3.13/site-packages/pydantic_settings/sources/base.py": 10200916670889920659, - "venv/lib/python3.13/site-packages/apscheduler/triggers/interval.py": 3964550092873794670, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/stride_tricks.pyi": 8257977532799807847, - "venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/WHEEL": 2357997949040430835, - "venv/lib/python3.13/site-packages/numpy/random/_pickle.pyi": 16081120364372391381, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/mod_derived_types.f90": 2556756676983488922, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_block_docstring.py": 18146459246837890489, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_offsets_properties.py": 2340780879864207500, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_console.py": 11657469008721907972, - "venv/lib/python3.13/site-packages/pygments/lexers/kuin.py": 2818054539831699366, - "frontend/src/lib/components/dataset-review/SourceIntakePanel.svelte": 10994864579319870671, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/LCSseq_py.py": 16054175754674285311, - "venv/lib/python3.13/site-packages/pygments/lexers/configs.py": 7712797939104760185, - "venv/lib/python3.13/site-packages/rsa/prime.py": 10820898885044917095, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/scope.py": 4096190764836489091, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_category.py": 3944898528119364040, - "frontend/src/routes/profile/__tests__/profile-preferences.integration.test.js": 6561454515118560091, - "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/licenses/LICENSE.BSD": 3858254215169937333, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_copy.py": 3114918520437707410, - "venv/lib/python3.13/site-packages/jeepney-0.9.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_quantile.py": 11966156706220948315, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ma.py": 15912582628112164509, - "frontend/src/routes/translate/+page.svelte": 3906731431561226801, - "backend/src/core/utils/superset_context_extractor/_templates.py": 6790136732701012567, - "backend/src/core/task_manager/context.py": 17543992255093146942, - "frontend/src/lib/components/translate/TranslationRunProgress.svelte": 10281443795034845589, - "frontend/src/lib/components/layout/__tests__/test_sidebar.svelte.js": 1424894894434906249, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/_serialization.py": 2011519400081029270, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/assertions.py": 5556667947376168765, - "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/RECORD": 1164466882742493155, - "venv/lib/python3.13/site-packages/numpy/f2py/func2subr.pyi": 16573082220135508510, - "venv/lib/python3.13/site-packages/greenlet/tests/__init__.py": 1181423074160870921, - "venv/lib/python3.13/site-packages/annotated_types/__init__.py": 7367790549779882749, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/introspection.py": 5447179017910128771, - "venv/lib/python3.13/site-packages/starlette/status.py": 16192064443996706569, - "backend/src/services/clean_release/__tests__/test_report_builder.py": 17265459530244848426, - "venv/lib/python3.13/site-packages/pydantic/warnings.py": 5142352784799639092, - "venv/lib/python3.13/site-packages/pygments/styles/lovelace.py": 15082819162722685616, - "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/WHEEL": 5160964596297665692, - "venv/lib/python3.13/site-packages/httpx/_auth.py": 1283189552342958900, - "venv/lib/python3.13/site-packages/pygments/lexers/_luau_builtins.py": 13690910306072616818, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/constant_time.py": 2499026008403328245, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_shift.py": 14681514853406253657, - "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/licenses/LICENSE": 3868190977070717994, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/arrayprint.pyi": 2424868797160722318, - "frontend/eslint.config.js": 14296985543214702398, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_constructors.py": 17392287676196409733, - "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/_in_process/__init__.py": 9627328185578406121, - "venv/lib/python3.13/site-packages/pip/_vendor/tomli/_parser.py": 3540203683732744499, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/emoji.py": 9166774203918731896, - "venv/lib/python3.13/site-packages/apscheduler/jobstores/zookeeper.py": 4318643109309626098, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/test_calendar.py": 12313641252472031631, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/roles.py": 5448455900674232810, - "venv/lib/python3.13/site-packages/PIL/_webp.cpython-313-x86_64-linux-gnu.so": 11070012119632935103, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_clip.py": 11111183698178681331, - "venv/lib/python3.13/site-packages/sqlalchemy/util/__init__.py": 15821192733097665649, - "venv/lib/python3.13/site-packages/jsonschema/__init__.py": 6925762200139836824, - "venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/RECORD": 17594742868855466393, - "venv/lib/python3.13/site-packages/pandas/_libs/window/aggregations.pyi": 6072607880689125113, - "frontend/src/lib/components/assistant/AssistantChatPanel.svelte": 15111082609123137207, - "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_printing.py": 1901396869745313303, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_format.py": 9331389900588353667, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_drop.py": 15751236355035730554, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_windows.py": 13341168721223961872, - "venv/lib/python3.13/site-packages/dateutil/tz/_common.py": 9009072600471223066, - "backend/tests/core/migration/test_archive_parser.py": 1909788158234142574, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_find_common_type.py": 9581516171321396333, - "venv/lib/python3.13/site-packages/pandas/io/json/__init__.py": 12333505155070172626, - "venv/lib/python3.13/site-packages/pip/_internal/operations/build/metadata_editable.py": 12494407279914732338, - "backend/src/plugins/translate/scheduler.py": 5240440208871506497, - "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/limited_api_latest.c": 5472633890472031814, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_set_name.py": 9094608008538024609, - "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_datetime64.py": 16272266806084058743, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/Jaro.pyi": 3145980717589050713, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/scrypt.py": 15294662527620994511, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/starlette/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_infer_dtype.py": 1647214604678171565, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/period.cpython-313-x86_64-linux-gnu.so": 14468234464367691795, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_pct_change.py": 10313980265441433173, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_concatenate_chunks.py": 9693420220003544490, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/Prefix_py.py": 17041764258638228993, - "venv/lib/python3.13/site-packages/pandas/tests/series/test_cumulative.py": 16283954014170928273, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/screen.py": 6933591906297023845, - "venv/lib/python3.13/site-packages/PIL/XpmImagePlugin.py": 6644626557482464312, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_util.py": 16024147572807865219, - "frontend/src/components/git/CommitModal.svelte": 2248630732087966961, - "venv/lib/python3.13/site-packages/anyio/_core/_subprocesses.py": 7271614043537119143, - "venv/lib/python3.13/site-packages/pandas/tests/apply/test_str.py": 149688376805129532, - "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/METADATA": 2810323639884879396, - "venv/lib/python3.13/site-packages/pandas/util/_exceptions.py": 14426860079366867683, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_format.py": 16150524965028369071, - "venv/lib/python3.13/site-packages/rsa/asn1.py": 3861968161559322784, - "frontend/src/pages/Settings.svelte": 5110524159352803966, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_nunique.py": 8450574751331186943, - "frontend/build/_app/immutable/nodes/32.CA42qfpo.js": 6728008632143803945, - "venv/lib/python3.13/site-packages/pip/_internal/utils/entrypoints.py": 11268059714209889385, - "venv/lib/python3.13/site-packages/pandas/core/groupby/categorical.py": 16588862198627920420, - "backend/conftest.py": 16521922883434363388, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_alpha_unix.h": 2759424570606117942, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/claims.py": 14794441479740527265, - "venv/lib/python3.13/site-packages/typing_inspection/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc_unix.h": 9608771997528633681, - "venv/lib/python3.13/site-packages/jaraco/classes/ancestry.py": 11742194518360056470, - "venv/lib/python3.13/site-packages/websockets/asyncio/async_timeout.py": 7267209982032642028, - "venv/lib/python3.13/site-packages/attrs/setters.py": 5775359015245600592, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/Postfix_py.py": 6653895521961110080, - "venv/lib/python3.13/site-packages/jose/backends/__init__.py": 16581763658239070112, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/kdf.pyi": 1626154870044880426, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/array_constructors.py": 6727209833819502644, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_to_frame.py": 4303613319747945709, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_math.h": 16701045088211015518, - "venv/lib/python3.13/site-packages/numpy/_core/_methods.pyi": 9155045948490225716, - "backend/src/plugins/translate/__tests__/test_dictionary.py": 17973099740734727535, - "venv/lib/python3.13/site-packages/dateutil/rrule.py": 398469817784230512, - "backend/src/services/git/_merge.py": 5311748722639845465, - "venv/lib/python3.13/site-packages/jsonschema/tests/test_exceptions.py": 15290185665769490169, - "venv/lib/python3.13/site-packages/urllib3-2.6.2.dist-info/RECORD": 15194367076254806710, - "venv/lib/python3.13/site-packages/pandas/core/window/ewm.py": 12143982379243011357, - "venv/lib/python3.13/site-packages/pandas/tests/window/test_win_type.py": 18105114803686556748, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/entities.py": 8001287806688585081, - "venv/lib/python3.13/site-packages/pydantic/_internal/_config.py": 12760390602912369447, - "venv/lib/python3.13/site-packages/referencing/tests/test_referencing_suite.py": 8875120876162738440, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/util.py": 955993052529739164, - "venv/lib/python3.13/site-packages/requests/sessions.py": 6936640856092320928, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/__init__.py": 8558541715982163200, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_year.py": 1478857009124807836, - "venv/lib/python3.13/site-packages/sqlalchemy/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/appengine.py": 16194997685865850655, - "venv/lib/python3.13/site-packages/pygments/lexers/monte.py": 15158829991357994573, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/_dml_constructors.py": 4497038002189188311, - "venv/lib/python3.13/site-packages/pandas/tests/tools/test_to_numeric.py": 18037815278545274402, - "venv/lib/python3.13/site-packages/fastapi/testclient.py": 2606236077497278662, - "venv/lib/python3.13/site-packages/pip/_internal/models/wheel.py": 10473287225032326206, - "backend/src/services/clean_release/exceptions.py": 14631509303697939633, - "backend/src/plugins/debug.py": 2035734953696955393, - "venv/lib/python3.13/site-packages/pydantic/__init__.py": 11536052293866174672, - "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/METADATA": 14608873187265321271, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_engines.py": 2790877023773269276, - "venv/lib/python3.13/site-packages/pip/_internal/cli/autocompletion.py": 7651919329635563739, - "venv/lib/python3.13/site-packages/numpy/_core/_exceptions.py": 5570375156851166818, - "venv/lib/python3.13/site-packages/numpy/doc/ufuncs.py": 11706048944901534664, - "venv/lib/python3.13/site-packages/numpy/_distributor_init.py": 1101690714183863290, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc_aix.h": 13316272821279308986, - "venv/lib/python3.13/site-packages/pandas/io/parsers/__init__.py": 11752833703934347122, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/plugin/plugin_base.py": 2880434680251108786, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/util.py": 2176177435997659667, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/cymysql.py": 5570881524647789741, - "venv/lib/python3.13/site-packages/pandas/core/indexing.py": 15507869313676722071, - "venv/lib/python3.13/site-packages/pyasn1/type/useful.py": 10313387611927801339, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_periodindex.py": 13430003945574795792, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_insert.py": 9195027887301180927, - "venv/lib/python3.13/site-packages/numpy/_array_api_info.py": 9709101823494959741, - "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/WHEEL": 16784970174376303810, - "venv/lib/python3.13/site-packages/numpy/_distributor_init.pyi": 1308368231471324581, - "venv/lib/python3.13/site-packages/passlib/tests/test_registry.py": 15377817946543064293, - "venv/lib/python3.13/site-packages/passlib/tests/sample1b.cfg": 2872366861156549016, - "venv/lib/python3.13/site-packages/pandas/tests/resample/test_resampler_grouper.py": 8388490036390951341, - "venv/lib/python3.13/site-packages/pygments/lexers/rego.py": 16022844238903541738, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/io/json/conftest.py": 9673372914396625461, - "venv/lib/python3.13/site-packages/pygments/lexers/_cl_builtins.py": 16540712925368297957, - "venv/lib/python3.13/site-packages/pygments/lexers/agile.py": 5686162551416231457, - "venv/lib/python3.13/site-packages/pygments/lexers/solidity.py": 5071425960622305629, - "venv/lib/python3.13/site-packages/packaging/specifiers.py": 2800449842990194437, - "backend/src/core/utils/superset_context_extractor/_filters.py": 281666313889333545, - "backend/src/plugins/search.py": 888817404897740233, - "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/WHEEL": 2357997949040430835, - "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/licenses/COPYING": 14459782230785388765, - "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/METADATA": 15970460108484113417, - "venv/lib/python3.13/site-packages/numpy/ma/LICENSE": 6723325434476453127, - "venv/lib/python3.13/site-packages/pip/_internal/cache.py": 210214424535803946, - "venv/lib/python3.13/site-packages/pydantic/experimental/pipeline.py": 9493054841465227788, - "venv/lib/python3.13/site-packages/numpy/tests/test_public_api.py": 11741922758622705449, - "venv/lib/python3.13/site-packages/pandas/tests/window/moments/test_moments_consistency_ewm.py": 12153690217678546798, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_range.py": 3544406211185340973, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_quoted_character.py": 2316632434571797367, - "venv/lib/python3.13/site-packages/referencing/exceptions.py": 2535322334430110414, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_join.py": 1697622393195784944, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_reduction.py": 2671872764983553906, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_concat.py": 1351478313334379336, - "venv/lib/python3.13/site-packages/starlette/types.py": 6372850128669191435, - "venv/lib/python3.13/site-packages/PIL/ImageMorph.py": 13861961228125789866, - "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/emscripten_fetch_worker.js": 10530710876604536879, - "venv/lib/python3.13/site-packages/pandas/io/excel/_base.py": 1251545894005373734, - "venv/lib/python3.13/site-packages/uvicorn/lifespan/on.py": 2866195356090164296, - "backend/src/models/mapping.py": 9358348320550260098, - "venv/lib/python3.13/site-packages/sqlalchemy/engine/events.py": 15099787454570172797, - "backend/tests/test_translate_scheduler_execution.py": 16687335504320865378, - "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_constructors.py": 979131987837682435, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_halfyear.py": 587199217232946404, - "venv/lib/python3.13/site-packages/jeepney/tests/test_bindgen.py": 8637878018232418583, - "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/WHEEL": 9788895026336324100, - "venv/lib/python3.13/site-packages/keyring/compat/properties.py": 1562771115138037410, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arcsinh.csv": 13695545125848146013, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_sorting.py": 8944017570338511677, - "venv/lib/python3.13/site-packages/iniconfig/_parse.py": 11418441008427032090, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_index.py": 4908727359687606870, - "venv/lib/python3.13/site-packages/h11/_receivebuffer.py": 4631433251046338381, - "venv/lib/python3.13/site-packages/pandas/tests/resample/test_resample_api.py": 3278209206670699265, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_halfyear.py": 9376272342364384767, - "venv/lib/python3.13/site-packages/_pytest/skipping.py": 10561585274103209115, - "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/METADATA": 6438256145634479451, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_align.py": 10284128457194204574, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/default_comparator.py": 47118577003622736, - "venv/lib/python3.13/site-packages/uvicorn/loops/asyncio.py": 16496916527760969173, - "venv/bin/pyrsa-sign": 15564653706771700451, - "venv/lib/python3.13/site-packages/numpy/_core/tests/_locales.py": 18178500267053825979, - "venv/lib/python3.13/site-packages/websockets/imports.py": 1995356703044158461, - "venv/lib/python3.13/site-packages/cryptography/x509/extensions.py": 10197248868682803019, - "venv/lib/python3.13/site-packages/anyio/_core/_resources.py": 8463932838064724564, - "venv/lib/python3.13/site-packages/pip/_vendor/distro/distro.py": 12494639376332486204, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_rename.py": 4890779493250245903, - "venv/lib/python3.13/site-packages/pandas/_config/localization.py": 11197430792343731762, - "venv/lib/python3.13/site-packages/apscheduler/executors/debug.py": 14072221218785494847, - "venv/lib/python3.13/site-packages/pycparser/c_lexer.py": 10964496587169353564, - "venv/lib/python3.13/site-packages/numpy/core/_dtype_ctypes.pyi": 15130871412783076140, - "venv/lib/python3.13/site-packages/charset_normalizer/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/RECORD": 12733654377842895588, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/_initialize.pyi": 6616985736007157309, - "venv/lib/python3.13/site-packages/pygments/lexers/esoteric.py": 16839499623020685146, - "backend/src/models/dataset_review.py": 5814500849969423218, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_day.py": 6371851881186970754, - "venv/lib/python3.13/site-packages/sqlalchemy/pool/base.py": 16951268065271931235, - "frontend/vitest.config.js": 142965001777137074, - "venv/lib/python3.13/site-packages/rpds/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/libs/test_join.py": 5982692266872978444, - "backend/src/api/routes/__tests__/test_reports_detail_api.py": 6960149894653710507, - "venv/lib/python3.13/site-packages/numpy/_core/numerictypes.pyi": 12144531601504755948, - "venv/lib/python3.13/site-packages/pandas/tests/io/sas/test_sas7bdat.py": 8963983384208121526, - "venv/lib/python3.13/site-packages/numpy/linalg/tests/test_deprecations.py": 14624516389510242394, - "backend/src/models/dataset_review_pkg/_finding_models.py": 17608383421420046491, - "venv/lib/python3.13/site-packages/numpy/lib/_iotools.pyi": 12873243737872788349, - "venv/lib/python3.13/site-packages/pandas/tests/reductions/__init__.py": 16150188643076000414, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_join.py": 11910166566689889389, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_pickle.py": 8705060420848529055, - "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_array_to_datetime.py": 3467480435568672840, - "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/INSTALLER": 17282701611721059870, - "frontend/src/lib/components/reports/__tests__/report_detail.integration.test.js": 4193615240297330385, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_pipe.py": 7400355977900310233, - "venv/lib/python3.13/site-packages/itsdangerous/timed.py": 12571102606719555007, - "venv/lib/python3.13/site-packages/pygments/lexers/markup.py": 10311057264960923433, - "venv/lib/python3.13/site-packages/pip/_internal/cli/req_command.py": 2887890799766730546, - "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/authorization_server.py": 2913800420669417152, - "venv/lib/python3.13/site-packages/pandas/core/array_algos/datetimelike_accumulations.py": 14719894187829729175, - "frontend/build/_app/immutable/nodes/14.DafKLV_n.js": 10724793506995782696, - "venv/lib/python3.13/site-packages/click-8.3.1.dist-info/RECORD": 3649834117451110628, - "venv/lib/python3.13/site-packages/websockets/uri.py": 264376168984862773, - "venv/lib/python3.13/site-packages/passlib/utils/handlers.py": 10182859005870689026, - "venv/lib/python3.13/site-packages/numpy/_core/fromnumeric.pyi": 13945478633722616250, - "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/tools.py": 6437315459200419827, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/methods/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_rowcount.py": 6682800584070485197, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_numpy.py": 222383250675686477, - "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/LICENSE": 6774760218010069963, - "venv/lib/python3.13/site-packages/rsa/pkcs1.py": 2576732594642491910, - "venv/lib/python3.13/site-packages/yaml/constructor.py": 8731384179016992045, - "venv/lib/python3.13/site-packages/pycparser/c_parser.py": 3954138286651284327, - "venv/lib/python3.13/site-packages/pandas/tests/extension/array_with_attr/test_array_with_attr.py": 6568496539994758985, - "backend/src/plugins/translate/__tests__/test_orthogonal_fixes.py": 17679703384686060315, - "backend/alembic/env.py": 17839770100030276595, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_comparison.py": 4611207880323503098, - "venv/lib/python3.13/site-packages/pygments/lexers/igor.py": 6506221273085723501, - "frontend/src/lib/components/dataset-review/__tests__/validation_findings_panel.ux.test.js": 8994492423600483794, - "venv/lib/python3.13/site-packages/_pytest/fixtures.py": 1442767529726551116, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_indexing.py": 14552860427542050771, - "backend/src/api/routes/mappings.py": 7071183920129492341, - "venv/lib/python3.13/site-packages/jsonschema_specifications/tests/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/provision.py": 9472538482404392519, - "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/WHEEL": 16097436423493754389, - "frontend/build/_app/immutable/entry/app.Cen278DP.js": 13502215328893449420, - "venv/lib/python3.13/site-packages/passlib/handlers/mssql.py": 2800599582708170195, - "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/METADATA": 5045041742469375466, - "venv/lib/python3.13/site-packages/PIL/DdsImagePlugin.py": 10646832373516499548, - "backend/src/core/superset_client/_dashboards_filters.py": 11002883972618719697, - "venv/lib/python3.13/site-packages/pygments/lexers/crystal.py": 3579547906957125755, - "frontend/build/_app/immutable/chunks/Vi81AIny.js": 9283030674196335690, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/aead.pyi": 13061638961405460334, - "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/backports/weakref_finalize.py": 7019253290755243568, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/gh26920/two_mods_with_no_public_entities.f90": 12296500845667555672, - "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libkrb5-fcafa220.so.3.3": 5620628698712971642, - "venv/lib/python3.13/site-packages/numpy/_typing/_shape.py": 12667553664122376205, - "backend/src/services/git/_remote_providers.py": 12661659133898682960, - "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/click/decorators.py": 2920877667855377423, - "venv/lib/python3.13/site-packages/pandas/tests/extension/base/dtype.py": 5553691086633215767, - "venv/lib/python3.13/site-packages/numpy/f2py/f90mod_rules.pyi": 18290764713161282980, - "venv/lib/python3.13/site-packages/_pytest/subtests.py": 14573790885130724739, - "venv/lib/python3.13/site-packages/pydantic/utils.py": 1533455264689378477, - "venv/lib/python3.13/site-packages/greenlet/__init__.py": 3447613556981242475, - "venv/lib/python3.13/site-packages/pip/_internal/models/pylock.py": 16697828625021519459, - "venv/lib/python3.13/site-packages/attr/converters.py": 5179615793507170642, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/memmap.pyi": 2834143910417841603, - "venv/lib/python3.13/site-packages/pandas/errors/cow.py": 14381282473643980776, - "venv/lib/python3.13/site-packages/numpy/conftest.py": 8971879716683736515, - "venv/lib/python3.13/site-packages/numpy/random/_sfc64.cpython-313-x86_64-linux-gnu.so": 17186695607612591922, - "venv/lib/python3.13/site-packages/pandas/tests/apply/test_numba.py": 203614377324678234, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7519/claims.py": 12645788445743898136, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_missing.py": 7034102519042351965, - "venv/lib/python3.13/site-packages/numpy/f2py/cb_rules.pyi": 12275242654430570028, - "venv/lib/python3.13/site-packages/urllib3/contrib/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pygments/styles/inkpot.py": 10516710471319090846, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/wait.py": 6196757964348666082, - "venv/lib/python3.13/site-packages/annotated_doc/__init__.py": 6834198874252778425, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/dynamic.py": 15220116196072524330, - "frontend/src/lib/components/reports/__tests__/report_detail.ux.test.js": 11878832350632571462, - "frontend/build/_app/immutable/nodes/3.BXhpfKSB.js": 17728812616595273401, - "backend/src/core/__tests__/test_native_filters.py": 823253235973274872, - "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libcom_err-2abe824b.so.2.1": 12870528025628871295, - "venv/lib/python3.13/site-packages/numpy/linalg/tests/test_regression.py": 5652583095949741238, - "venv/lib/python3.13/site-packages/pandas/core/dtypes/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pydantic/v1/networks.py": 13262073155118055511, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_memmap.py": 8709963808115492688, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ndarray_misc.pyi": 16219573290116396099, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/metrics_cpp.cpython-313-x86_64-linux-gnu.so": 10263790384087091349, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/dh.pyi": 3254633032236269842, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_to_dict.py": 16252265723192124609, - "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth1/resource_protector.py": 14354891358060085360, - "venv/lib/python3.13/site-packages/keyring/backends/fail.py": 5792496235026678021, - "venv/lib/python3.13/site-packages/authlib/integrations/flask_client/integration.py": 12670848015915724967, - "venv/lib/python3.13/site-packages/starlette/middleware/wsgi.py": 12506262030845301606, - "venv/lib/python3.13/site-packages/apscheduler/jobstores/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/passlib/tests/test_utils_handlers.py": 556092537518149789, - "venv/lib/python3.13/site-packages/pandas/_libs/missing.pyi": 13543139288840944411, - "venv/lib/python3.13/site-packages/pandas/tests/io/xml/test_xml_dtypes.py": 18293138335799308439, - "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/_lint_dependency_groups.py": 2609365889369107154, - "venv/lib/python3.13/site-packages/pandas/tests/window/test_apply.py": 7511915990531229598, - "venv/lib/python3.13/site-packages/httpx/_decoders.py": 14478643473006178492, - "venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py": 7301817934902711510, - "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/auto.py": 12818217385551437286, - "venv/lib/python3.13/site-packages/starlette/staticfiles.py": 11256974306202558529, - "venv/lib/python3.13/site-packages/keyring/devpi_client.py": 3445890176686211982, - "venv/lib/python3.13/site-packages/pandas/tests/apply/test_series_apply.py": 12349190935180702377, - "venv/lib/python3.13/site-packages/pandas/_libs/ops_dispatch.cpython-313-x86_64-linux-gnu.so": 5284769758475394095, - "venv/lib/python3.13/site-packages/numpy/ma/tests/test_deprecations.py": 8310244516175542839, - "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_ccalendar.py": 8819357623337533489, - "venv/lib/python3.13/site-packages/pip/py.typed": 10243553515949422671, - "venv/lib/python3.13/site-packages/websockets/protocol.py": 6401227903827084901, - "venv/lib/python3.13/site-packages/pyasn1/codec/der/decoder.py": 11876648884087997745, - "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/licenses/numpy/_core/src/highway/LICENSE": 15636145745140922094, - "frontend/build/_app/immutable/chunks/DoFYTHzk.js": 8080725323375789598, - "backend/src/core/superset_client/_charts.py": 8101226087578568224, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/numpyconfig.h": 13339221870252345205, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_read_fwf.py": 13684564756628524738, - "backend/src/api/routes/__tests__/test_assistant_authz.py": 8404416194210647280, - "backend/src/plugins/git/__init__.py": 2144831474780401625, - "backend/src/services/clean_release/repositories/policy_repository.py": 10990781278715170404, - "venv/lib/python3.13/site-packages/pandas/_testing/_hypothesis.py": 12298650110193262367, - "venv/lib/python3.13/site-packages/passlib/ext/django/utils.py": 8118896525895185626, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/pymssql.py": 6650008663791598065, - "venv/lib/python3.13/site-packages/pandas/_testing/asserters.py": 272063856832951430, - "backend/src/plugins/translate/service.py": 16088501346836746367, - "backend/src/core/mapping_service.py": 15428037653286485748, - "venv/lib/python3.13/site-packages/attr/exceptions.pyi": 12323493441583681402, - "backend/src/__init__.py": 11250920420388310655, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_tz_localize.py": 4937713043686953098, - "venv/lib/python3.13/site-packages/urllib3/fields.py": 9503202008440141421, - "venv/lib/python3.13/site-packages/pip/_vendor/requests/__version__.py": 14138134075118474134, - "venv/lib/python3.13/site-packages/numpy/lib/tests/data/win64python2.npy": 11005857803794805939, - "venv/lib/python3.13/site-packages/numpy/f2py/rules.pyi": 1342380029484127983, - "venv/lib/python3.13/site-packages/numpy/polynomial/laguerre.pyi": 11310761736182213265, - "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_box_unbox.py": 7579587620530953711, - "venv/lib/python3.13/site-packages/sqlalchemy/engine/characteristics.py": 2916810597149066609, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_indexing_slow.py": 12558235638488427077, - "venv/lib/python3.13/site-packages/pygments/lexers/web.py": 11104721221615804497, - "venv/lib/python3.13/site-packages/_pytest/compat.py": 10046464101087327473, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_both.f90": 13943066317159236257, - "venv/lib/python3.13/site-packages/pip/_internal/metadata/importlib/_envs.py": 5657151394155576509, - "venv/lib/python3.13/site-packages/pandas/core/nanops.py": 18291534943985310005, - "venv/lib/python3.13/site-packages/pandas/_libs/writers.cpython-313-x86_64-linux-gnu.so": 6878855127769203372, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timedeltas.pyi": 3783371827926657291, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/errors.py": 12777931960088171310, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_to_julian_date.py": 6868080396693831272, - "venv/bin/uvicorn": 3776670267111625708, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_as_unit.py": 8492383355919959393, - "venv/lib/python3.13/site-packages/pip/_vendor/tomli/_types.py": 7175518113263603341, - "backend/src/services/dataset_review/clarification_pkg/_helpers.py": 4822867945130807759, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/random/bitgen.h": 12421210767114721499, - "venv/lib/python3.13/site-packages/pandas/core/window/numba_.py": 1444123360986509769, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_join.py": 17874591841487372992, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_join.py": 1364886077926604427, - "frontend/src/lib/components/assistant/AssistantClarificationCard.svelte": 15872391111837089374, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/refresh_token.py": 17927903035152872556, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/align.py": 6078666505647454830, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_nep50_promotions.py": 6318578947214302182, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_equivalence.py": 17843623343419137458, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_formats.py": 1265319125235346745, - "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_compression.py": 8577756801858495168, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_attr_equal.py": 5612259834202470413, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_pickle.py": 6232650893735715362, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_eng_formatting.py": 14768815444701392013, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/style.py": 12654125988995362593, - "venv/lib/python3.13/site-packages/pygments/lexers/templates.py": 16267123844830647955, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/common.py": 16314033415206173235, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_integer.f90": 8308927438994838783, - "venv/lib/python3.13/site-packages/websockets/typing.py": 13268801935274185287, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/test_other.py": 783701524491896337, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/collections.cpython-313-x86_64-linux-gnu.so": 6157288238855118017, - "backend/src/core/migration/dry_run_orchestrator.py": 10939333902806918334, - "venv/lib/python3.13/site-packages/authlib/consts.py": 14226604841596736870, - "venv/lib/python3.13/site-packages/greenlet/tests/test_version.py": 6317733744899804292, - "venv/lib/python3.13/site-packages/numpy/ma/tests/test_mrecords.py": 15952147778503828707, - "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_hermite.py": 3628609433179387988, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_datetime.py": 7456744745424297814, - "venv/lib/python3.13/site-packages/requests/__init__.py": 2604491098990438229, - "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_tokenizer.py": 7994281991455916540, - "venv/lib/python3.13/site-packages/numpy/lib/_npyio_impl.py": 2215312866861772848, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/pyodbc.py": 11271266527234292020, - "venv/lib/python3.13/site-packages/pygments/lexers/_sourcemod_builtins.py": 11809503654078535014, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/types.py": 356973910046950951, - "venv/lib/python3.13/site-packages/pygments/lexers/forth.py": 17623561228839319663, - "venv/lib/python3.13/site-packages/httpcore/_models.py": 2501866419898326733, - "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/pygments/lexers/maxima.py": 11824576541091274641, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh17859.f": 13562390882286135024, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/loading.py": 3460142472461437916, - "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_array_ops.py": 6709502157317299163, - "venv/lib/python3.13/site-packages/anyio/_core/_sockets.py": 10525237827959090532, - "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_elffile.py": 5728213398707817049, - "venv/lib/python3.13/site-packages/jsonschema/benchmarks/useless_applicator_schemas.py": 8395157526634674143, - "venv/lib/python3.13/site-packages/pydantic/config.py": 1450073446492183677, - "venv/lib/python3.13/site-packages/numpy/_core/umath.py": 6132761780113682667, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_fiscal.py": 14652343698825214870, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/emath.pyi": 3718540478840842664, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_repeat.py": 18394463352314692642, - "venv/lib/python3.13/site-packages/pygments/lexers/clean.py": 17772169928835025327, - "scripts/generate_financial_arrears_data.py": 15989529185799374517, - "venv/lib/python3.13/site-packages/pip/_internal/utils/direct_url_helpers.py": 6075890513530296650, - "venv/lib/python3.13/site-packages/numpy/_pyinstaller/hook-numpy.py": 5221550291012182443, - "venv/lib/python3.13/site-packages/authlib/oauth2/client.py": 7237359250450222680, - "venv/lib/python3.13/site-packages/pygments/lexers/graphviz.py": 15677908982985025500, - "venv/lib/python3.13/site-packages/websockets/sync/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_odf.py": 15484940480924122966, - "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/METADATA": 13428590545328703138, - "venv/lib/python3.13/site-packages/bcrypt/_bcrypt.pyi": 15067467792538416274, - "venv/lib/python3.13/site-packages/numpy/_core/_add_newdocs_scalars.py": 652332294655046106, - "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/parsing.cpython-313-x86_64-linux-gnu.so": 13104135217735363438, - "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth1/authorization_server.py": 724388765673082720, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/conversion.pyi": 16976386782787920450, - "backend/src/plugins/translate/executor.py": 15432132330664319797, - "venv/lib/python3.13/site-packages/pandas/tests/io/generate_legacy_storage_files.py": 11015954144633661960, - "venv/lib/python3.13/site-packages/urllib3/contrib/socks.py": 645086578806871685, - "backend/src/plugins/translate/__tests__/test_inline_correction.py": 3246602656771855554, - "venv/lib/python3.13/site-packages/pygments/lexers/gsql.py": 15294109558028161389, - "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/unevaluated": 11193150813314469394, - "venv/lib/python3.13/site-packages/pandas/tseries/frequencies.py": 2262381949755250516, - "venv/lib/python3.13/site-packages/keyring/cli.py": 10996746519742056101, - "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/meta-data": 11957232619107868023, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/highlighter.py": 10615901258492570740, - "venv/lib/python3.13/site-packages/pip/_internal/vcs/subversion.py": 7423946096970870727, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ufuncs.pyi": 14995898537484305307, - "venv/lib/python3.13/site-packages/starlette/middleware/cors.py": 11384893784314197864, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/Postfix.py": 4440659352851541547, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/connection.py": 8190661510572400096, - "venv/lib/python3.13/site-packages/numpy/random/_generator.cpython-313-x86_64-linux-gnu.so": 15625019745021657670, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7515/jws.py": 7505219131537941130, - "venv/lib/python3.13/site-packages/fastapi/datastructures.py": 727178955746650271, - "venv/lib/python3.13/site-packages/starlette/_utils.py": 8384087194580626069, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/pager.py": 18072372651585577904, - "venv/lib/python3.13/site-packages/pandas/core/arrays/timedeltas.py": 7318851108932357510, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/revocation.py": 5718403706971163960, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_timedeltaindex.py": 2359681317403710563, - "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/__init__.py": 11709551233929312136, - "venv/lib/python3.13/site-packages/pandas/tests/window/test_numba.py": 6409810497251251179, - "venv/lib/python3.13/site-packages/charset_normalizer/utils.py": 11724147997933584095, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/columns.py": 8488246354818721406, - "venv/lib/python3.13/site-packages/pygments/lexers/modeling.py": 15714077241620129689, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_snap.py": 4515844385819802784, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_os.h": 7883047506449405400, - "frontend/src/lib/components/dataset-review/ExecutionMappingReview.svelte": 11412197655386056417, - "backend/src/api/routes/translate/_router.py": 12128313085703966868, - "venv/lib/python3.13/site-packages/PIL/GbrImagePlugin.py": 7681313333602257802, - "venv/lib/python3.13/site-packages/numpy/_typing/_nbit_base.pyi": 6546751036506752550, - "venv/lib/python3.13/site-packages/numpy/random/_mt19937.pyi": 15904463104068500379, - "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/test_support.pyi": 3893434234020223151, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_counting.py": 5628494712451120258, - "venv/lib/python3.13/site-packages/uvicorn/middleware/proxy_headers.py": 13206297306768491360, - "venv/lib/python3.13/site-packages/smmap/test/test_util.py": 5634593621291240094, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py": 6109201994963211857, - "venv/lib/python3.13/site-packages/apscheduler/schedulers/blocking.py": 3483388533957772681, - "venv/lib/python3.13/site-packages/numpy/lib/user_array.py": 14003456655595459585, - "venv/lib/python3.13/site-packages/click/parser.py": 13988544851350599869, - "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/secrets.py": 17816662030600756342, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/string.f": 17328443345813567449, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh24662.f90": 4241310200087270990, - "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/RECORD": 15865206372525596795, - "venv/lib/python3.13/site-packages/pygments/lexers/prql.py": 1159462562014166646, - "frontend/src/components/llm/ProviderConfig.svelte": 3397430691323614679, - "venv/lib/python3.13/site-packages/pydantic/_internal/_decorators.py": 9928398334052202841, - "venv/lib/python3.13/site-packages/jsonschema/tests/typing/test_all_concrete_validators_match_protocol.py": 14824388798676578409, - "venv/lib/python3.13/site-packages/iniconfig/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/httpx/_api.py": 6697370469329778523, - "venv/lib/python3.13/site-packages/gitdb/const.py": 14122142034887286559, - "venv/lib/python3.13/site-packages/numpy/random/_examples/cython/extending_distributions.pyx": 15302775787158991386, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-expm1.csv": 8710594949902856122, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/pg8000.py": 6580512354643849828, - "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/websockets_impl.py": 15673691977157706075, - "venv/lib/python3.13/site-packages/annotated_types/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/core": 10616484054735611337, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/padding.py": 11244071766694094554, - "venv/lib/python3.13/site-packages/pandas/core/flags.py": 4690844374637430013, - "venv/lib/python3.13/site-packages/pandas/tests/base/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/fixtures/orm.py": 7554417559838785150, - "venv/lib/python3.13/site-packages/pygments/lexers/qlik.py": 3881663935630350152, - "venv/lib/python3.13/site-packages/pygments/lexers/asc.py": 10744437946030875496, - "frontend/postcss.config.js": 5714274776976071678, - "venv/lib/python3.13/site-packages/h11/py.typed": 12358286306858197118, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_accessor.py": 10074496835594855786, - "backend/src/plugins/__init__.py": 17194112070692432889, - "venv/lib/python3.13/site-packages/uvicorn/protocols/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/jsonschema/benchmarks/useless_keywords.py": 11487954623214475915, - "venv/lib/python3.13/site-packages/passlib/ext/__init__.py": 15240312484046875203, - "venv/lib/python3.13/site-packages/pygments/lexers/vip.py": 11287963054551122004, - "venv/lib/python3.13/site-packages/jsonschema/benchmarks/contains.py": 3098087827310439993, - "venv/lib/python3.13/site-packages/dateutil/tz/_factories.py": 7538654189286887518, - "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_take.py": 9847808489301498487, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/jwt_bearer.py": 6973859422068490274, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/__main__.py": 487896753130729554, - "venv/lib/python3.13/site-packages/numpy/random/tests/test_regression.py": 9375525053479844400, - "venv/lib/python3.13/site-packages/pandas/util/_doctools.py": 3766479022075611396, - "frontend/src/routes/dashboards/[id]/components/DashboardLinkedResources.svelte": 8279080994517688482, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_symbolic.py": 8093576026032854125, - "venv/lib/python3.13/site-packages/pygments/lexers/wowtoc.py": 17527844575999013592, - "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/licenses/LICENSE": 3868190977070717994, - "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/WHEEL": 16223367184831500348, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_pytables_missing.py": 12154582133989896069, - "venv/lib/python3.13/site-packages/git/compat.py": 16843345645628515492, - "frontend/build/_app/immutable/chunks/CMf6_6c5.js": 8239303945597047871, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/__init__.py": 5118993772178969104, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/_openssl.pyi": 4376871621615688626, - "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/licenses/LICENSE": 6653202620765194772, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_astype.py": 6578539240745332772, - "backend/tests/test_resource_hubs.py": 3990299394875930767, - "frontend/build/_app/immutable/chunks/Bvsi1riv.js": 1050921296731081209, - "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_complex/foo77.f": 7353666717928699883, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/segment.py": 2555584120510872966, - "venv/lib/python3.13/site-packages/sqlalchemy/connectors/aioodbc.py": 2018840826888846321, - "venv/lib/python3.13/site-packages/gitdb/test/test_base.py": 16305779366785148795, - "venv/lib/python3.13/site-packages/click/_winconsole.py": 8133229457213704188, - "venv/lib/python3.13/site-packages/_pytest/cacheprovider.py": 5114545353355728201, - "venv/lib/python3.13/site-packages/urllib3/response.py": 1987354357306756790, - "venv/lib/python3.13/site-packages/pydantic/deprecated/json.py": 17692639396786690144, - "venv/lib/python3.13/site-packages/numpy/lib/recfunctions.pyi": 10487441680587530350, - "venv/lib/python3.13/site-packages/pygments/lexers/promql.py": 8929925488296216854, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/exc.py": 3242780937124999391, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/types.py": 1343652083039949282, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/nested_sequence.pyi": 11245460325970663922, - "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_indexing.py": 14461606056665485421, - "venv/lib/python3.13/site-packages/ecdsa/der.py": 9374566189581725372, - "venv/lib/python3.13/site-packages/uvicorn/supervisors/basereload.py": 14479857245734482609, - "venv/lib/python3.13/site-packages/pandas/_libs/sas.cpython-313-x86_64-linux-gnu.so": 16309838137741124637, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_api.py": 14120915875574640262, - "venv/lib/python3.13/site-packages/starlette/middleware/sessions.py": 11719848399661632707, - "venv/lib/python3.13/site-packages/_pytest/_io/saferepr.py": 8025234471485188730, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/mod.pyi": 10591120373577657317, - "venv/lib/python3.13/site-packages/pandas/core/arrays/categorical.py": 15993211255162930859, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_string.py": 9224234539232195189, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/indexable.py": 4131796922597075758, - "backend/src/api/routes/dashboards/_projection.py": 1559143255780155174, - "backend/src/services/git/_status.py": 8680190871452171795, - "venv/lib/python3.13/site-packages/pygments/styles/_mapping.py": 11752660241391232497, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/methods/test_as_unit.py": 4283520188709399244, - "frontend/build/_app/immutable/chunks/EgbRkp7y.js": 17762282902360655390, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/_initialize.py": 15511055314565873928, - "venv/lib/python3.13/site-packages/git/index/__init__.py": 7874728461616959441, - "venv/lib/python3.13/site-packages/numpy/_core/_simd.cpython-313-x86_64-linux-gnu.so": 12609666221355091416, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_deprecate_kwarg.py": 10417724544218303733, - "venv/lib/python3.13/site-packages/passlib/tests/test_hosts.py": 8284535274820610802, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/npyio.pyi": 15811156298637131744, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_umath.py": 13010939919217862164, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/__init__.py": 293004106962245584, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/AB.inc": 10441778083831997423, - "venv/lib/python3.13/site-packages/pycparser/__init__.py": 16499940957411260458, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/styled.py": 8726407298858811635, - "venv/lib/python3.13/site-packages/pandas/core/internals/ops.py": 4740509262379451243, - "venv/lib/python3.13/site-packages/smmap/test/test_tutorial.py": 16309370344201290582, - "venv/lib/python3.13/site-packages/uvicorn/logging.py": 12858188863836778374, - "backend/test_pat_api.py": 4206656943734821967, - "venv/lib/python3.13/site-packages/numpy/char/__init__.pyi": 12214207343146244743, - "venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/METADATA": 14158024963562115116, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/operators.f90": 5949265961908386974, - "frontend/build/_app/immutable/chunks/BD7asREZ.js": 16800371498949052968, - "frontend/build/_app/immutable/chunks/DezVU0o_.js": 8360472471203146195, - "venv/lib/python3.13/site-packages/itsdangerous/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/secretstorage/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/WHEEL": 16097436423493754389, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_libsparse.py": 1859997684694949029, - "venv/lib/python3.13/site-packages/referencing/tests/test_jsonschema.py": 9815500901482570619, - "venv/lib/python3.13/site-packages/pygments/lexers/maple.py": 7402467573829618534, - "venv/lib/python3.13/site-packages/rapidfuzz/__init__.pyi": 13131938031654453415, - "venv/lib/python3.13/site-packages/rapidfuzz/fuzz_cpp_avx2.cpython-313-x86_64-linux-gnu.so": 12574929384355254457, - "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/oauth2_client.py": 6742098857947604729, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/style.py": 10665998898253460114, - "venv/lib/python3.13/site-packages/jeepney/io/blocking.py": 4699555965372200059, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/__init__.py": 13841777369501476946, - "venv/lib/python3.13/site-packages/pip/_internal/cli/status_codes.py": 9143625681947330756, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_non_compound.f90": 8048650253889213460, - "backend/src/core/utils/superset_context_extractor/_base.py": 15730081123519745401, - "venv/lib/python3.13/site-packages/apscheduler/triggers/cron/__init__.py": 14268033439436797364, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_arithmetic.py": 11620920548943067949, - "backend/src/services/__tests__/test_health_service.py": 5498183976797488518, - "venv/lib/python3.13/site-packages/uvicorn/supervisors/watchfilesreload.py": 13062440477475586751, - "venv/lib/python3.13/site-packages/sqlalchemy/events.py": 9329355486544822483, - "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py2-objarr.npy": 9694707264403109829, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/provision.py": 13156893203444936309, - "backend/src/core/task_manager/__tests__/test_context.py": 4211690952139950648, - "venv/lib/python3.13/site-packages/PIL/ImageMath.py": 7395449734007598797, - "venv/lib/python3.13/site-packages/pandas/io/formats/xml.py": 12235904458551067063, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_arraymethod.py": 14421188237635557797, - "venv/lib/python3.13/site-packages/numpy/_core/arrayprint.py": 1262543237476191714, - "venv/include/site/python3.13/greenlet/greenlet.h": 16216120538647882082, - "venv/lib/python3.13/site-packages/jose/constants.py": 10880650415673457194, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_finfo.py": 17174674209412768422, - "frontend/build/_app/immutable/chunks/CITo06Mq.js": 12229096590932140328, - "venv/lib/python3.13/site-packages/anyio/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_internal/utils/unpacking.py": 106471890743211548, - "venv/lib/python3.13/site-packages/jose/utils.py": 1926138853970725083, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/__init__.py": 15130871412783076140, - "backend/tests/test_models.py": 3998442321184404421, - "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/RECORD": 6187512110158566509, - "venv/lib/python3.13/site-packages/pygments/lexers/j.py": 9766594937623918053, - "frontend/src/lib/stores.js": 8062876368729352764, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/constants.pyi": 15633065380510755171, - "venv/lib/python3.13/site-packages/pip/_internal/operations/install/wheel.py": 3531093454660385247, - "venv/lib/python3.13/site-packages/pygments/scanner.py": 5640381644804445932, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_pivot_multilevel.py": 9830258607305392103, - "backend/src/api/routes/translate/__init__.py": 12084177602375001417, - "venv/lib/python3.13/site-packages/numpy/ma/testutils.pyi": 3899348061346041413, - "venv/lib/python3.13/site-packages/fastapi/_compat/may_v1.py": 9880083742927480960, - "venv/lib/python3.13/site-packages/pygments/styles/vim.py": 2621036947954523349, - "venv/lib/python3.13/site-packages/numpy/lib/format.py": 14971167445246135440, - "venv/lib/python3.13/site-packages/pygments/lexers/_stan_builtins.py": 1961875544235948177, - "frontend/src/lib/components/assistant/__tests__/assistant_confirmation.integration.test.js": 12582020574293031526, - "venv/lib/python3.13/site-packages/httpcore/_backends/sync.py": 576247220834179928, - "venv/lib/python3.13/site-packages/pygments/styles/native.py": 4559566444883341527, - "venv/lib/python3.13/site-packages/yaml/nodes.py": 3463622922914760653, - "venv/lib/python3.13/site-packages/h11/_state.py": 11398755254809751139, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/metrics_cpp_avx2.cpython-313-x86_64-linux-gnu.so": 2991745295485163924, - "venv/lib/python3.13/site-packages/psycopg2/_psycopg.cpython-313-x86_64-linux-gnu.so": 13471342289207537479, - "venv/lib/python3.13/site-packages/_pytest/raises.py": 8188402179490363767, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/lib_version.py": 10384171076976071398, - "venv/lib/python3.13/site-packages/pandas/core/sparse/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/nditer.py": 10038360623032425884, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/validator.py": 11486125578281617670, - "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/AUTHORS": 10073225185964928425, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_equals.py": 18261810467289276844, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_setops.py": 5208912445718807372, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/_neighborhood_iterator_imp.h": 10634781863364525895, - "venv/lib/python3.13/site-packages/authlib/integrations/starlette_client/integration.py": 3085827906490477329, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_partial.py": 3151286293440416036, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_arithmetics.py": 16527169124402715210, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_setops.py": 17350958906336246626, - "frontend/src/components/DashboardGrid.svelte": 5332611872674866671, - "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/INSTALLER": 17282701611721059870, - "frontend/build/_app/immutable/chunks/CiqmpDGb.js": 15624069632350610927, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_head_tail.py": 13047338070883375426, - "venv/lib/python3.13/site-packages/pip/_vendor/truststore/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/datetimes/test_reductions.py": 1713831062142840146, - "venv/lib/python3.13/site-packages/PIL/FliImagePlugin.py": 13364963053197422923, - "venv/lib/python3.13/site-packages/charset_normalizer/legacy.py": 1706599349563920562, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_map.py": 32086858815359344, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ma.pyi": 8186102816080813799, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_pop.py": 14885271225856187795, - "backend/tests/core/migration/test_dry_run_orchestrator.py": 5158126098685923841, - "venv/lib/python3.13/site-packages/anyio/_core/_typedattr.py": 17584691045493791349, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/string_/test_concat.py": 3788461606817482165, - "venv/lib/python3.13/site-packages/annotated_types/test_cases.py": 5123395674810472016, - "venv/lib/python3.13/site-packages/greenlet/greenlet_allocator.hpp": 11041111583319491309, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_array_api_info.py": 16491629653122827368, - "venv/lib/python3.13/site-packages/secretstorage/__init__.py": 4535964275649588672, - "venv/lib/python3.13/site-packages/keyring/__main__.py": 14602212239605295451, - "venv/lib/python3.13/site-packages/pip/_internal/operations/build/wheel_editable.py": 14352954849821931255, - "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/LICENSE": 16343563559291870811, - "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/providers.py": 7267821734584612032, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_setops.py": 8622608042929141013, - "venv/lib/python3.13/site-packages/sqlalchemy/event/registry.py": 2857989070743633709, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_constructors.py": 11065058462752831997, - "venv/lib/python3.13/site-packages/PIL/ImageShow.py": 11437096951764124817, - "venv/lib/python3.13/site-packages/yaml/serializer.py": 1783761365703703558, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/traversals.py": 1188980668212022868, - "venv/lib/python3.13/site-packages/pip/_internal/utils/wheel.py": 450504439085405418, - "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/METADATA": 7788873460115135563, - "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/WHEEL": 7145482834744213753, - "frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js": 15091004230843271151, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/nbit_base_example.pyi": 8571452382806614924, - "venv/lib/python3.13/site-packages/pandas/core/ops/missing.py": 9493665944764255854, - "venv/lib/python3.13/site-packages/pandas/tests/io/test_iceberg.py": 1726421917529457420, - "venv/lib/python3.13/site-packages/pygments/lexers/idl.py": 11454152060351801696, - "venv/lib/python3.13/site-packages/PIL/ImageColor.py": 17058618058554970738, - "frontend/src/routes/admin/settings/llm/+page.svelte": 8015678318492837753, - "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_symbol.py": 10792387279408528886, - "venv/lib/python3.13/site-packages/pandas/core/computation/expr.py": 13085709365673019494, - "venv/lib/python3.13/site-packages/cffi/model.py": 13544803366359102016, - "venv/lib/python3.13/site-packages/pandas/tests/frame/test_api.py": 5813060676255093777, - "venv/lib/python3.13/site-packages/numpy/lib/_index_tricks_impl.pyi": 5892973170789971535, - "venv/lib/python3.13/site-packages/pandas/tests/io/test_sql.py": 3901697517087276687, - "venv/lib/python3.13/site-packages/websockets/legacy/framing.py": 12759022769700230409, - "venv/lib/python3.13/site-packages/typing_inspection/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pydantic/_internal/_validators.py": 2939255306814626438, - "frontend/svelte.config.js": 8473636210766821560, - "backend/src/plugins/translate/__tests__/test_orchestrator.py": 17131259366407024684, - "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/RECORD": 7914594107698271488, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/argon2.py": 15389474901714096890, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/cryptography/hazmat/__init__.py": 6534110674636458866, - "venv/lib/python3.13/site-packages/pandas/core/dtypes/missing.py": 11241703105777668183, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_combine.py": 4446011286411407708, - "venv/lib/python3.13/site-packages/pandas/io/formats/templates/html_style.tpl": 3352086677417301397, - "venv/lib/python3.13/site-packages/pillow.libs/liblcms2-cc10e42f.so.2.0.17": 4221600618602131476, - "backend/tests/services/dataset_review/test_superset_matrix.py": 5114797134613078913, - "venv/lib/python3.13/site-packages/pydantic/fields.py": 4142211199816898047, - "backend/alembic/README": 17625003422504608299, - "venv/lib/python3.13/site-packages/pip/_internal/operations/build/build_tracker.py": 9389444024234384408, - "venv/lib/python3.13/site-packages/pip/_internal/network/__init__.py": 1586148254475575526, - "venv/lib/python3.13/site-packages/httpx/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/random/tests/test_seed_sequence.py": 7687465232954593311, - "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/zip-safe": 15240312484046875203, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/dsa.pyi": 1065808244870331598, - "venv/lib/python3.13/site-packages/numpy/matrixlib/__init__.pyi": 1942236362568669510, - "backend/src/api/routes/__init__.py": 9441391336360835840, - "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libkrb5support-d0bcff84.so.0.1": 16819924515291719993, - "venv/lib/python3.13/site-packages/gitdb/test/lib.py": 13294941660283059872, - "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/WHEEL": 6514509858522675228, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_indexing.py": 9988098331562906950, - "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/WHEEL": 5990830714395966792, - "venv/lib/python3.13/site-packages/pygments/lexers/modula2.py": 6575895980250662093, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_union_categoricals.py": 6843679254735807, - "venv/lib/python3.13/site-packages/numpy/ma/tests/test_subclassing.py": 17318983445227658412, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_repr.py": 5577699046802107144, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/ndarrayobject.h": 7320510589635636690, - "venv/lib/python3.13/site-packages/jeepney-0.9.0.dist-info/licenses/LICENSE": 11986475601091748012, - "venv/lib/python3.13/site-packages/httpcore/_sync/interfaces.py": 1532245423878428608, - "venv/lib/python3.13/site-packages/pandas/tests/util/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/frame/test_alter_axes.py": 11338712836362534969, - "backend/src/api/routes/assistant/_llm_planner_intent.py": 10603216032586398176, - "backend/src/services/mapping_service.py": 5976063352141712188, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7519/jwt.py": 9642615960197748105, - "venv/lib/python3.13/site-packages/packaging/_manylinux.py": 8268418900652790584, - "backend/alembic/versions/aa1b2c3d4e5f_drop_deprecated_translate_columns.py": 15433357059529111004, - "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/authorization_server.py": 17967809814827547139, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/Hamming.py": 3762934316884129514, - "venv/lib/python3.13/site-packages/pydantic/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_csv.py": 6678500392137188521, - "venv/lib/python3.13/site-packages/jaraco/functools/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/authlib/integrations/django_client/integration.py": 13610682193839598457, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_take.py": 3281943380342853080, - "backend/src/api/routes/__tests__/conftest.py": 8465980330386544642, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/models.py": 16636119441941357281, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/util.py": 5252158959761945519, - "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/METADATA": 2053484635654179443, - "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/RECORD": 16740224557818847141, - "venv/lib/python3.13/site-packages/passlib/tests/test_pwd.py": 10089138951415591061, - "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/RECORD": 10036839994791510159, - "venv/lib/python3.13/site-packages/pandas/tests/extension/base/__init__.py": 16123561007855424016, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_append.py": 9644955836191900614, - "venv/lib/python3.13/site-packages/pip/_vendor/distlib/compat.py": 17520043776344667309, - "venv/lib/python3.13/site-packages/numpy/testing/_private/__init__.pyi": 15130871412783076140, - "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_django.py": 8455054295577203929, - "venv/lib/python3.13/site-packages/pandas/compat/pickle_compat.py": 11073483984394766474, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/__init__.py": 14522970260621605208, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_character/foo90.f90": 2435648607844815947, - "venv/lib/python3.13/site-packages/pip/_internal/resolution/legacy/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_internal/utils/urls.py": 8698341051522816167, - "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/provider.py": 16463243654123731993, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/hashes.py": 8545380307201732345, - "venv/lib/python3.13/site-packages/gitdb/utils/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/fastapi/requests.py": 14587947416691824903, - "venv/lib/python3.13/site-packages/pip/_internal/self_outdated_check.py": 991029278889407558, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/rsa.pyi": 13850254283540522444, - "venv/lib/python3.13/site-packages/numpy/_utils/_pep440.py": 15854257948148516490, - "venv/lib/python3.13/site-packages/urllib3/util/ssltransport.py": 1175688460659745788, - "frontend/src/services/__tests__/gitService.test.js": 12845562082447336909, - "backend/src/api/routes/translate/_schedule_routes.py": 9081639461481759877, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_size.py": 14032390806503440750, - "venv/lib/python3.13/site-packages/pip/_internal/distributions/wheel.py": 13979536782410081712, - "venv/lib/python3.13/site-packages/numpy/tests/test_warnings.py": 3154249157134620649, - "venv/lib/python3.13/site-packages/pygments/lexers/fift.py": 7537570342576781911, - "venv/lib/python3.13/site-packages/jsonschema/tests/_suite.py": 6307666366417438489, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked_shared.py": 8453174300922339015, - "venv/lib/python3.13/site-packages/pandas/_testing/__init__.py": 10127496080404419481, - "venv/lib/python3.13/site-packages/pandas/tests/window/test_expanding.py": 9047466276603454007, - "venv/lib/python3.13/site-packages/pip/_internal/req/req_uninstall.py": 3515239440812977025, - "venv/lib/python3.13/site-packages/pygments/formatters/other.py": 13124903290103898118, - "venv/lib/python3.13/site-packages/numpy/_core/lib/npy-pkg-config/mlib.ini": 16151597765994697599, - "venv/lib/python3.13/site-packages/numpy/_expired_attrs_2_0.py": 8786558894094307341, - "venv/lib/python3.13/site-packages/pip/_internal/req/constructors.py": 17485271035479378662, - "backend/tests/test_translate_scheduler.py": 14274816721941617887, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_reduction.py": 1049551473665255648, - "venv/lib/python3.13/site-packages/cryptography/x509/oid.py": 13909847799728532602, - "backend/tests/services/clean_release/test_candidate_manifest_services.py": 16861589402854148894, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_asof.py": 15792528637923603240, - "backend/tests/test_translate_scheduler_guard.py": 13396608843530344156, - "frontend/build/_app/immutable/chunks/omsjLJ6z.js": 45189729016770272, - "backend/src/plugins/translate/prompt_builder.py": 5148937139906904004, - "venv/lib/python3.13/site-packages/pandas/tests/test_expressions.py": 16378925536309828288, - "venv/lib/python3.13/site-packages/ecdsa/test_curves.py": 6577762025900435885, - "venv/lib/python3.13/site-packages/numpy/f2py/crackfortran.py": 12796890117561096360, - "venv/lib/python3.13/site-packages/pandas/tests/extension/uuid/test_uuid.py": 13955678427426850807, - "venv/lib/python3.13/site-packages/pygments/lexers/tlb.py": 1169242051301155885, - "frontend/src/components/StartupEnvironmentWizard.svelte": 6947772062866928838, - "backend/src/api/routes/assistant/_command_parser.py": 2745692387994130159, - "venv/lib/python3.13/site-packages/pygments/lexers/jsonnet.py": 1314044008440065525, - "venv/lib/python3.13/site-packages/pydantic/v1/errors.py": 11245135449608452720, - "frontend/src/routes/+page.svelte": 5766160745549070101, - "frontend/src/components/git/ConflictResolver.svelte": 12431368407090802392, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_sort_values.py": 15072305514178699398, - "venv/lib/python3.13/site-packages/pygments/util.py": 4815334059917765852, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7592/endpoint.py": 18260428408051728802, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/util.py": 6088868370298560146, - "venv/lib/python3.13/site-packages/jeepney/io/__init__.py": 2568357146184259175, - "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_setitem.py": 14920902525192671548, - "venv/lib/python3.13/site-packages/pandas/core/reshape/encoding.py": 12702053687535473061, - "venv/lib/python3.13/site-packages/pandas/tests/test_nanops.py": 8709105600366913011, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/descriptor_props.py": 7044852927393650707, - "venv/lib/python3.13/site-packages/pyasn1/compat/__init__.py": 5902203086150636670, - "venv/lib/python3.13/site-packages/jsonschema/benchmarks/__init__.py": 5863110456909134678, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/hooks.py": 8580161128344266243, - "venv/lib/python3.13/site-packages/numpy/testing/__init__.pyi": 8126257788928282891, - "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/licenses/LICENSE.APACHE": 8359973023624924624, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py": 16768579082462294745, - "venv/lib/python3.13/site-packages/yaml/error.py": 5626374410579058436, - "venv/lib/python3.13/site-packages/pyasn1/codec/native/decoder.py": 15336592439379775543, - "venv/lib/python3.13/site-packages/typing_inspection/typing_objects.pyi": 18193727720492050602, - "venv/lib/python3.13/site-packages/fastapi/openapi/models.py": 1680354178147364813, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_sh_gcc.h": 3574353221233465215, - "venv/lib/python3.13/site-packages/passlib/tests/test_handlers.py": 4940305787631493030, - "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/zip-safe": 15240312484046875203, - "venv/lib/python3.13/site-packages/pip/_vendor/distlib/wheel.py": 828222664427570058, - "venv/lib/python3.13/site-packages/passlib/totp.py": 14590474309565233318, - "venv/lib/python3.13/site-packages/starlette/concurrency.py": 9835859079437525910, - "venv/lib/python3.13/site-packages/pygments/lexers/_vbscript_builtins.py": 9882134558469491349, - "venv/lib/python3.13/site-packages/ecdsa/ssh.py": 17010933326090778158, - "venv/lib/python3.13/site-packages/numpy/_pytesttester.pyi": 5750506937526308405, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_describe.py": 11923715539897559626, - "frontend/build/_app/immutable/chunks/BOaVavs8.js": 7966656432589868496, - "backend/src/services/rbac_permission_catalog.py": 4811877724682885443, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_csky_gcc.h": 12929785267195988209, - "venv/lib/python3.13/site-packages/pip/_internal/utils/glibc.py": 12335359492756627313, - "venv/lib/python3.13/site-packages/pygments/lexers/ul4.py": 9580182474451220952, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/test_federal.py": 16758212916399857971, - "venv/lib/python3.13/site-packages/ecdsa/test_eddsa.py": 1785854649532849946, - "venv/lib/python3.13/site-packages/attr/_make.py": 2348458829123990579, - "backend/src/core/auth/repository.py": 7314530014494164270, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/_initialize_cpp.cpython-313-x86_64-linux-gnu.so": 7490281502544276964, - "venv/lib/python3.13/site-packages/pygments/lexers/_mql_builtins.py": 2376212048709413586, - "venv/lib/python3.13/site-packages/numpy/f2py/common_rules.py": 7352635707860427145, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_equals.py": 9903250467264848187, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_iter.py": 9232021002336641851, - "backend/src/models/dataset_review_pkg/_profile_models.py": 3121807680272913669, - "venv/lib/python3.13/site-packages/referencing/_attrs.pyi": 10030665705880994025, - "venv/lib/python3.13/site-packages/pandas/tests/series/test_subclass.py": 13490541871827928531, - "venv/lib/python3.13/site-packages/pandas/io/formats/html.py": 11849941990375030601, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_pct_change.py": 18056235438452125034, - "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_searchsorted.py": 12074107109575676897, - "venv/lib/python3.13/site-packages/pydantic/_internal/_repr.py": 1758478941817868344, - "frontend/build/_app/immutable/nodes/34.B1G9Ceba.js": 15227780133014315507, - "backend/src/services/clean_release/repositories/candidate_repository.py": 14784344453820731941, - "venv/lib/python3.13/site-packages/greenlet/tests/fail_clearing_run_switches.py": 3020294789560975101, - "venv/lib/python3.13/site-packages/numpy/f2py/_isocbind.py": 15031197044862908440, - "backend/src/plugins/translate/__tests__/test_executor.py": 12854951718356374947, - "venv/lib/python3.13/site-packages/numpy/f2py/_isocbind.pyi": 5786150108623563787, - "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/authorization_server.py": 4427151727224472650, - "backend/src/schemas/dataset_review_pkg/_composites.py": 1898056130177244572, - "backend/src/core/config_manager.py": 18161236261317111528, - "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/RECORD": 11788532857617688351, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_astype.py": 8505605634958454768, - "backend/src/api/routes/assistant/_llm_planner.py": 17830859532452456684, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/_typing.py": 10524021526716767489, - "venv/lib/python3.13/site-packages/pycparser/ast_transforms.py": 9032453625977464506, - "backend/src/core/superset_client/_datasets_preview.py": 16476837380317508068, - "venv/lib/python3.13/site-packages/rapidfuzz/utils.py": 5682627611354455144, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/token.py": 6987328478153445584, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_comment.py": 5603075924832933306, - "venv/lib/python3.13/site-packages/pandas/core/window/expanding.py": 14141093310397856286, - "venv/lib/python3.13/site-packages/greenlet/CObjects.cpp": 3454797518210223926, - "backend/src/core/auth/oauth.py": 9925908783612235042, - "venv/lib/python3.13/site-packages/pandas/core/arrays/interval.py": 16281221279220043867, - "backend/src/api/routes/llm.py": 5549663650842379152, - "venv/lib/python3.13/site-packages/pandas/_libs/tslib.cpython-313-x86_64-linux-gnu.so": 10742615805788605480, - "venv/lib/python3.13/site-packages/pygments/styles/autumn.py": 8750937312198920971, - "venv/lib/python3.13/site-packages/numpy/matrixlib/__init__.py": 18402126171936308228, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_factorize.py": 5585211699185937865, - "venv/lib/python3.13/site-packages/pygments/lexers/eiffel.py": 8964563077187051946, - "frontend/src/routes/translate/history/+page.svelte": 8993421379788635747, - "frontend/build/_app/immutable/nodes/16.ClShNgv8.js": 11360248111062186711, - "venv/lib/python3.13/site-packages/apscheduler/executors/twisted.py": 2695602672085615762, - "venv/lib/python3.13/site-packages/packaging/_tokenizer.py": 7442392076059866359, - "venv/lib/python3.13/site-packages/pandas/tests/strings/test_extract.py": 14547819021277949280, - "venv/lib/python3.13/site-packages/pandas/tests/io/conftest.py": 5864037534050136837, - "venv/lib/python3.13/site-packages/pluggy/_manager.py": 18202550145040079612, - "venv/lib/python3.13/site-packages/pandas/tests/frame/test_ufunc.py": 5025605639221470838, - "venv/lib/python3.13/site-packages/pandas/tests/extension/base/missing.py": 14589973874359353799, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/test_arrow_compat.py": 12986187285988432338, - "venv/lib/python3.13/site-packages/PIL/ImagePath.py": 18323293175183057101, - "venv/lib/python3.13/site-packages/pygments/lexers/savi.py": 95400050302239274, - "venv/lib/python3.13/site-packages/pip/_vendor/tomli/__init__.py": 12906995259233516197, - "venv/lib/python3.13/site-packages/numpy/ma/README.rst": 13203411621071845216, - "frontend/src/routes/dashboards/+page.svelte": 7340914202224737248, - "venv/lib/python3.13/site-packages/gitdb/test/test_pack.py": 7518388297247535189, - "backend/alembic/versions/2a7b8c9d0e1f_add_target_languages_to_translation_jobs.py": 7201017059554918882, - "venv/lib/python3.13/site-packages/numpy/random/tests/data/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test__exceptions.py": 12099001631178696189, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/__main__.py": 111505188798650285, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/transform/test_transform.py": 5674175311567817854, - "venv/lib/python3.13/site-packages/pygments/lexers/blueprint.py": 6370363226580199085, - "venv/lib/python3.13/site-packages/pandas/tests/resample/conftest.py": 1643522609234951699, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/_typing.py": 17598638528781632158, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_kind.py": 18178830861475480607, - "venv/lib/python3.13/site-packages/pandas/io/sas/__init__.py": 8095743504390517992, - "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/resource_protector.py": 3563910821279222695, - "venv/lib/python3.13/site-packages/git/refs/reference.py": 2038789918710608481, - "frontend/build/_app/immutable/nodes/12.C45g1odY.js": 3364177908218078138, - "venv/lib/python3.13/site-packages/pygments/lexers/macaulay2.py": 8022891778577314212, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/device_code.py": 6712610002227849281, - "backend/src/api/routes/assistant/_resolvers.py": 1139669723103531814, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/token.py": 4161760290367932793, - "venv/lib/python3.13/site-packages/h11/_readers.py": 832030916375670301, - "venv/lib/python3.13/site-packages/starlette/templating.py": 9242638124487797988, - "venv/lib/python3.13/site-packages/numpy/lib/_iotools.py": 10522826373041592861, - "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/applicator": 6616723520993329538, - "frontend/build/_app/immutable/nodes/7.D1ZRe8Pd.js": 10261432846649332940, - "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/_impl.py": 16610770935842519289, - "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/WHEEL": 16097436423493754389, - "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/min_max_.py": 13457611930368041821, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_interval_range.py": 9900908262700749861, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_shift.py": 14026124784027171225, - "venv/lib/python3.13/site-packages/websockets/__init__.py": 4916307256304054040, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_inspect.py": 10573558345297891848, - "venv/lib/python3.13/site-packages/passlib/tests/sample_config_1s.cfg": 1809713544666311828, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_reindex_like.py": 1407890639206728014, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_common.py": 12064185052519470358, - "venv/lib/python3.13/site-packages/pandas/tests/frame/constructors/test_from_dict.py": 4937173601709369119, - "venv/lib/python3.13/site-packages/pygments/styles/algol.py": 3040373291664740876, - "frontend/build/_app/immutable/nodes/21.elO5x4W8.js": 7224240725322450585, - "venv/lib/python3.13/site-packages/pygments/lexers/go.py": 11118104397271513417, - "venv/lib/python3.13/site-packages/keyring/backends/macOS/api.py": 4502902558534812719, - "backend/src/api/routes/dashboards/__init__.py": 15214026957520044598, - "venv/lib/python3.13/site-packages/pandas/tests/window/test_rolling_quantile.py": 4225791949463893856, - "venv/lib/python3.13/site-packages/numpy/_pyinstaller/tests/pyinstaller-smoke.py": 13570990531070630950, - "venv/lib/python3.13/site-packages/pandas/util/version/__init__.py": 3844072588696074141, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_backend.py": 17793139799410518847, - "venv/lib/python3.13/site-packages/pygments/lexers/_julia_builtins.py": 8846111188795315103, - "venv/lib/python3.13/site-packages/greenlet/greenlet.cpp": 3281107194043468270, - "venv/lib/python3.13/site-packages/pydantic/plugin/__init__.py": 16803973597469216174, - "venv/lib/python3.13/site-packages/pandas/core/methods/selectn.py": 13552176539021625776, - "venv/lib/python3.13/site-packages/pandas/io/api.py": 8275376846208437741, - "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pandas/_libs/sas.pyi": 873957906443703977, - "frontend/build/_app/immutable/nodes/10.CN_3DgUX.js": 2682713571147054657, - "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libsasl2-883649fd.so.3.0.0": 13306917506408577991, - "venv/lib/python3.13/site-packages/pandas/tests/frame/test_repr.py": 16609300578827398344, - "backend/_convert_defs.py": 208535643309836247, - "frontend/src/routes/login/+page.svelte": 4542360917085342323, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/protocol.py": 932296179250981622, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm64_masm.asm": 16630507336149184509, - "venv/lib/python3.13/site-packages/numpy/typing/tests/test_typing.py": 10311989961588249147, - "venv/lib/python3.13/site-packages/rapidfuzz/process_cpp.py": 16797760903996739079, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_time_series.py": 5205199092955498507, - "frontend/src/lib/components/health/PolicyForm.svelte": 10697252862978287099, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_constructors.py": 5627819885594450614, - "venv/lib/python3.13/site-packages/numpy/linalg/tests/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/x25519.pyi": 11455144434558323236, - "venv/lib/python3.13/site-packages/numpy/_core/_type_aliases.pyi": 15848834171197104301, - "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/LICENSE": 16174281248426886206, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_cov_corr.py": 13652339565475304679, - "venv/lib/python3.13/site-packages/rapidfuzz/_feature_detector.py": 15458248567257759500, - "venv/lib/python3.13/site-packages/pandas/tests/frame/test_validate.py": 12789481642730855139, - "venv/lib/python3.13/site-packages/_pytest/tmpdir.py": 10834220332037364219, - "venv/lib/python3.13/site-packages/sqlalchemy/engine/reflection.py": 5951113078754792806, - "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/util.py": 2866856507760047219, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/block_docstring/foo.f": 2489756567993745076, - "venv/lib/python3.13/site-packages/pandas/tests/extension/test_datetime.py": 1678885152993000592, - "venv/lib/python3.13/site-packages/numpy/tests/test_numpy_config.py": 3636377988901907424, - "venv/lib/python3.13/site-packages/PIL/__main__.py": 827665918723937817, - "venv/lib/python3.13/site-packages/numpy/_core/getlimits.pyi": 15746478550640231553, - "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_scrypt.py": 8106466515670064013, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_melt.py": 15663807247682146566, - "venv/lib/python3.13/site-packages/keyring/core.py": 2764269590123131634, - "venv/lib/python3.13/site-packages/pandas/_libs/index.pyi": 17679349633640606985, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_grouping.py": 5994909693214299971, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_reset_index.py": 5946666595195952693, - "venv/lib/python3.13/site-packages/git/objects/submodule/root.py": 5322248117564025370, - "venv/lib/python3.13/site-packages/pygments/lexers/_tsql_builtins.py": 829193091321611630, - "venv/lib/python3.13/site-packages/pygments/lexers/rnc.py": 9747352274729854620, - "backend/src/core/utils/superset_compilation_adapter.py": 4974836712746468095, - "backend/src/api/routes/__tests__/test_reports_api.py": 17714266401048048508, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/array_like.pyi": 1968570015765106620, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_custom_business_month.py": 1613806538807726074, - "venv/lib/python3.13/site-packages/pandas/tests/window/test_rolling_skew_kurt.py": 15225601437354712351, - "venv/lib/python3.13/site-packages/pydantic_core/_pydantic_core.pyi": 16799580742094025110, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/json.py": 14755215397454910426, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_equals.py": 9405821443172167066, - "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/format-assertion": 2607512361823362698, - "venv/lib/python3.13/site-packages/numpy/_utils/_convertions.py": 12886275429547303345, - "venv/lib/python3.13/site-packages/numpy/core/__init__.py": 10397294636564169377, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_interval.py": 2911379732293827726, - "venv/lib/python3.13/site-packages/cffi/pkgconfig.py": 16057517851163939571, - "venv/lib/python3.13/site-packages/pandas/tests/io/test_pickle.py": 2910383574326146698, - "frontend/src/routes/dashboards/health/__tests__/health_page.integration.test.js": 11653729504599199718, - "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_period.py": 15671388508498441412, - "backend/src/api/routes/git/_config_routes.py": 6093940098740660772, - "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/REQUESTED": 15130871412783076140, - "frontend/src/components/llm/__tests__/provider_config.integration.test.js": 2061085383592666930, - "venv/lib/python3.13/site-packages/pip/_internal/cli/command_context.py": 9426036980437931533, - "venv/lib/python3.13/site-packages/numpy/core/einsumfunc.py": 3484247123731380377, - "venv/lib/python3.13/site-packages/pandas/_libs/properties.pyi": 9268470215750269699, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_unicode_ddl.py": 2569618488804767890, - "venv/lib/python3.13/site-packages/PIL/PdfParser.py": 13710342183037972042, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_index_equal.py": 10617870815989304510, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/numeric.pyi": 17005748821769179511, - "venv/lib/python3.13/site-packages/numpy/_core/function_base.py": 5676611841071163854, - "venv/lib/python3.13/site-packages/numpy/polynomial/polynomial.pyi": 9935587108964614958, - "venv/lib/python3.13/site-packages/pygments/styles/algol_nu.py": 6229131016121450375, - "backend/src/plugins/llm_analysis/__tests__/test_service.py": 9850768293526486431, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/jwe_algs.py": 2479791018067637690, - "venv/lib/python3.13/site-packages/requests/exceptions.py": 6474239743209354989, - "venv/lib/python3.13/site-packages/numpy/linalg/__init__.pyi": 18409133021422984774, - "venv/lib/python3.13/site-packages/pygments/lexers/bare.py": 18266858932333619451, - "backend/tests/test_logger.py": 11506419828617508917, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_arrayobject.py": 13337664596833150958, - "backend/src/core/auth/logger.py": 14199514105394646252, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/base.py": 16052592982063844259, - "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/anyio/abc/_resources.py": 8330687082933028623, - "venv/lib/python3.13/site-packages/pandas/core/reshape/merge.py": 300205528811693975, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_extension_array_equal.py": 16119106336497630796, - "venv/lib/python3.13/site-packages/numpy/polynomial/legendre.pyi": 2029639875417260268, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/usecols/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/licenses/AUTHORS": 17022185907188244883, - "venv/lib/python3.13/site-packages/git/repo/base.py": 13975465345838683533, - "venv/lib/python3.13/site-packages/pandas/core/algorithms.py": 487939626203097713, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/strings.pyi": 15361498560917514616, - "venv/lib/python3.13/site-packages/fastapi/exceptions.py": 12665775976182239091, - "venv/bin/keyring": 1488968652276547659, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_frozen.py": 3484963987053884566, - "venv/lib/python3.13/site-packages/numpy/_typing/_char_codes.py": 14162745886150625150, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_api.py": 13739775047493489785, - "frontend/src/components/MappingTable.svelte": 3101497452073042168, - "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/lib/_arraypad_impl.py": 6348811074249398741, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/util.py": 4815334059917765852, - "venv/lib/python3.13/site-packages/numpy/_core/_dtype_ctypes.pyi": 14543653817631274394, - "venv/lib/python3.13/site-packages/jeepney/__init__.py": 1063800617763464773, - "venv/lib/python3.13/site-packages/numpy/fft/_pocketfft_umath.cpython-313-x86_64-linux-gnu.so": 16443444849116065961, - "venv/lib/python3.13/site-packages/pandas/tests/apply/test_frame_apply.py": 8103417303073393969, - "venv/lib/python3.13/site-packages/pandas/tests/extension/base/io.py": 11072022722163954973, - "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/WHEEL": 16097436423493754389, - "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_loongarch64_linux.h": 6566098590441297326, - "venv/lib/python3.13/site-packages/numpy/f2py/_src_pyf.pyi": 8916922961301555974, - "venv/lib/python3.13/site-packages/urllib3/connection.py": 12761371748350595804, - "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/METADATA": 3044554568188160018, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/named_types.py": 6099185243355915896, - "frontend/src/components/git/DeploymentModal.svelte": 6232413208557068848, - "frontend/src/routes/settings/EnvironmentsTab.svelte": 16246319452479236452, - "venv/lib/python3.13/site-packages/pip/_vendor/requests/auth.py": 912521029864094489, - "venv/lib/python3.13/site-packages/attrs/converters.py": 13109003765349201809, - "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/METADATA": 8985010079096958084, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/usecols/test_usecols_basic.py": 16382444980424010514, - "venv/lib/python3.13/site-packages/git/refs/tag.py": 9979537867501757110, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_skew.py": 5276102682005383261, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_limited_api.py": 15788485008764560845, - "venv/lib/python3.13/site-packages/numpy/_utils/_pep440.pyi": 6796322258258182775, - "venv/lib/python3.13/site-packages/pandas/_libs/window/indexers.pyi": 9911899303567570646, - "venv/lib/python3.13/site-packages/numpy/lib/_polynomial_impl.pyi": 2042169688753984918, - "venv/lib/python3.13/site-packages/urllib3/http2/connection.py": 1661620860881397554, - "backend/logs/app.log.bak": 12967408684782809237, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7636/challenge.py": 6388445104761482746, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timestamps.cpython-313-x86_64-linux-gnu.so": 13209491675968970365, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_resolution.py": 6076761538303762297, - "venv/lib/python3.13/site-packages/pygments/lexers/nix.py": 15050086330545600356, - "venv/lib/python3.13/site-packages/pandas/tests/test_take.py": 17628004130770326677, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_sequence.py": 3721630758772772345, - "venv/lib/python3.13/site-packages/jaraco/context/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/__init__.pyi": 10548370574281981402, - "venv/lib/python3.13/site-packages/pygments/styles/material.py": 14325514369696961874, - "venv/lib/python3.13/site-packages/authlib/oidc/core/errors.py": 18154419146257747681, - "backend/alembic.ini": 8897071018956157084, - "venv/lib/python3.13/site-packages/pydantic/v1/class_validators.py": 6471688474853407718, - "venv/lib/python3.13/site-packages/requests/api.py": 12339139862411341381, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc_linux.h": 15772978805500070727, - "venv/lib/python3.13/site-packages/pygments/lexers/csound.py": 2175454840368374515, - "frontend/src/components/auth/ProtectedRoute.svelte": 7705373237339863677, - "venv/bin/pip": 13861749540792881808, - "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/licenses/LICENSE": 1424673738228762254, - "venv/lib/python3.13/site-packages/pip/_internal/metadata/importlib/__init__.py": 10834852742917144496, - "venv/lib/python3.13/site-packages/passlib/handlers/postgres.py": 14162382430051693313, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_reductions.py": 3575617237516305456, - "venv/lib/python3.13/site-packages/pygments/lexers/lisp.py": 11872331622183590758, - "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/licenses/LICENSE": 2345070715845618109, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_sort_values.py": 12064896795288302730, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_formats.py": 5259100336852479395, - "frontend/src/services/adminService.js": 6375990585512014277, - "venv/lib/python3.13/site-packages/pandas/tests/io/test_html.py": 12040484325988635032, - "venv/lib/python3.13/site-packages/pygments/lexers/pddl.py": 9256112535059995841, - "venv/lib/python3.13/site-packages/pandas/tests/resample/test_period_index.py": 6634414375581820058, - "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/anyio/from_thread.py": 7973678341601453474, - "venv/lib/python3.13/site-packages/greenlet/TMainGreenlet.cpp": 9489520001674089404, - "venv/lib/python3.13/site-packages/websockets/__main__.py": 11948055520555854616, - "backend/src/api/routes/__tests__/test_tasks_logs.py": 15585487936320145746, - "venv/lib/python3.13/site-packages/urllib3/util/retry.py": 17988032431204662756, - "venv/lib/python3.13/site-packages/greenlet/TExceptionState.cpp": 17617354576371846109, - "venv/lib/python3.13/site-packages/certifi/core.py": 7472627735517449185, - "venv/lib/python3.13/site-packages/pip/_vendor/distlib/index.py": 2763962019423787504, - "venv/lib/python3.13/site-packages/numpy/core/shape_base.py": 17925759824894973734, - "venv/lib/python3.13/site-packages/click/_compat.py": 14451519072991457993, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_tz_convert.py": 13349243029437881949, - "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/LICENSE": 8177430849046795595, - "venv/lib/python3.13/site-packages/greenlet/platform/setup_switch_x64_masm.cmd": 8473866644286785815, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/base.py": 7110726987481713080, - "venv/lib/python3.13/site-packages/cryptography/x509/base.py": 9124948989225782039, - "venv/lib/python3.13/site-packages/pip/_internal/distributions/__init__.py": 1343779312297539596, - "venv/lib/python3.13/site-packages/numpy/random/__init__.py": 11732100564412485633, - "venv/lib/python3.13/site-packages/PIL/_version.py": 3025206805667405876, - "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/RECORD": 18314788057673509075, - "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pluggy/_callers.py": 1042673447718196223, - "venv/lib/python3.13/site-packages/pandas/core/ops/__init__.py": 4049432353810047365, - "venv/lib/python3.13/site-packages/sqlalchemy/util/preloaded.py": 3719702436309355562, - "venv/lib/python3.13/site-packages/charset_normalizer/api.py": 9172704759115759638, - "venv/lib/python3.13/site-packages/pygments/lexers/resource.py": 8057351545636349791, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_mixins.py": 12351373879926460719, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_infer_objects.py": 16868563755487479303, - "venv/lib/python3.13/site-packages/pip/_internal/commands/help.py": 4175797322922912326, - "venv/lib/python3.13/site-packages/passlib/handlers/pbkdf2.py": 16686685453577026643, - "venv/lib/python3.13/site-packages/charset_normalizer/md.cpython-313-x86_64-linux-gnu.so": 1835299664481804968, - "frontend/src/components/git/CommitHistory.svelte": 15861316872235672161, - "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/WHEEL": 16097436423493754389, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/theme.py": 14225878259183479398, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/filepost.py": 16698380375728063923, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/f77comments.f": 4801926170672147659, - "backend/src/api/routes/assistant/_routes.py": 6252816315418755346, - "venv/lib/python3.13/site-packages/numpy/ma/__init__.pyi": 1855615156913010107, - "backend/src/services/clean_release/manifest_service.py": 10873340336255220063, - "venv/lib/python3.13/site-packages/pygments/styles/paraiso_light.py": 15941591873059208999, - "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/licenses/LICENSE": 14230156892574098522, - "venv/lib/python3.13/site-packages/jsonschema/_format.py": 8987698648383779883, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_network.py": 13159427333040109523, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/quoted_character/foo.f": 15318083678609435813, - "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/processors.cpython-313-x86_64-linux-gnu.so": 18139875206371157315, - "venv/lib/python3.13/site-packages/starlette/middleware/trustedhost.py": 8302185291610019926, - "venv/lib/python3.13/site-packages/pip/_internal/models/scheme.py": 4101322315594430874, - "venv/lib/python3.13/site-packages/greenlet/tests/_test_extension_cpp.cpython-313-x86_64-linux-gnu.so": 7659849621107414188, - "venv/lib/python3.13/site-packages/cryptography/hazmat/_oid.py": 755042927629281577, - "venv/lib/python3.13/site-packages/numpy/_core/shape_base.py": 3996519099530770308, - "venv/lib/python3.13/site-packages/pydantic/v1/error_wrappers.py": 5701679786078971939, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/char.f90": 12203871998988759364, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_setops.py": 15196593522537569500, - "venv/lib/python3.13/site-packages/pandas/tests/strings/test_string_array.py": 8260883866404398980, - "venv/lib/python3.13/site-packages/anyio/_core/_tempfile.py": 230288423480899091, - "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/RECORD": 10052481303799123207, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ufunclike.pyi": 12215374902556647369, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/events.py": 7576713358952064464, - "venv/lib/python3.13/site-packages/pydantic_settings/main.py": 17272314000918984790, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/dml.py": 6519732236745017861, - "venv/lib/python3.13/site-packages/numpy/f2py/src/fortranobject.h": 5980733638838895780, - "venv/lib/python3.13/site-packages/pandas/tests/apply/test_frame_transform.py": 6759417099641034692, - "venv/lib/python3.13/site-packages/PIL/McIdasImagePlugin.py": 14137545069906812251, - "venv/lib/python3.13/site-packages/PIL/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/io/formats/string.py": 14718123345899686696, - "venv/lib/python3.13/site-packages/httpcore/_async/connection.py": 2155744160496556069, - "venv/lib/python3.13/site-packages/fastapi/middleware/httpsredirect.py": 5775982317459922443, - "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/RECORD": 9964194961227523130, - "venv/lib/python3.13/site-packages/passlib/ext/django/models.py": 12386223748379294996, - "venv/lib/python3.13/site-packages/requests/_internal_utils.py": 4091305333167213279, - "venv/lib/python3.13/site-packages/click/types.py": 6491651131669287534, - "venv/lib/python3.13/site-packages/numpy/testing/tests/test_utils.py": 5291132432383518704, - "venv/lib/python3.13/site-packages/idna-3.11.dist-info/METADATA": 14036738037171597049, - "venv/lib/python3.13/site-packages/git/objects/fun.py": 15014209679156260865, - "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_coercion.py": 7261787308019145312, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/arrayterator.pyi": 15722265241660279277, - "venv/lib/python3.13/site-packages/git/index/fun.py": 18338379518768926372, - "venv/lib/python3.13/site-packages/PIL/SunImagePlugin.py": 7661622930404688367, - "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_delitem.py": 16538190861492829338, - "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/METADATA": 5628172948035858892, - "venv/lib/python3.13/site-packages/pygments/lexers/capnproto.py": 15713281507099411738, - "frontend/public/vite.svg": 13568221685541582385, - "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_normalize.py": 3203921571999101793, - "venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/INSTALLER": 17282701611721059870, - "frontend/src/lib/stores/__tests__/setupTests.js": 13316015450930652502, - "frontend/src/routes/dashboards/[id]/+page.svelte": 1225758611896418118, - "venv/lib/python3.13/site-packages/pandas/compat/_constants.py": 3909166275649444824, - "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/licenses/LICENSE.BSD": 16833702494864671773, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/_version.py": 15336513445621042105, - "venv/lib/python3.13/site-packages/numpy/f2py/symbolic.pyi": 14558091964387571257, - "frontend/src/components/git/BranchSelector.svelte": 6225347983501401973, - "venv/lib/python3.13/site-packages/passlib/handlers/sha2_crypt.py": 8171587560325812664, - "venv/lib/python3.13/site-packages/dotenv/__init__.py": 15464030923609356017, - "venv/lib/python3.13/site-packages/pycparser/_ast_gen.py": 5464347629908906775, - "venv/lib/python3.13/site-packages/pygments/lexers/_qlik_builtins.py": 1728058904137960444, - "venv/lib/python3.13/site-packages/PIL/XVThumbImagePlugin.py": 7472134175570205454, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_nat.py": 18428782698385974380, - "venv/lib/python3.13/site-packages/jsonschema/_keywords.py": 949562792260528762, - "backend/src/plugins/llm_analysis/scheduler.py": 14673660738877638091, - "venv/lib/python3.13/site-packages/websockets/asyncio/server.py": 885415484558949506, - "venv/lib/python3.13/site-packages/uvicorn/middleware/message_logger.py": 14825516604555033580, - "venv/lib/python3.13/site-packages/pygments/lexers/_lilypond_builtins.py": 1766946089314631488, - "venv/lib/python3.13/site-packages/numpy/f2py/__init__.py": 7470157159992827389, - "venv/lib/python3.13/site-packages/more_itertools/__init__.py": 9858612105173082060, - "venv/lib/python3.13/site-packages/httpcore/_exceptions.py": 6716590711697088732, - "merge_spec.py": 5285945727297582371, - "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/meta-data": 9599129816090399315, - "venv/lib/python3.13/site-packages/pip/_internal/operations/freeze.py": 3469845570614985559, - "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/reporters.py": 10760889726586439724, - "venv/lib/python3.13/site-packages/pydantic/v1/generics.py": 1150594223414883339, - "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_categorical.py": 9923236395692943732, - "venv/lib/python3.13/site-packages/pandas/core/indexers/utils.py": 5861072573716897447, - "backend/src/services/git_service.py": 1930048176535450912, - "venv/lib/python3.13/site-packages/apscheduler/job.py": 1858376671986108667, - "venv/lib/python3.13/site-packages/numpy/f2py/__version__.pyi": 9759534743796867731, - "backend/src/plugins/translate/__tests__/test_sql_generator.py": 4467071942040481147, - "venv/lib/python3.13/site-packages/numpy/_core/printoptions.pyi": 16758392990920041462, - "venv/lib/python3.13/site-packages/pygments/lexers/ecl.py": 12886695201994337568, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/themes.py": 6451091097727599550, - "venv/lib/python3.13/site-packages/anyio/streams/memory.py": 11762722143503428823, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_nlargest.py": 1423106021399469694, - "venv/lib/python3.13/site-packages/numpy/_core/numerictypes.py": 6205675182996213576, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/assumed_shape/foo_free.f90": 10939657740734987454, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_timedelta_range.py": 15081095442418142820, - "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/utils.py": 7707707044867513457, - "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_str_accessor.py": 4066094997616994612, - "venv/lib/python3.13/site-packages/jeepney-0.9.0.dist-info/RECORD": 7810411361439269754, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/abc.py": 6227782083136374888, - "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/websockets_sansio_impl.py": 17221368219485351394, - "frontend/build/_app/immutable/chunks/Bq9hCVSi.js": 1342535258328212659, - "venv/lib/python3.13/site-packages/pip/_internal/index/__init__.py": 14829074315307489628, - "venv/lib/python3.13/site-packages/pydantic/v1/types.py": 10761779263335288559, - "venv/lib/python3.13/site-packages/jeepney/tests/secrets_introspect.xml": 10717038359151125278, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_numba.py": 1668304729617150075, - "venv/lib/python3.13/site-packages/jsonschema/_typing.py": 13152346021901861822, - "venv/lib/python3.13/site-packages/ecdsa/rfc6979.py": 11564966030899162026, - "venv/lib/python3.13/site-packages/numpy/_utils/_inspect.pyi": 17825266810219495672, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_textreader.py": 388955620768371652, - "venv/lib/python3.13/site-packages/pygments/styles/sas.py": 12363791134941577382, - "venv/lib/python3.13/site-packages/pygments/lexers/c_cpp.py": 1211842877043321095, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/plugin/__init__.py": 10470644151952252331, - "backend/src/core/superset_client/__init__.py": 6869599313455380203, - "venv/lib/python3.13/site-packages/authlib/integrations/base_client/errors.py": 6538052228921426956, - "venv/lib/python3.13/site-packages/pygments/lexers/qvt.py": 1895735583818227972, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/_collections.py": 14307204206312829238, - "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/models.py": 15928924478695638423, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_old_base.py": 191359377446257900, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_from_dummies.py": 5670811108950300761, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_coercion.py": 3339075591248270762, - "venv/lib/python3.13/site-packages/click/globals.py": 18353671282454331523, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/vectorized.pyi": 15498895254516573071, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/einsumfunc.py": 9944042006439149561, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/plugin/pytestplugin.py": 1591034895268415944, - "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/util.pyx": 649821942746469002, - "venv/lib/python3.13/site-packages/pygments/filter.py": 16846063190466267618, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/unitofwork.py": 3177255974394221645, - "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/WHEEL": 16097436423493754389, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/__init__.py": 15644105878811738516, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/scalars.py": 3468820466230647963, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/np_datetime.cpython-313-x86_64-linux-gnu.so": 7840846965295537844, - "venv/lib/python3.13/site-packages/pygments/lexers/factor.py": 15788613154609197002, - "frontend/src/lib/components/reports/__tests__/fixtures/reports.fixtures.js": 10647302793388244094, - "backend/tests/core/test_migration_engine.py": 7419155921858935534, - "venv/lib/python3.13/site-packages/PIL/ImagePalette.py": 9227837918026991107, - "backend/src/services/clean_release/repositories/artifact_repository.py": 9040122866024534865, - "venv/lib/python3.13/site-packages/pip/_internal/operations/build/wheel_legacy.py": 12735901522735836481, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_insert.py": 15536994417338770457, - "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_where.py": 14167991754625133668, - "venv/lib/python3.13/site-packages/apscheduler/jobstores/sqlalchemy.py": 811968833735951956, - "venv/lib/python3.13/site-packages/numpy/fft/tests/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/common.py": 2075178842766962782, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_reindex_like.py": 13803156447991282315, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_astype.py": 15384141282611151560, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_wrap.py": 17083394123203662880, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_integrity.py": 12010564145080323987, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_round.py": 14996007456708990295, - "venv/lib/python3.13/site-packages/pandas/io/spss.py": 864838144958947906, - "venv/lib/python3.13/site-packages/pandas/io/parquet.py": 14415622950469421518, - "frontend/src/routes/datasets/review/__tests__/dataset_review_entry.test.js": 7689381541193660594, - "venv/lib/python3.13/site-packages/pandas/tests/computation/test_eval.py": 2921337784087808487, - "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/METADATA": 10220680536734745103, - "venv/lib/python3.13/site-packages/pygments/styles/stata_dark.py": 324072437809944751, - "venv/lib/python3.13/site-packages/pip/_internal/commands/wheel.py": 16397273591245583356, - "venv/lib/python3.13/site-packages/numpy/lib/_datasource.pyi": 5894423389796456573, - "venv/lib/python3.13/site-packages/fastapi/security/base.py": 15674297568104917749, - "venv/lib/python3.13/site-packages/pydantic/main.py": 14086938579850319884, - "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_bcrypt.py": 11146468670439284889, - "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/WHEEL": 8954358347596196608, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/lexers/python.py": 17886036670342116501, - "venv/lib/python3.13/site-packages/pandas/core/indexes/timedeltas.py": 13653393430363556843, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_astype.py": 4854809596041987380, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/clsregistry.py": 1589692649837935355, - "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pygments/lexers/mips.py": 2078929831513352031, - "venv/lib/python3.13/site-packages/pandas/tests/extension/test_interval.py": 14749388246573356959, - "venv/lib/python3.13/site-packages/_pytest/timing.py": 14080119171718125986, - "venv/lib/python3.13/site-packages/pydantic/v1/validators.py": 1060954771151908883, - "venv/lib/python3.13/site-packages/pandas/core/arrays/period.py": 11560984428402318984, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/test_function.py": 644452398244782315, - "frontend/src/services/taskService.js": 11368052191249479533, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/implicit.py": 7379110378465568776, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/pbkdf2.py": 3369246520501764730, - "venv/lib/python3.13/site-packages/numpy/_core/records.pyi": 14194354215405544730, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_compare.py": 3079569478684646491, - "venv/lib/python3.13/site-packages/pygments/modeline.py": 6194365452131561478, - "venv/lib/python3.13/site-packages/click/_termui_impl.py": 3296085065310341855, - "venv/lib/python3.13/site-packages/pip/_internal/vcs/mercurial.py": 335201628064585213, - "venv/lib/python3.13/site-packages/_pytest/_code/__init__.py": 6211607282116942091, - "venv/lib/python3.13/site-packages/pip/_internal/models/format_control.py": 12916176880659590456, - "venv/lib/python3.13/site-packages/tzlocal-5.3.1.dist-info/METADATA": 11439969143853665311, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh26681.f90": 1515497186927052106, - "venv/lib/python3.13/site-packages/pandas/io/formats/__init__.py": 18140261896107421679, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c": 17333399794446198412, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_tools.py": 13994164937603424236, - "backend/src/services/reports/report_service.py": 17586405613867657190, - "backend/src/api/routes/migration.py": 6030566471113208264, - "venv/lib/python3.13/site-packages/pandas/_libs/json.cpython-313-x86_64-linux-gnu.so": 2436285663630821963, - "backend/src/core/migration/__init__.py": 13075189211840127611, - "venv/lib/python3.13/site-packages/numpy/random/bit_generator.pyi": 15790738442952696034, - "venv/lib/python3.13/site-packages/PIL/WalImageFile.py": 12442826195371137238, - "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/_pip_wrapper.py": 2516476609539242190, - "venv/lib/python3.13/site-packages/requests/compat.py": 5836590172733661320, - "venv/lib/python3.13/site-packages/pygments/lexers/tcl.py": 10343667975436015855, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_join.py": 13115782559805895662, - "venv/lib/python3.13/site-packages/pydantic/_internal/_docs_extraction.py": 5210114991139191634, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/f2cmap/isoFortranEnvMap.f90": 15768643271492041853, - "venv/lib/python3.13/site-packages/pandas/tests/extension/base/index.py": 15694995431926521471, - "venv/lib/python3.13/site-packages/pandas/io/_util.py": 13608922148814398500, - "backend/src/core/superset_client/_dashboards_list.py": 16574697057051064609, - "venv/lib/python3.13/site-packages/psycopg2/tz.py": 9966680685796585198, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_map.py": 6556132946198785761, - "venv/lib/python3.13/site-packages/_pytest/python_api.py": 12953851690889336092, - "venv/lib/python3.13/site-packages/secretstorage/util.py": 1004887530903069622, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_duplicated.py": 6659959750254523427, - "venv/lib/python3.13/site-packages/cryptography/hazmat/decrepit/ciphers/algorithms.py": 2375452080667815941, - "venv/lib/python3.13/site-packages/pygments/styles/dracula.py": 12379322008538174078, - "venv/lib/python3.13/site-packages/pygments/lexers/_asy_builtins.py": 1665617945818958781, - "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/extension_types.py": 1856757457657310231, - "venv/lib/python3.13/site-packages/pygments/lexers/ptx.py": 4855144232064607995, - "venv/lib/python3.13/site-packages/cffi/_embedding.h": 9441285871823018603, - "venv/lib/python3.13/site-packages/pandas/_libs/_cyutility.cpython-313-x86_64-linux-gnu.so": 3372660143512868174, - "frontend/src/routes/migration/__tests__/migration_dashboard.ux.test.js": 17118608261683412409, - "venv/lib/python3.13/site-packages/pygments/styles/paraiso_dark.py": 3976779833379189837, - "venv/lib/python3.13/site-packages/itsdangerous/signer.py": 3694661094753475840, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_validate_args_and_kwargs.py": 3381939712123764154, - "backend/src/models/assistant.py": 6168086159312177112, - "frontend/src/lib/components/layout/sidebarNavigation.js": 12067620255981492739, - "venv/lib/python3.13/site-packages/passlib/utils/__init__.py": 11704122205941631503, - "frontend/src/lib/components/translate/__tests__/test_correction_cell.svelte.js": 2314051239468628554, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame_color.py": 3700828402084646308, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_fillna.py": 7244491410004453166, - "venv/lib/python3.13/site-packages/numpy/f2py/f2py2e.pyi": 14181518821845356636, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/base.cpython-313-x86_64-linux-gnu.so": 8335798324308957127, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/parameters.py": 5104015814292812973, - "venv/lib/python3.13/site-packages/numpy/_core/_dtype.pyi": 17662618580381221543, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/algorithms.py": 17106903014205241774, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_is_monotonic.py": 4626065848596214108, - "venv/lib/python3.13/site-packages/yaml/reader.py": 9873075843010693205, - "venv/lib/python3.13/site-packages/pygments/lexers/sgf.py": 6802546617450210439, - "venv/lib/python3.13/site-packages/pandas/_libs/interval.pyi": 15698173755300703836, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/lower_f2py_fortran.f90": 13315882216322269383, - "backend/src/api/routes/clean_release.py": 1984604735131504761, - "venv/lib/python3.13/site-packages/python_multipart/exceptions.py": 5971058243218049183, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/object/test_astype.py": 563689238486630866, - "venv/lib/python3.13/site-packages/sqlalchemy/__init__.py": 9751988289698484530, - "venv/lib/python3.13/site-packages/httpcore/_async/http_proxy.py": 13364803556177997526, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/string/test_astype.py": 10171766562093740708, - "venv/lib/python3.13/site-packages/pydantic/class_validators.py": 4643597082531287188, - "venv/lib/python3.13/site-packages/git/index/typ.py": 11661540784850363024, - "backend/src/scripts/clean_release_cli.py": 14467814161661747234, - "venv/lib/python3.13/site-packages/pandas/tests/apply/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/dotenv/version.py": 13508433229287636267, - "backend/src/services/clean_release/policy_resolution_service.py": 5075709738950902327, - "backend/tests/test_task_manager.py": 1706217361689506763, - "venv/lib/python3.13/site-packages/cffi/_shimmed_dist_utils.py": 4824806157907607487, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust.abi3.so": 2537152913308578487, - "venv/lib/python3.13/site-packages/pandas/core/dtypes/dtypes.py": 9839461501970023861, - "venv/lib/python3.13/site-packages/numpy/core/numeric.py": 17025007229779320230, - "frontend/src/routes/reports/llm/[taskId]/+page.svelte": 14394593511269407852, - "venv/lib/python3.13/site-packages/numpy/_core/_string_helpers.py": 17192211156810267818, - "venv/lib/python3.13/site-packages/numpy/random/tests/test_extending.py": 10202091354750153497, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/base.py": 13269563625127294513, - "venv/lib/python3.13/site-packages/pluggy/_hooks.py": 6941854999025808196, - "venv/lib/python3.13/site-packages/pygments/lexers/robotframework.py": 11507713622179102496, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/keys.pyi": 1846673463183660140, - "venv/lib/python3.13/site-packages/pandas/core/resample.py": 13814298871925341617, - "venv/lib/python3.13/site-packages/pip/_vendor/packaging/requirements.py": 11478648568700804705, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/__init__.pyi": 17469792319379909312, - "venv/lib/python3.13/site-packages/numpy/random/tests/data/sfc64-testset-2.csv": 4052796393463357888, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/conftest.py": 3691712173202219606, - "backend/src/api/routes/translate/_helpers.py": 15633442720544972283, - "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py": 14946223589457772924, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/pkcs12.pyi": 7801211423226951223, - "backend/src/core/auth/config.py": 8065625913451826937, - "venv/lib/python3.13/site-packages/passlib/handlers/bcrypt.py": 8125664010268654055, - "venv/lib/python3.13/site-packages/passlib/crypto/_blowfish/base.py": 15872835330892203433, - "venv/lib/python3.13/site-packages/pandas/io/excel/_util.py": 6664989864423807444, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/exceptions.py": 7518613450390473990, - "venv/lib/python3.13/site-packages/pip/_internal/req/req_file.py": 5180401483285462901, - "venv/lib/python3.13/site-packages/anyio/to_interpreter.py": 8369454842687342401, - "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/azure.py": 13529763490186254462, - "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_insert.py": 11635164392966270621, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_formats.py": 9738552308554950419, - "venv/lib/python3.13/site-packages/pandas/tests/extension/base/constructors.py": 7587476800569414769, - "venv/lib/python3.13/site-packages/rapidfuzz/__pyinstaller/test_rapidfuzz_packaging.py": 5189055608193366093, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_constructors.py": 6440526981746306640, - "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/licenses/LICENSE": 16499431172938528491, - "venv/lib/python3.13/site-packages/sqlalchemy/engine/_py_row.py": 918740441973901148, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_unique.py": 16285418015531891530, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/__multiarray_api.c": 9134176670140958459, - "venv/lib/python3.13/site-packages/sqlalchemy/event/attr.py": 5971663429221923939, - "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_sorting.py": 10523740688498427929, - "backend/src/models/dataset_review_pkg/_mapping_models.py": 6232602161916984422, - "dist/docker/backend.v1.0.0-rc2-docker.tar": 9693793465773386616, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_to_latex.py": 2628895559914914693, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_algos.py": 5356470832688354593, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_integer.py": 16102640589300356639, - "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/criterion.py": 2042509334195547606, - "venv/lib/python3.13/site-packages/smmap/util.py": 13276170835044840023, - "venv/lib/python3.13/site-packages/authlib/oidc/core/userinfo.py": 17201158389976619872, - "venv/lib/python3.13/site-packages/pandas/core/reshape/pivot.py": 4736553530021653868, - "backend/src/core/superset_client/_datasets.py": 4813403545392307482, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/asyncio.py": 2517623574187179319, - "venv/lib/python3.13/site-packages/pandas/tests/extension/decimal/test_decimal.py": 17811784255174057561, - "venv/lib/python3.13/site-packages/pandas/io/formats/printing.py": 3054136648863371285, - "venv/lib/python3.13/site-packages/numpy/_typing/_add_docstring.py": 14657346268890680694, - "venv/lib/python3.13/site-packages/sqlalchemy/future/__init__.py": 17688444679736059779, - "venv/lib/python3.13/site-packages/pygments/lexers/boa.py": 14409319610243925864, - "venv/lib/python3.13/site-packages/pygments/lexers/lilypond.py": 1088755646568511197, - "venv/lib/python3.13/site-packages/numpy/_array_api_info.pyi": 13283968924732680159, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_dtypes.py": 13065857166166716628, - "venv/lib/python3.13/site-packages/dateutil/tz/win.py": 8427821225251397364, - "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/format-annotation": 4826455560768665215, - "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/licenses/AUTHORS": 3558407083075395848, - "venv/lib/python3.13/site-packages/yaml/tokens.py": 2279161238859232338, - "venv/lib/python3.13/site-packages/pandas/tests/reductions/test_stat_reductions.py": 11569525436540769152, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_delete.py": 3485374671877063217, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_complex.py": 12963449957363121481, - "venv/lib/python3.13/site-packages/sqlalchemy/engine/__init__.py": 6327819603201859020, - "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/oauth1_client.py": 3129955464287331242, - "venv/lib/python3.13/site-packages/PIL/QoiImagePlugin.py": 17663704273100331654, - "venv/lib/python3.13/site-packages/httpcore/_sync/http_proxy.py": 14037211594707072958, - "venv/lib/python3.13/site-packages/uvicorn/_types.py": 3339389597716220585, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_to_pydatetime.py": 1129954411080617001, - "venv/lib/python3.13/site-packages/jsonschema/benchmarks/json_schema_test_suite.py": 6152158310190822762, - "venv/lib/python3.13/site-packages/keyring/testing/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/cryptography/utils.py": 18088508841978595788, - "venv/lib/python3.13/site-packages/pandas/core/common.py": 14578909424716153057, - "backend/src/services/clean_release/approval_service.py": 12912719831239691496, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_sample.py": 4641567828238191927, - "venv/lib/python3.13/site-packages/pydantic/v1/_hypothesis_plugin.py": 6383299780629629080, - "venv/lib/python3.13/site-packages/pydantic/annotated_handlers.py": 10186120300163345360, - "venv/lib/python3.13/site-packages/numpy/matlib.py": 112839038090033740, - "venv/lib/python3.13/site-packages/pandas/core/arrays/numeric.py": 17834058423729918687, - "venv/lib/python3.13/site-packages/requests/cookies.py": 4997226307650350876, - "venv/lib/python3.13/site-packages/numpy/_configtool.pyi": 9670892208858157218, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh18335.f90": 1126438609189294255, - "venv/lib/python3.13/site-packages/authlib/jose/jwk.py": 13560749074922587626, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8414/well_known.py": 7183795183137931709, - "venv/lib/python3.13/site-packages/gitdb/db/__init__.py": 2615504918450276693, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/chararray.pyi": 9683985931409244216, - "venv/lib/python3.13/site-packages/numpy/f2py/_src_pyf.py": 546976622482819095, - "venv/lib/python3.13/site-packages/numpy/_core/shape_base.pyi": 10225243791643474943, - "venv/lib/python3.13/site-packages/pandas/tests/generic/test_generic.py": 1297407268239966429, - "venv/lib/python3.13/site-packages/fastapi/middleware/trustedhost.py": 4285622102799027823, - "venv/lib/python3.13/site-packages/jose/jwe.py": 3325660353225624025, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_index_tricks.py": 4676293127859087991, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_interpolate.py": 6154072863387383113, - "venv/lib/python3.13/site-packages/pandas/tests/strings/test_split_partition.py": 2715491071550545667, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_array.py": 11271807719833350332, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/coercions.py": 5112358449376598662, - "venv/lib/python3.13/site-packages/urllib3/util/ssl_.py": 11720964010284185952, - "venv/lib/python3.13/site-packages/pygments/lexers/wgsl.py": 9718384325049172855, - "frontend/src/lib/stores/activity.js": 14023344642294459631, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/orderinglist.py": 10162099108656794338, - "venv/lib/python3.13/site-packages/numpy/ma/tests/test_regression.py": 12593643817685777170, - "venv/lib/python3.13/site-packages/pandas/core/ops/common.py": 17314999825118928100, - "frontend/src/lib/components/translate/TranslationRunResult.svelte": 17300907945810807567, - "venv/lib/python3.13/site-packages/websockets/sync/server.py": 7966978001578584901, - "frontend/src/routes/storage/repos/+page.svelte": 3849368960648953479, - "venv/lib/python3.13/site-packages/pandas/tests/frame/common.py": 7426635866622531875, - "backend/src/core/migration/archive_parser.py": 8828677257278703059, - "venv/lib/python3.13/site-packages/httpcore/_synchronization.py": 10997080307461682786, - "backend/src/api/routes/__tests__/test_migration_routes.py": 4357515184436771537, - "backend/alembic/versions/c4a3a2f74bfe_add_missing_columns_needs_review_.py": 4320606555167902916, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/lexers/_mapping.py": 17519715342700184302, - "venv/lib/python3.13/site-packages/anyio/_backends/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_protocols.py": 5019018645804313814, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_internals.py": 10472508540875131797, - "venv/lib/python3.13/site-packages/pydantic/color.py": 1007422551673129827, - "venv/lib/python3.13/site-packages/passlib/ifc.py": 14479133654556657428, - "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_timedelta64.py": 16821719402662529276, - "venv/lib/python3.13/site-packages/pip/_internal/cli/progress_bars.py": 7584699216537478969, - "venv/lib/python3.13/site-packages/apscheduler/jobstores/base.py": 11386927749822539057, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_extint128.py": 11074657869101074458, - "venv/lib/python3.13/site-packages/pandas/core/sparse/api.py": 9094651265692218821, - "venv/lib/python3.13/site-packages/more_itertools/more.pyi": 4844596605492825806, - "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/METADATA": 10810011740984652381, - "venv/lib/python3.13/site-packages/numpy/core/overrides.pyi": 1968648615494204783, - "venv/lib/python3.13/site-packages/numpy/linalg/_linalg.pyi": 9629457630163613604, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/lib_function_base.pyi": 2792940598392356268, - "venv/lib/python3.13/site-packages/pandas/core/groupby/indexing.py": 18009437216172136227, - "venv/lib/python3.13/site-packages/pandas/tests/extension/test_period.py": 6047041810867211174, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_dict_of_blocks.py": 11646835537993064324, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_autocorr.py": 1092316868398391792, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_arithmetic.py": 15071337112968886738, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_replace.py": 18039668944453454689, - "venv/lib/python3.13/site-packages/pandas/io/excel/_xlrd.py": 14430937200583666658, - "venv/lib/python3.13/site-packages/pillow.libs/libwebpmux-7f11e5ce.so.3.1.2": 13105940093474848953, - "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_musllinux.py": 2423350951094915747, - "venv/lib/python3.13/site-packages/pandas/io/excel/_xlsxwriter.py": 16873939324418752965, - "venv/lib/python3.13/site-packages/PIL/ImageGrab.py": 11114379915762058868, - "venv/lib/python3.13/site-packages/PIL/ImageEnhance.py": 3218405223202808764, - "venv/lib/python3.13/site-packages/httpx/_transports/base.py": 6498990531443644896, - "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py2-np0-objarr.npy": 1615546603475261360, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_monotonic.py": 11817523305776951162, - "backend/src/core/auth/jwt.py": 2300190538212143465, - "venv/lib/python3.13/site-packages/fastapi/cli.py": 13972351579061154035, - "venv/lib/python3.13/site-packages/python_multipart/__init__.py": 10290895261363712562, - "venv/lib/python3.13/site-packages/pyasn1/codec/ber/encoder.py": 8912119133548489544, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/generate_umath_validation_data.cpp": 10880681943327843928, - "venv/lib/python3.13/site-packages/sqlalchemy/engine/interfaces.py": 4890958419958257958, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/Prefix.pyi": 2700568594438441246, - "backend/src/services/clean_release/stages/no_external_endpoints.py": 11041035366569218866, - "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/controller.py": 5450931608244830335, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/retry.py": 17371295199208325375, - "venv/lib/python3.13/site-packages/cryptography/hazmat/decrepit/__init__.py": 63497920264089252, - "backend/src/services/git/__init__.py": 14011752637167919253, - "venv/lib/python3.13/site-packages/numpy/tests/test_matlib.py": 14395481530627870882, - "venv/lib/python3.13/site-packages/PIL/BufrStubImagePlugin.py": 5520941821175895889, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/filesize.py": 13234856188049714485, - "venv/lib/python3.13/site-packages/pandas/core/indexers/__init__.py": 1756397319068017890, - "venv/lib/python3.13/site-packages/pandas/core/indexes/category.py": 18192569199634406001, - "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_delitem.py": 14336697139511118920, - "frontend/src/services/storageService.js": 14408290095426695791, - "venv/lib/python3.13/site-packages/pandas/core/accessor.py": 1188716996113179524, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_indexing.py": 6039808271042864401, - "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/WHEEL": 3749476255729626245, - "venv/lib/python3.13/site-packages/pandas/tests/extension/base/interface.py": 3134071530627935964, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/syntax.py": 18070449217682341495, - "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/resultproxy.pyx": 5760108632332714287, - "venv/lib/python3.13/site-packages/pycparser/yacctab.py": 18018314512916353707, - "venv/lib/python3.13/site-packages/pip/__init__.py": 9449893869469432503, - "venv/lib/python3.13/site-packages/numpy/polynomial/_polybase.pyi": 15864712173815045309, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_shape_base.py": 4117141349022217163, - "venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/RECORD": 12015288851076448205, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/automap.py": 4672057253309608464, - "venv/lib/python3.13/site-packages/pygments/styles/__init__.py": 18383248976818885498, - "venv/lib/python3.13/site-packages/pandas/core/indexes/datetimelike.py": 4356700619632833878, - "venv/lib/python3.13/site-packages/PIL/_typing.py": 17407980360703360848, - "backend/src/core/auth/__tests__/test_auth.py": 14999763239648705195, - "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/__init__.py": 71159121705871510, - "venv/lib/python3.13/site-packages/authlib/integrations/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/parsing.pyi": 11967691665766452312, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_unsupported.py": 9115440166074553860, - "venv/lib/python3.13/site-packages/pygments/lexers/theorem.py": 15666523910367201285, - "frontend/src/lib/components/reports/__tests__/report_type_profiles.test.js": 498330292141991614, - "venv/lib/python3.13/site-packages/pip/_vendor/distlib/metadata.py": 1362166613223529108, - "venv/lib/python3.13/site-packages/_pytest/outcomes.py": 12782895027812738142, - "venv/lib/python3.13/site-packages/numpy/random/_common.pxd": 3402284125943848851, - "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pandas/tests/apply/test_series_apply_relabeling.py": 3930092097678339743, - "venv/lib/python3.13/site-packages/requests/certs.py": 16052880877156864882, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/padding.py": 7470483648602195268, - "venv/lib/python3.13/site-packages/starlette/middleware/base.py": 16850428285382256618, - "venv/lib/python3.13/site-packages/ecdsa/test_pyecdsa.py": 14542286382742044648, - "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/oauth1_session.py": 1911069558956893789, - "venv/lib/python3.13/site-packages/uvicorn/protocols/http/auto.py": 15947958974558543657, - "venv/lib/python3.13/site-packages/pip/_vendor/idna/intranges.py": 12536174834761591006, - "venv/lib/python3.13/site-packages/smmap/test/lib.py": 2924931247676024085, - "venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/WHEEL": 7127684561765977531, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_formats.py": 12299393760307251036, - "frontend/src/lib/stores/__tests__/test_taskDrawer.js": 13582869875796637016, - "venv/lib/python3.13/site-packages/anyio/_backends/_asyncio.py": 10265081145401348863, - "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/accessors.py": 12743680296510533030, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_datetime.py": 13781712980921881470, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_values.py": 8372572954663628844, - "venv/lib/python3.13/site-packages/numpy/_core/numeric.pyi": 17785360553418386488, - "venv/lib/python3.13/site-packages/pandas/io/clipboard/__init__.py": 3656451154829206939, - "frontend/build/_app/immutable/nodes/23.DidEHbej.js": 11332551805513625112, - "venv/lib/python3.13/site-packages/pillow.libs/libbrotlidec-b57ddf63.so.1.2.0": 10032590058372320813, - "venv/lib/python3.13/site-packages/pandas/tests/series/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/ma/core.pyi": 4829891173366130328, - "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/licenses/numpy/_core/src/umath/svml/LICENSE": 9584102918819171104, - "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_matrix_linalg.py": 2858987911347541177, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_python_parser_only.py": 12231449578582108346, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/fromnumeric.pyi": 6708743411405679061, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_indexing.py": 16264430536704066847, - "venv/lib/python3.13/site-packages/pandas/tests/test_register_accessor.py": 16661086720613729974, - "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/frequencies/__init__.py": 15130871412783076140, - "backend/src/core/scheduler.py.bak": 15045927989195339728, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_interval.py": 8549680643865283913, - "backend/src/models/dataset_review_pkg/_session_models.py": 14346374229033337012, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/authorization_server.py": 13696038495666024258, - "venv/lib/python3.13/site-packages/greenlet/TPythonState.cpp": 12828594265749606443, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/containers.py": 5969831151685016772, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_reindex.py": 8772423071604000084, - "venv/lib/python3.13/site-packages/gitdb/typ.py": 16374739906244805047, - "venv/lib/python3.13/site-packages/psycopg2_binary.libs/liblber-1c9097e2.so.2.0.200": 2651879839738900594, - "venv/lib/python3.13/site-packages/attrs/exceptions.py": 2871247302586505373, - "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/WHEEL": 17410883677306885019, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_indexing.py": 7181087459615188551, - "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/licenses/LICENSE": 4123064337800029995, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/test_indexing.py": 9862204223281834360, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_tz_convert.py": 17957207974799052653, - "backend/src/services/notifications/__tests__/test_notification_service.py": 2377464079178202565, - "venv/lib/python3.13/site-packages/pip/_vendor/requests/compat.py": 5871636909854554063, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_nlargest.py": 14518132768753249360, - "venv/lib/python3.13/site-packages/passlib/tests/sample1.cfg": 9597283806285213340, - "venv/lib/python3.13/site-packages/pandas/core/dtypes/base.py": 3628510830969664111, - "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/stride_tricks.pyi": 5844806555773292985, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/scoping.py": 17216492046645992674, - "venv/lib/python3.13/site-packages/git/repo/fun.py": 9019364012746153312, - "venv/lib/python3.13/site-packages/pygments/formatters/svg.py": 11686316844190214147, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pygments/lexers/asn1.py": 15030988816882821134, - "venv/lib/python3.13/site-packages/pydantic/networks.py": 15767095796055034509, - "venv/lib/python3.13/site-packages/numpy/random/__init__.pyi": 13833571330152615376, - "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/errors.py": 16711622442922413520, - "venv/lib/python3.13/site-packages/_pytest/mark/structures.py": 12237146603608917650, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_concat.py": 16549010224568175202, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_fillna.py": 4610666845291315333, - "venv/lib/python3.13/site-packages/pandas/core/tools/datetimes.py": 13313374952742129866, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_ops.py": 3875181889032080505, - "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libpq-9b38f5e3.so.5.17": 9680474575710585826, - "venv/lib/python3.13/site-packages/pygments/lexers/praat.py": 54226477748516386, - "backend/src/api/routes/git/_gitea_routes.py": 14644218433873522624, - "venv/bin/pyrsa-keygen": 8222542582170363672, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_modules.py": 16835987029123241300, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_bar.py": 7791068963246005463, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_indexing.py": 5063545640498065297, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_amd64_unix.h": 16679226724722970205, - "venv/lib/python3.13/site-packages/pandas/core/array_algos/masked_reductions.py": 633644255158859565, - "frontend/src/components/tasks/LogFilterBar.svelte": 11464828454938370522, - "venv/lib/python3.13/site-packages/pandas/tests/util/conftest.py": 11143177766735481660, - "venv/lib/python3.13/site-packages/numpy/core/overrides.py": 11228841530565061867, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/datetimes/__init__.py": 15130871412783076140, - "venv/bin/pyrsa-priv2pub": 16766314338551408621, - "venv/lib/python3.13/site-packages/pandas/io/orc.py": 12754290195886557668, - "backend/src/core/superset_client/_base.py": 17832258524611728315, - "backend/src/services/clean_release/publication_service.py": 5215271639026811180, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/memmap.pyi": 15629663272474054909, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_upcast.py": 6496794053681247105, - "backend/src/services/clean_release/compliance_orchestrator.py": 10585043190405940115, - "backend/src/schemas/profile.py": 7072251247808762582, - "venv/lib/python3.13/site-packages/jeepney/tests/test_auth.py": 15125055415702968414, - "venv/lib/python3.13/site-packages/passlib/handlers/django.py": 66638338316838351, - "venv/lib/python3.13/site-packages/pandas/core/computation/eval.py": 3176226283265954028, - "venv/lib/python3.13/site-packages/git/objects/blob.py": 8972374723153211283, - "backend/tests/test_task_persistence.py": 1764267414712263025, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/token.py": 4747545058753492487, - "venv/lib/python3.13/site-packages/pandas/tests/config/test_config.py": 4630144191929135452, - "backend/src/core/utils/superset_context_extractor/_pii.py": 14826864290194304173, - "venv/lib/python3.13/site-packages/passlib/utils/compat/__init__.py": 17369882236606423129, - "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/RECORD": 6349071557579241461, - "venv/lib/python3.13/site-packages/anyio/_core/_asyncio_selector_thread.py": 1760597191437520000, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_excel.py": 5467043641314706635, - "venv/lib/python3.13/site-packages/pygments/lexers/console.py": 18266795648198475028, - "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_get.py": 10255752806860493777, - "backend/src/api/routes/assistant/_admin_routes.py": 3380446401429936332, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/__init__.py": 13331622784664204066, - "venv/lib/python3.13/site-packages/PIL/ImageStat.py": 18442709639217312689, - "venv/lib/python3.13/site-packages/pygments/lexers/_lua_builtins.py": 12653747099659257203, - "venv/lib/python3.13/site-packages/referencing/tests/test_exceptions.py": 10846225989746274213, - "venv/lib/python3.13/site-packages/pandas/tests/base/test_constructors.py": 2439700578107653984, - "frontend/src/lib/Counter.svelte": 4002153662176313030, - "venv/lib/python3.13/site-packages/anyio/abc/_eventloop.py": 2023190981288767991, - "venv/lib/python3.13/site-packages/attr/__init__.py": 14436902698244718082, - "venv/lib/python3.13/site-packages/httpx/_content.py": 1301854837767395687, - "venv/lib/python3.13/site-packages/pip/_internal/models/target_python.py": 422323125651848065, - "venv/lib/python3.13/site-packages/pandas/tests/resample/test_timedelta.py": 17052461094717926538, - "venv/lib/python3.13/site-packages/pygments/lexers/rdf.py": 14488319292387226505, - "backend/src/plugins/translate/preview.py": 14641288388025627288, - "venv/lib/python3.13/site-packages/ecdsa/errors.py": 11755424742691057760, - "venv/lib/python3.13/site-packages/pyasn1/codec/cer/__init__.py": 15728752901274520502, - "venv/lib/python3.13/site-packages/pip/_internal/commands/search.py": 8292218231992728142, - "venv/lib/python3.13/site-packages/keyring/backends/null.py": 12740996416911604870, - "venv/lib/python3.13/site-packages/passlib/handlers/windows.py": 8969739861295277439, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_rank.py": 14115215895836854973, - "venv/lib/python3.13/site-packages/numpy/linalg/_umath_linalg.pyi": 7674087576653964854, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/apply.py": 3906017176873949738, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_arraypad.py": 4907193085512342162, - "venv/lib/python3.13/site-packages/numpy/lib/_arraypad_impl.pyi": 2186875333484796630, - "venv/lib/python3.13/site-packages/pygments/styles/rrt.py": 9490973359165080360, - "venv/lib/python3.13/site-packages/pygments/lexers/webmisc.py": 9530962803076253849, - "venv/lib/python3.13/site-packages/jeepney/io/tests/test_blocking.py": 6312017389529916004, - "venv/lib/python3.13/site-packages/certifi/__init__.py": 9045580998764948967, - "venv/lib/python3.13/site-packages/pandas/tests/io/test_parquet.py": 11050150015772440923, - "venv/lib/python3.13/site-packages/pydantic/errors.py": 3506829204186508192, - "venv/lib/python3.13/site-packages/numpy/polynomial/laguerre.py": 151202984060101867, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_produces_warning.py": 750781117570375777, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_store.py": 1500300322083708794, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_compat.py": 6032546839876195115, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/_selectable_constructors.py": 84919308502240880, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/compiler.py": 13924519162400330589, - "venv/lib/python3.13/site-packages/pygments/styles/nord.py": 8469538903422182155, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_diff.py": 2216748778018882333, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_asfreq.py": 2701081989348180239, - "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_set_value.py": 4166411740676564820, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7591/endpoint.py": 13389763148720370546, - "venv/lib/python3.13/site-packages/sqlalchemy/engine/_py_processors.py": 16557117595879208702, - "venv/lib/python3.13/site-packages/pygments/styles/stata_light.py": 16319330015324455277, - "venv/lib/python3.13/site-packages/pygments/lexers/tact.py": 1164971357219795420, - "venv/lib/python3.13/site-packages/ecdsa/curves.py": 812969717084691115, - "frontend/src/lib/stores/__tests__/mocks/environment.js": 16653269108049932073, - "venv/lib/python3.13/site-packages/websockets/asyncio/__init__.py": 15130871412783076140, - "frontend/src/components/tasks/TaskLogPanel.svelte": 7807716346006847037, - "backend/src/api/routes/tasks.py": 4058255810929412793, - "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/METADATA": 16498441272591167134, - "venv/lib/python3.13/site-packages/pandas/compat/numpy/__init__.py": 1037113402100731082, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/state.py": 10500170103357297551, - "venv/lib/python3.13/site-packages/pandas/core/arrays/masked.py": 13977195666947626206, - "venv/lib/python3.13/site-packages/_pytest/_io/pprint.py": 11202117031437223527, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_converter.py": 7709581879446228856, - "backend/src/services/clean_release/repositories/compliance_repository.py": 7402628017251283691, - "venv/lib/python3.13/site-packages/cryptography/hazmat/backends/openssl/backend.py": 9072112660082423691, - "venv/lib/python3.13/site-packages/numpy.libs/libscipy_openblas64_-096271d3.so": 14338208504131470036, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/rec.pyi": 14615751247243515028, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_put.py": 8547660958963625817, - "venv/lib/python3.13/site-packages/urllib3/http2/probe.py": 4069929463671970243, - "backend/src/schemas/__tests__/test_settings_and_health_schemas.py": 13526616847756581689, - "venv/lib/python3.13/site-packages/PIL/CurImagePlugin.py": 17697303205012181529, - "venv/lib/python3.13/site-packages/urllib3/util/timeout.py": 17922362393077965047, - "backend/src/services/reports/__tests__/test_report_service.py": 6045116534626984913, - "venv/lib/python3.13/site-packages/pandas/tests/test_errors.py": 10116716310156374885, - "venv/lib/python3.13/site-packages/numpy/random/_pickle.py": 7774620933480975313, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_inf.py": 8659210689723088321, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/psycopg.py": 8023549900603235601, - "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/licenses/LICENSE": 6965457853328313914, - "venv/lib/python3.13/site-packages/pandas/tests/series/test_npfuncs.py": 13987318550267921389, - "venv/lib/python3.13/site-packages/pandas/_libs/window/indexers.cpython-313-x86_64-linux-gnu.so": 9380059465932560412, - "venv/lib/python3.13/site-packages/charset_normalizer/__main__.py": 8887772289570078278, - "venv/lib/python3.13/site-packages/charset_normalizer/md.py": 2029760700380476138, - "venv/lib/python3.13/site-packages/tzlocal/__init__.py": 11017072814026497364, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/arrayprint.py": 5912583751693302370, - "venv/lib/python3.13/site-packages/uvicorn/_subprocess.py": 13965754246493254447, - "frontend/src/app.html": 10207534912546549080, - "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/pydantic_settings/sources/utils.py": 8633356372647820801, - "venv/lib/python3.13/site-packages/pydantic/v1/config.py": 12050640083719340958, - "frontend/src/routes/storage/+page.svelte": 5003283673039328108, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_converters.py": 8869440774594127419, - "venv/lib/python3.13/site-packages/pandas/core/_numba/extensions.py": 4132402557064663751, - "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/pydantic/experimental/__init__.py": 492399139963056461, - "venv/lib/python3.13/site-packages/pip/_internal/commands/completion.py": 4435231315212798769, - "venv/lib/python3.13/site-packages/pip/_internal/configuration.py": 2563100675379605810, - "venv/lib/python3.13/site-packages/keyring/backends/macOS/__init__.py": 1010937986753403630, - "venv/lib/python3.13/site-packages/httpx/_client.py": 1063593889704982038, - "venv/lib/python3.13/site-packages/numpy/_core/strings.py": 3623885046208831106, - "frontend/build/_app/immutable/chunks/Bq_f12oM.js": 16951726516394160940, - "venv/lib/python3.13/site-packages/jeepney/io/common.py": 15160647397460834508, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/conftest.py": 4124267277224879990, - "venv/lib/python3.13/site-packages/pandas/core/arrays/_mixins.py": 14293848457775268010, - "venv/lib/python3.13/site-packages/PIL/ImageFile.py": 15765130658900167517, - "venv/lib/python3.13/site-packages/authlib/jose/errors.py": 15231759002942436632, - "venv/lib/python3.13/site-packages/numpy/random/bit_generator.cpython-313-x86_64-linux-gnu.so": 2574035311375507054, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_conversion.py": 9159276697339089788, - "venv/lib/python3.13/site-packages/httpcore/_sync/connection.py": 1539337414493486168, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/bitwise_ops.py": 14350609278188982939, - "venv/bin/pip3.13": 13861749540792881808, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc64_linux.h": 4071314837793906998, - "venv/lib/python3.13/site-packages/numpy/testing/_private/extbuild.py": 4984721349618127021, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/numerictypes.py": 5719374287454872555, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_asof.py": 8656532774394927388, - "venv/lib/python3.13/site-packages/_pytest/nodes.py": 515939386237558331, - "venv/lib/python3.13/site-packages/pip/_internal/req/__init__.py": 12266077985828139928, - "backend/logs/app.log.5": 4675888931719915527, - "venv/lib/python3.13/site-packages/pip/_internal/models/installation_report.py": 14534544543677907640, - "venv/lib/python3.13/site-packages/pandas/tests/strings/test_case_justify.py": 8204537837649550062, - "frontend/src/components/tools/ConnectionForm.svelte": 4060811448046342875, - "backend/ss_tools_backend.egg-info/PKG-INFO": 15134841326777953914, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_timezones.py": 15157687716502574038, - "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_openssl.py": 10446441599800965961, - "venv/lib/python3.13/site-packages/pip/_vendor/idna/idnadata.py": 1169745920682458213, - "venv/lib/python3.13/site-packages/numpy/random/_common.cpython-313-x86_64-linux-gnu.so": 12834724130890991478, - "venv/lib/python3.13/site-packages/pip/_internal/network/download.py": 5256731341219268693, - "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/WHEEL": 14929202952940710322, - "venv/lib/python3.13/site-packages/authlib/oauth2/base.py": 12948318231066662045, - "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/authlib/oidc/discovery/models.py": 6924198551176217533, - "venv/lib/python3.13/site-packages/PIL/Jpeg2KImagePlugin.py": 16905402423248975204, - "venv/lib/python3.13/site-packages/pandas/_libs/hashtable.pyi": 15034917167424979097, - "venv/lib/python3.13/site-packages/pip/_internal/operations/prepare.py": 13514839972066861359, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_astype.py": 15768655715952923925, - "venv/lib/python3.13/site-packages/pydantic/dataclasses.py": 12384956801113860889, - "venv/lib/python3.13/site-packages/pandas/io/clipboards.py": 5183212433608887727, - "venv/lib/python3.13/site-packages/yaml/composer.py": 13619070314468518566, - "venv/lib/python3.13/site-packages/pygments/lexers/graphics.py": 13783143864729682444, - "backend/src/api/routes/assistant/_dispatch.py": 3811422882986895565, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/Levenshtein.py": 15426828792217499138, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/simple.py": 11050636051019777317, - "venv/lib/python3.13/site-packages/pandas/_libs/properties.cpython-313-x86_64-linux-gnu.so": 7092136701092358552, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ufunclike.pyi": 14623308681600207918, - "frontend/src/routes/profile/__tests__/fixtures/profile.fixtures.js": 2726190101012864209, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/numpy_/test_numpy.py": 9825804096508014886, - "venv/lib/python3.13/site-packages/_pytest/__init__.py": 3769333500910148571, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/incfile.f90": 4348588746493647387, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/token_endpoint.py": 6118770923176099889, - "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/base_server.py": 9643197259080504542, - "venv/lib/python3.13/site-packages/secretstorage/exceptions.py": 16701299261122689924, - "venv/lib/python3.13/site-packages/pip/_vendor/idna/package_data.py": 3078502124870585867, - "venv/lib/python3.13/site-packages/urllib3/util/url.py": 15992369651965016538, - "frontend/src/lib/stores/__tests__/mocks/state.js": 3616783395254238777, - "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/INSTALLER": 17282701611721059870, - "backend/src/dependencies.py": 9481683691730170837, - "frontend/src/lib/stores/datasetReviewSession.js": 3915919349382526215, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/privatemod.f90": 8999550841368314739, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/abstract_interface/gh18403_mod.f90": 6219951399575860362, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_reorder_levels.py": 10996225584998355824, - "backend/alembic/versions/543d43d752b8_migrate_old_dictionary_entries_and_.py": 10988663686444687907, - "venv/lib/python3.13/site-packages/numpy/lib/_utils_impl.py": 13012775703413938576, - "venv/lib/python3.13/site-packages/pandas/_libs/lib.pyi": 3049004444338566197, - "venv/lib/python3.13/site-packages/pandas/io/excel/_calamine.py": 13354427767660487637, - "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/pydantic_settings/sources/types.py": 13384984564922916167, - "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libkeyutils-dfe70bd6.so.1.5": 9414227432578104677, - "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/format": 12697928260201325593, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/DamerauLevenshtein.py": 17993169044119596860, - "venv/lib/python3.13/site-packages/numpy/f2py/diagnose.pyi": 8607205990821121708, - "venv/lib/python3.13/site-packages/pydantic/_internal/_typing_extra.py": 14843908493613991959, - "venv/lib/python3.13/site-packages/numpy/testing/print_coercion_tables.py": 11758491058846790938, - "venv/lib/python3.13/site-packages/pip/_internal/metadata/importlib/_compat.py": 4677414058216516380, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalarprint.py": 9482100952562512933, - "venv/lib/python3.13/site-packages/pandas/tests/frame/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/extension/base/casting.py": 12226803454582253097, - "venv/lib/python3.13/site-packages/PIL/_imagingtk.pyi": 18222325750818585549, - "venv/lib/python3.13/site-packages/pygments/lexers/procfile.py": 3860651022061090738, - "backend/src/api/routes/git_schemas.py": 9243114525622127446, - "venv/lib/python3.13/site-packages/pandas/core/methods/describe.py": 17006836623161521092, - "venv/lib/python3.13/site-packages/numpy/random/_bounded_integers.pyi": 14150710436003340771, - "backend/src/services/git/_gitea.py": 3585029718367932699, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_constructors.py": 9767900500541600486, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_arrayprint.py": 13335063050941743734, - "venv/lib/python3.13/site-packages/pygments/styles/friendly.py": 13799024964803741891, - "backend/src/services/git/_sync.py": 16596597562042405179, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_groupby.py": 2738671407653333726, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_cython.py": 14695721638531081573, - "frontend/src/lib/api/translate.js": 18119277537390809809, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/dtype.py": 9342837412280377086, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/wrappers.py": 315409799569602977, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalarmath.py": 9762951701352556447, - "venv/lib/python3.13/site-packages/rsa/py.typed": 11041940105507257053, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/progress_bar.py": 15595912766961891283, - "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/toml.py": 2225382735669153136, - "backend/src/services/clean_release/__tests__/test_stages.py": 15353751625742444422, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_validate_args.py": 5821040955806257450, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_sort_index.py": 13517883160584591966, - "venv/lib/python3.13/site-packages/pip/_internal/cli/index_command.py": 15798187258841839292, - "venv/lib/python3.13/site-packages/pandas/_libs/algos.pyi": 22405377601029952, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_dtypes.py": 481191723198819568, - "venv/lib/python3.13/site-packages/numpy/core/function_base.py": 12696640832638144604, - "venv/lib/python3.13/site-packages/numpy/_core/_multiarray_umath.cpython-313-x86_64-linux-gnu.so": 2888939866336522308, - "venv/lib/python3.13/site-packages/numpy/random/_bounded_integers.cpython-313-x86_64-linux-gnu.so": 16604252871044637047, - "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/RECORD": 9461427699726982537, - "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/METADATA": 4975169119201255384, - "venv/lib/python3.13/site-packages/pygments/lexers/gcodelexer.py": 13712494327007684318, - "venv/lib/python3.13/site-packages/authlib/integrations/base_client/sync_app.py": 14788764260762890368, - "venv/lib/python3.13/site-packages/authlib/deprecate.py": 3563885283090710443, - "venv/lib/python3.13/site-packages/_pytest/config/exceptions.py": 3199245296954654462, - "venv/lib/python3.13/site-packages/numpy/lib/_user_array_impl.py": 13115032674230220791, - "venv/lib/python3.13/site-packages/pandas/core/arrays/datetimelike.py": 394614958716301173, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_value_attrspec.py": 7741590618654448240, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_cumulative.py": 11752712818547022872, - "venv/lib/python3.13/site-packages/pygments/lexers/jslt.py": 11805394130669644345, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_duplicated.py": 14676058112867601208, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_logical/foo77.f": 16250175448122328648, - "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/RECORD": 2963644632913976754, - "venv/lib/python3.13/site-packages/pygments/lexers/basic.py": 12723021007042054402, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_m68k_gcc.h": 6580173800099450404, - "venv/lib/python3.13/site-packages/pygments/lexers/parsers.py": 12372594608244797844, - "venv/lib/python3.13/site-packages/pandas/tests/apply/test_frame_apply_relabeling.py": 5600949862632014700, - "venv/bin/f2py": 11006035631504708368, - "backend/src/services/clean_release/policy_engine.py": 3180817867716931725, - "venv/lib/python3.13/site-packages/greenlet/tests/_test_extension.cpython-313-x86_64-linux-gnu.so": 1211491156495529145, - "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/__init__.py": 10920760520224795596, - "venv/lib/python3.13/site-packages/smmap/test/test_mman.py": 8977119225749253844, - "venv/lib/python3.13/site-packages/keyring/backends/chainer.py": 12526770797516553385, - "frontend/build/_app/immutable/chunks/EsxH6zEp.js": 876411456806196282, - "venv/lib/python3.13/site-packages/pygments/lexers/scripting.py": 4167168074165473790, - "venv/lib/python3.13/site-packages/_pytest/assertion/rewrite.py": 2425990712758915831, - "venv/lib/python3.13/site-packages/packaging/_parser.py": 13394093358675095309, - "venv/bin/jsonschema": 16516374846693491442, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_timedeltas.py": 4118671843063545221, - "frontend/build/_app/immutable/chunks/B2w4gPsQ.js": 2675139182904252836, - "venv/lib/python3.13/site-packages/numpy/core/__init__.pyi": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalarbuffer.py": 16859789411010045795, - "venv/lib/python3.13/site-packages/numpy/_core/umath.pyi": 11775804030935134661, - "venv/lib/python3.13/site-packages/uvicorn/middleware/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_index.py": 12015738970771703312, - "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/util.cpython-313-x86_64-linux-gnu.so": 12473903676666680134, - "venv/lib/python3.13/site-packages/greenlet/tests/test_gc.py": 6383305344377882524, - "venv/lib/python3.13/site-packages/pandas/core/indexes/range.py": 3838277376774246164, - "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/misc/extended_precision.pyi": 6541258584648209609, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_period_range.py": 9598872514187524706, - "venv/lib/python3.13/site-packages/packaging/_structures.py": 13086687542872305890, - "venv/lib/python3.13/site-packages/pip/_vendor/packaging/licenses/_spdx.py": 17182188548503720124, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/lib_function_base.pyi": 10972502518588022706, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_nlargest_nsmallest.py": 11049656379959696695, - "frontend/src/routes/tools/debug/+page.svelte": 8699044541980877686, - "frontend/build/_app/immutable/nodes/11.DDAAtpef.js": 1940689094142880081, - "backend/src/services/dataset_review/repositories/session_repository.py": 4058785536575367912, - "venv/lib/python3.13/site-packages/rpds/__init__.py": 5862197328247012275, - "venv/lib/python3.13/site-packages/httpcore/_async/__init__.py": 491192949420297153, - "backend/tests/test_translate_jobs.py": 16585154497956900995, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/type_check.pyi": 1599910480066368464, - "venv/lib/python3.13/site-packages/gitdb/test/test_example.py": 3039934065817753241, - "venv/lib/python3.13/site-packages/pip/_vendor/msgpack/__init__.py": 5896924546560667519, - "venv/lib/python3.13/site-packages/jsonschema/tests/typing/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/random/_examples/cffi/extending.py": 9859383893070793914, - "venv/lib/python3.13/site-packages/numpy/_typing/_scalars.py": 17701938912160369190, - "frontend/src/components/Navbar.svelte": 12353588862181566761, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_stride_tricks.py": 1064774375151677743, - "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_string.py": 15542851215119662814, - "venv/lib/python3.13/site-packages/jaraco/context/__init__.py": 10975097417056278427, - "backend/src/api/__init__.py": 5287505122015708040, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-log1p.csv": 16333455295913164408, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_setops.py": 13440916133402971190, - "frontend/build/_app/immutable/nodes/35.CJsJv8X6.js": 10348890531182330576, - "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/__init__.py": 4752355175318979033, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_win32_console.py": 18092547253031555768, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_sort_index.py": 14187428934500390688, - "venv/lib/python3.13/site-packages/numpy/_core/overrides.pyi": 13121243505132110607, - "frontend/build/_app/immutable/nodes/13.Cj83yPnA.js": 2832245715688571342, - "venv/lib/python3.13/site-packages/numpy/__config__.pyi": 1422114139050700402, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/rec.pyi": 9140655366667421698, - "docker/frontend.Dockerfile": 9514032629617942525, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/assertion.py": 5287436128235488464, - "venv/lib/python3.13/site-packages/passlib/utils/des.py": 2650106381178222229, - "frontend/src/lib/stores/__tests__/test_datasetReviewSession.js": 12620073136419991103, - "backend/tests/services/clean_release/test_publication_service.py": 17277940125978730159, - "venv/lib/python3.13/site-packages/numpy/_pyinstaller/__init__.pyi": 15130871412783076140, - "venv/lib/python3.13/site-packages/passlib/handlers/misc.py": 18255658377109333797, - "venv/lib/python3.13/site-packages/_pytest/main.py": 931018496411984909, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/data_stmts.f90": 6123192245816905092, - "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/WHEEL": 2357997949040430835, - "venv/lib/python3.13/site-packages/numpy/_core/_rational_tests.cpython-313-x86_64-linux-gnu.so": 13475521165331256711, - "venv/lib/python3.13/site-packages/pandas/core/interchange/column.py": 9498044216416177656, - "venv/lib/python3.13/site-packages/rapidfuzz/fuzz_cpp.cpython-313-x86_64-linux-gnu.so": 14187094676876471848, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/table.py": 16856253349556498073, - "venv/lib/python3.13/site-packages/attr/exceptions.py": 11532465891810816417, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/test_arrow_compat.py": 17818294260710640443, - "venv/lib/python3.13/site-packages/pandas/io/formats/templates/string.tpl": 15796203549130590784, - "venv/lib/python3.13/site-packages/rsa/common.py": 10921682819204792805, - "venv/lib/python3.13/site-packages/PIL/MpegImagePlugin.py": 7726254767528154514, - "venv/lib/python3.13/site-packages/pygments/formatters/pangomarkup.py": 17135620955205945255, - "frontend/src/routes/profile/__tests__/profile-settings-state.integration.test.js": 3674649277514557450, - "venv/lib/python3.13/site-packages/six.py": 948867418687428421, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_to_numpy.py": 9663734591667845940, - "venv/lib/python3.13/site-packages/pandas/_testing/contexts.py": 11714205921752896137, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/base.py": 13634605726041717070, - "backend/src/api/routes/assistant/_dataset_review_dispatch.py": 10108558091463171824, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_contains.py": 17630310725250553247, - "venv/lib/python3.13/site-packages/PIL/GimpGradientFile.py": 9777026720028891154, - "backend/logs/app.log.1": 5033969853318871181, - "venv/bin/fastapi": 12400009726251862770, - "venv/lib/python3.13/site-packages/pandas/core/arrays/sparse/__init__.py": 6758781485387665020, - "venv/lib/python3.13/site-packages/sqlalchemy/util/queue.py": 1289234691048379395, - "venv/lib/python3.13/site-packages/numpy/_core/lib/pkgconfig/numpy.pc": 14713682399742251335, - "venv/lib/python3.13/site-packages/numpy/_core/overrides.py": 252940520997718714, - "venv/lib/python3.13/site-packages/passlib/utils/binary.py": 13123975436674239306, - "backend/src/models/report.py": 9185954411073383239, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_indexing.py": 4063662953863959087, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/__init__.py": 14571251344510763303, - "backend/src/services/clean_release/stages/internal_sources_only.py": 3635582838654262092, - "venv/lib/python3.13/site-packages/pandas/core/construction.py": 10646956189518908985, - "venv/lib/python3.13/site-packages/pyasn1/type/univ.py": 7163437624197683039, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/file_proxy.py": 17695135735211897444, - "venv/lib/python3.13/site-packages/pandas/io/json/_normalize.py": 15938855324762935595, - "venv/lib/python3.13/site-packages/numpy/_pyinstaller/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_concat.py": 4472503149811617440, - "backend/src/services/clean_release/artifact_catalog_loader.py": 16969668877930596278, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/halffloat.h": 16913381775994652343, - "backend/logs/app.log.3": 366149754645105088, - "venv/lib/python3.13/site-packages/numpy/_core/einsumfunc.py": 11393954913234866059, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/jsonschema/tests/test_cli.py": 3173259257428855556, - "venv/lib/python3.13/site-packages/greenlet/platform/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/_pytest/legacypath.py": 7512065138259788426, - "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/licenses/LICENSE.PSF": 13208428090829817329, - "venv/lib/python3.13/site-packages/passlib/tests/test_context.py": 15195609282700801214, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_loc.py": 2127584756555503873, "venv/lib/python3.13/site-packages/pandas/tests/test_sorting.py": 10751098438703044961, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_function_base.py": 15241999259666702619, - "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/numpy/lib/stride_tricks.pyi": 5879290708972838025, - "venv/lib/python3.13/site-packages/greenlet/tests/test_cpp.py": 10982107081267457286, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_filters.py": 17271344092069736999, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_casting_floatingpoint_errors.py": 4301355720042319835, - "venv/lib/python3.13/site-packages/jsonschema/tests/test_jsonschema_test_suite.py": 12733761462141495972, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_scalar_compat.py": 10068989979144965125, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_iat.py": 3570464615146398178, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/dml.py": 5340326603935367534, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arccosh.csv": 5882025767947638305, - "venv/lib/python3.13/site-packages/pandas/tests/strings/test_strings.py": 17398806130402098912, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/cx_oracle.py": 10093932131797570986, - "venv/lib/python3.13/site-packages/cffi/lock.py": 13507686939203117974, - "backend/src/services/notifications/providers.py": 5844970860921555598, - "venv/lib/python3.13/site-packages/pydantic/parse.py": 13750341403702794392, - "backend/src/services/clean_release/repository.py": 3077298775936340703, - "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/METADATA": 6656194161182818439, - "venv/lib/python3.13/site-packages/pygments/lexers/mosel.py": 1877592344012288438, - "venv/lib/python3.13/site-packages/pygments/lexers/perl.py": 17014528337020572681, - "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/anyio/pytest_plugin.py": 4165280709813718099, - "venv/lib/python3.13/site-packages/numpy/random/_bounded_integers.pxd": 9126772093305708921, - "venv/lib/python3.13/site-packages/numpy/random/tests/test_generator_mt19937.py": 7299586490442539723, - "venv/lib/python3.13/site-packages/pydantic/v1/utils.py": 902648247561165429, - "venv/lib/python3.13/site-packages/attr/converters.pyi": 17675091788614033166, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/methods/test_round.py": 7912161077874611432, - "venv/lib/python3.13/site-packages/apscheduler/schedulers/asyncio.py": 11442130378027628520, - "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_deprecated_kwargs.py": 10379929935087904974, - "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/METADATA": 11557342107649194148, - "venv/lib/python3.13/site-packages/pygments/lexers/_ada_builtins.py": 16331776886501464264, - "backend/src/models/clean_release.py": 6080208142954589647, - "venv/lib/python3.13/site-packages/authlib/jose/rfc8037/jws_eddsa.py": 833927568269372333, - "venv/lib/python3.13/site-packages/pandas/_libs/hashing.pyi": 5241441378073929968, - "venv/lib/python3.13/site-packages/pandas/core/window/rolling.py": 6316477981414191778, - "venv/lib/python3.13/site-packages/dateutil/zoneinfo/rebuild.py": 1813298167468704155, - "venv/lib/python3.13/site-packages/numpy/linalg/lapack_lite.pyi": 14069586330277925998, - "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/LICENSE": 8423899413955829149, - "venv/lib/python3.13/site-packages/_pytest/config/argparsing.py": 11156052029258891503, - "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_generic.py": 1098361087956787007, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/lambdas.py": 13377298868598623228, - "venv/lib/python3.13/site-packages/pygments/lexers/haskell.py": 8011341851439354724, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/module_data_docstring.f90": 18245403117623015312, - "venv/lib/python3.13/site-packages/starlette/exceptions.py": 15978811612997200737, - "venv/lib/python3.13/site-packages/ecdsa/eddsa.py": 15966858338456571506, - "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/signals.py": 10390443713463805090, - "venv/lib/python3.13/site-packages/pandas/core/computation/expressions.py": 10684284531040203747, - "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_conversion.py": 12184280074522274780, - "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/einsumfunc.pyi": 200771351328522379, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_style.py": 6849613206971398029, - "venv/lib/python3.13/site-packages/pip/_internal/utils/deprecation.py": 7435269308988385470, - "venv/lib/python3.13/site-packages/pygments/formatter.py": 11156733836937309465, - "venv/bin/Activate.ps1": 1196103427939049710, - "frontend/build/_app/immutable/chunks/DbEeTmbI.js": 7478467633861776200, - "venv/lib/python3.13/site-packages/numpy/_pyinstaller/tests/test_pyinstaller.py": 9430762168079129025, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/decl_class.py": 6328411894571735935, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/Prefix.py": 4672871351134074735, - "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libk5crypto-b1f99d5c.so.3.1": 10669523137596317954, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/base.py": 6348888156686452825, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_setops.py": 9991233160569430204, - "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/METADATA": 3618776395694990076, - "venv/lib/python3.13/site-packages/pydantic_settings/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/jsonschema/cli.py": 9813914882090789748, - "venv/lib/python3.13/site-packages/typing_inspection/introspection.py": 13916695705179237047, - "venv/lib/python3.13/site-packages/pandas/core/reshape/tile.py": 17137524194129840833, - "venv/lib/python3.13/site-packages/authlib/common/security.py": 2291133227104016684, - "venv/lib/python3.13/site-packages/jaraco/classes/meta.py": 15930255620248873425, - "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/licenses/LICENSE.rst": 5960743202700406649, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/asymmetric_key.py": 14948661854506285135, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_arithmetic.py": 13304014482504911016, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/mypy.ini": 4763385838822685881, - "venv/lib/python3.13/site-packages/pandas/io/sas/sasreader.py": 12766780210114366112, - "venv/lib/python3.13/site-packages/PIL/IcoImagePlugin.py": 14483964191652228364, - "venv/lib/python3.13/site-packages/httpcore/_backends/trio.py": 8394426709857317737, - "venv/lib/python3.13/site-packages/pyasn1/type/tag.py": 13912273274509186651, - "venv/lib/python3.13/site-packages/pygments/lexers/iolang.py": 10997512999728724130, - "venv/lib/python3.13/site-packages/greenlet/PyGreenlet.cpp": 7360124705400993707, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_explode.py": 16195468192763502449, - "backend/src/scripts/seed_superset_load_test.py": 14952302154142898180, - "backend/src/core/__tests__/test_throttled_scheduler.py": 10949494963069000037, - "venv/lib/python3.13/site-packages/pygments/lexers/openscad.py": 13045825115225232396, - "venv/lib/python3.13/site-packages/numpy/lib/scimath.pyi": 18165025261847276375, - "venv/lib/python3.13/site-packages/greenlet/TStackState.cpp": 16720079760074325527, - "frontend/build/_app/immutable/chunks/BZrlJ68A.js": 11613051606352698644, - "venv/lib/python3.13/site-packages/pillow.libs/libXau-154567c4.so.6.0.0": 4340972632724893052, - "venv/lib/python3.13/site-packages/pip/_vendor/__init__.py": 11734104142988812647, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_pivot.py": 334735766122314163, - "venv/lib/python3.13/site-packages/pydantic/v1/mypy.py": 17076910404409672245, - "venv/lib/python3.13/site-packages/numpy/ma/core.py": 338350463523585845, - "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_can_hold_element.py": 5406431247116557833, - "venv/lib/python3.13/site-packages/charset_normalizer/__init__.py": 12412600648990392633, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/__ufunc_api.h": 4516275133897904047, - "venv/lib/python3.13/site-packages/websockets/datastructures.py": 5180442040351387281, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_item.py": 17619314877770917080, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_index.py": 1551768441102117466, - "venv/lib/python3.13/site-packages/pygments/lexers/func.py": 12257919753150082714, - "venv/lib/python3.13/site-packages/anyio/to_thread.py": 12767326212338028587, - "venv/lib/python3.13/site-packages/pandas/core/roperator.py": 2587829042468916489, - "venv/lib/python3.13/site-packages/git/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-sin.csv": 1443087417808027268, - "backend/alembic/versions/ed310b33f02c_multi_language_translation_tables.py": 1424919631205944664, - "venv/lib/python3.13/site-packages/pip/_vendor/msgpack/fallback.py": 4260636031748548345, - "venv/lib/python3.13/site-packages/click/exceptions.py": 9734955259447933725, - "venv/lib/python3.13/site-packages/anyio/to_process.py": 16627578499791368365, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_s390_unix.h": 5161826643658505126, - "frontend/src/lib/stores/__tests__/taskDrawer.test.js": 12307450726550947042, - "venv/lib/python3.13/site-packages/pydantic/deprecated/class_validators.py": 2200511838255373813, - "venv/lib/python3.13/site-packages/pandas/tests/frame/conftest.py": 15090201792072045503, - "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/RECORD": 1051307407005554409, - "venv/lib/python3.13/site-packages/pygments/lexers/_openedge_builtins.py": 4979988747924637739, - "venv/lib/python3.13/site-packages/jsonschema/__main__.py": 18136546137047911521, - "venv/lib/python3.13/site-packages/pip/_vendor/requests/__init__.py": 11009955319062089477, - "venv/lib/python3.13/site-packages/rapidfuzz/__init__.py": 12462153783886855740, - "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/__init__.py": 5895297076117159245, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/x963kdf.py": 14995426099932276090, - "venv/lib/python3.13/site-packages/pandas/core/window/doc.py": 4204367435727844696, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_methods.py": 12694335778731418517, - "venv/lib/python3.13/site-packages/attr/filters.py": 14156141488477438777, - "venv/lib/python3.13/site-packages/attr/validators.pyi": 15579625896285277321, - "venv/lib/python3.13/site-packages/greenlet/TGreenlet.hpp": 6993553444981671786, - "venv/lib/python3.13/site-packages/numpy/f2py/auxfuncs.pyi": 10077265709692546934, - "venv/lib/python3.13/site-packages/numpy/f2py/cb_rules.py": 11397521081216402594, - "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/RECORD": 10264342250058307301, - "venv/lib/python3.13/site-packages/keyring/http.py": 1408024724330078009, - "venv/lib/python3.13/site-packages/idna/idnadata.py": 200840860629525970, - "venv/lib/python3.13/site-packages/httpx/__init__.py": 6383055693166097719, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_round.py": 8336918400205461173, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_factorize.py": 17995673140216929494, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_delete.py": 5958440386632506587, - "venv/lib/python3.13/site-packages/pandas/tests/extension/base/accumulate.py": 5780225603819849877, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_drop.py": 11341278355685583133, - "venv/lib/python3.13/site-packages/pandas/tests/io/xml/test_xml.py": 6906547816798138000, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_function_base.py": 16624804022675533740, - "venv/lib/python3.13/site-packages/pandas/io/formats/csvs.py": 17223598248259691292, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/dml.py": 17308908394336670576, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/declarative/__init__.py": 2436195108273216959, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_warnings.py": 13071210233876253749, - "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_ufunclike.py": 13752381070039804384, - "venv/lib/python3.13/site-packages/charset_normalizer/cli/__init__.py": 9702005609966176016, - "frontend/src/components/RepositoryDashboardGrid.svelte": 17100594220040865069, - "frontend/build/_app/immutable/entry/start.BFyEuKf2.js": 2516797770297376306, - "venv/lib/python3.13/site-packages/pandas/core/internals/blocks.py": 6448406236246476333, - "backend/src/models/translate.py": 15814361247636396225, - "venv/lib/python3.13/site-packages/cryptography/x509/name.py": 15338066443257445241, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/linalg.pyi": 269481015135399748, - "venv/lib/python3.13/site-packages/passlib/tests/test_utils_pbkdf2.py": 17016810698578473773, - "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/resolver.py": 9931394693284776391, - "venv/lib/python3.13/site-packages/pandas/core/dtypes/astype.py": 9925183787411796679, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_partial_indexing.py": 4132091154215910029, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_update.py": 9098258267671647783, - "venv/lib/python3.13/site-packages/greenlet/greenlet_compiler_compat.hpp": 465436185632243991, - "venv/lib/python3.13/site-packages/pip/_vendor/distlib/scripts.py": 8759605303886441976, - "venv/lib/python3.13/site-packages/jose/backends/ecdsa_backend.py": 2684176977865283060, - "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/WHEEL": 2823347510103459191, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_indexing.py": 14717641281147152159, - "venv/lib/python3.13/site-packages/pycparser/_build_tables.py": 569728086093219621, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/fields.py": 10090313990429695520, - "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/requests.py": 14847842002253212098, - "venv/lib/python3.13/site-packages/pandas/core/ops/docstrings.py": 3721650738518391256, - "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_downcast.py": 10399746645741452200, - "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_polynomial.py": 777287409151500309, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/requests.py": 1102963893193914979, - "venv/lib/python3.13/site-packages/numpy/random/_examples/cffi/parse.py": 2427019397934437210, - "venv/lib/python3.13/site-packages/sqlalchemy/event/__init__.py": 16182540084654095394, - "venv/lib/python3.13/site-packages/numpy/polynomial/_polytypes.pyi": 7528777458251688517, - "venv/lib/python3.13/site-packages/passlib/handlers/ldap_digests.py": 8658529184965699766, - "venv/lib/python3.13/site-packages/_pytest/unittest.py": 10848803633530338204, - "venv/lib/python3.13/site-packages/pip/_internal/utils/setuptools_build.py": 13594639612360346306, - "venv/lib/python3.13/site-packages/pydantic/types.py": 785880062468926292, - "venv/lib/python3.13/site-packages/pydantic/v1/datetime_parse.py": 10467114625921924095, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/util.py": 10640907133050862176, - "venv/lib/python3.13/site-packages/PIL/ImageSequence.py": 16459886231802763032, - "frontend/src/lib/components/assistant/__tests__/assistant_chat.integration.test.js": 13047006106880121194, - "backend/src/api/routes/git/__init__.py": 9989336734947065016, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/shape_base.pyi": 10291383658131961346, - "venv/lib/python3.13/site-packages/sqlalchemy/engine/util.py": 1520899420719605380, - "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/content": 12465123883296161860, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_common.h": 14732581790650403546, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_reset_index.py": 14490875921264161445, - "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/WHEEL": 16097436423493754389, - "venv/lib/python3.13/site-packages/PIL/PcfFontFile.py": 8867692961463798279, - "backend/src/services/clean_release/enums.py": 7365670144442292671, - "venv/lib/python3.13/site-packages/click-8.3.1.dist-info/WHEEL": 8600534672961461758, - "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_readlines.py": 15928258358116399067, - "venv/lib/python3.13/site-packages/jeepney-0.9.0.dist-info/WHEEL": 12054782055241301457, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/__init__.py": 15130871412783076140, - "backend/src/services/reports/type_profiles.py": 8365014439236739390, - "venv/lib/python3.13/site-packages/pygments/lexers/tnt.py": 4657130609241407766, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/unicode_comment.f90": 11326797716215117266, - "backend/src/services/git/_url.py": 15729080796864187707, - "venv/lib/python3.13/site-packages/fastapi/security/__init__.py": 1345944646061334046, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90": 8821492401453445757, - "frontend/build/_app/immutable/chunks/Mn1vnqBO.js": 5859696651271826291, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/__init__.py": 2246704695838251846, - "venv/lib/python3.13/site-packages/cffi/vengine_cpy.py": 10684192171370688079, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/data_with_comments.f": 3980077223827767077, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_formats.py": 10263085276270778330, - "backend/src/api/routes/git/_router.py": 8701683910668868827, - "venv/lib/python3.13/site-packages/idna/uts46data.py": 5698404064763638591, - "venv/lib/python3.13/site-packages/pandas/io/parsers/base_parser.py": 15148258424429418380, - "venv/lib/python3.13/site-packages/jsonschema/tests/test_deprecations.py": 16367195310156359251, - "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_json_table_schema.py": 14454690938977069049, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/npyio.pyi": 14147712281086095231, - "venv/lib/python3.13/site-packages/git/index/base.py": 641556304637379636, - "venv/lib/python3.13/site-packages/yaml/scanner.py": 8554164423030397366, - "venv/lib/python3.13/site-packages/pandas/tests/test_common.py": 8987965560487646705, - "backend/src/api/routes/__tests__/test_connections_routes.py": 18044815559820610056, - "venv/lib/python3.13/site-packages/pandas/tests/window/moments/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/jsonschema/benchmarks/unused_registry.py": 10153622516112471812, - "venv/lib/python3.13/site-packages/rapidfuzz/_feature_detector_cpp.cpython-313-x86_64-linux-gnu.so": 16337157355618216738, - "venv/lib/python3.13/site-packages/git/refs/head.py": 16271128287606894569, - "venv/lib/python3.13/site-packages/pygments/lexers/_scheme_builtins.py": 5722444920479775453, - "frontend/src/lib/components/health/HealthMatrix.svelte": 16085178486788467644, - "venv/lib/python3.13/site-packages/ecdsa/keys.py": 10281170640484982154, - "venv/lib/python3.13/site-packages/numpy/random/_pcg64.pyi": 14785496840737986355, - "venv/lib/python3.13/site-packages/pandas/core/methods/to_dict.py": 4653628436393663485, - "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_get_value.py": 389530025760539462, - "venv/lib/python3.13/site-packages/passlib/pwd.py": 14727089240749133060, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/comparisons.py": 7327629888601690759, - "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_categorical.py": 12897027063618569795, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_partial.py": 15129217814262096441, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_isetitem.py": 14895552405828068177, - "venv/lib/python3.13/site-packages/apscheduler/executors/tornado.py": 6635576580306890718, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/type_api.py": 10299750173867399533, - "backend/src/plugins/llm_analysis/__init__.py": 9254812131558249924, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_read_errors.py": 4559483361564472117, - "backend/src/plugins/git_plugin.py": 12799126783361308681, - "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/packaging/licenses/__init__.py": 15879493360260891293, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_swaplevel.py": 3584770792383216626, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_datetimelike.py": 5317270578347271174, - "venv/lib/python3.13/site-packages/authlib/oidc/registration/claims.py": 4161520263207458028, - "venv/lib/python3.13/site-packages/pip/_internal/models/index.py": 2839270935469791607, - "venv/lib/python3.13/site-packages/numpy/_core/_ufunc_config.pyi": 9291444594181042963, - "venv/lib/python3.13/site-packages/pandas/tests/extension/test_extension.py": 17245018204352082978, - "venv/lib/python3.13/site-packages/pandas/tests/test_multilevel.py": 10500316376521962061, - "venv/lib/python3.13/site-packages/PIL/AvifImagePlugin.py": 1872412416505003364, - "venv/lib/python3.13/site-packages/pip/_vendor/requests/cookies.py": 4997226307650350876, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/lexers/__init__.py": 7316739139609490520, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_copy.py": 12902342280706372953, - "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/mean_.py": 3641008929910474457, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_isin.py": 8136794647591341784, - "venv/lib/python3.13/site-packages/jsonschema/tests/test_validators.py": 14178329676643700151, - "frontend/build/_app/env.js": 8815854342083926790, - "venv/lib/python3.13/site-packages/pygments/lexers/ml.py": 7510453371068494792, - "venv/lib/python3.13/site-packages/greenlet/tests/fail_switch_three_greenlets.py": 10923534235697247269, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_data.py": 2397937327057341, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/bitwise_ops.pyi": 15598239133239520456, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/pymysql.py": 12923876736367229454, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/layout.py": 11554376181083053156, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_reshape.py": 5572426834735088916, - "venv/lib/python3.13/site-packages/sqlalchemy/engine/result.py": 12262298207886620908, - "venv/lib/python3.13/site-packages/numpy/rec/__init__.pyi": 1782063765067823837, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/random.pyi": 1808392097712315455, - "venv/lib/python3.13/site-packages/pygments/lexers/typst.py": 8883289726601667104, - "venv/lib/python3.13/site-packages/pydantic/deprecated/decorator.py": 8609500261161560793, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/schema.py": 5391655516870611151, - "venv/lib/python3.13/site-packages/keyring/backends/libsecret.py": 11621088556661567306, - "venv/lib/python3.13/site-packages/pyasn1/codec/native/__init__.py": 15728752901274520502, - "venv/lib/python3.13/site-packages/pandas/api/__init__.py": 1145864207387918302, - "venv/lib/python3.13/site-packages/pandas/tests/extension/list/test_list.py": 4538625980063375611, - "frontend/src/lib/stores/sidebar.js": 8409084311045055153, - "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/util.py": 18279366777506483176, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/hashes.pyi": 7385072545198817771, - "venv/lib/python3.13/site-packages/gitdb/db/pack.py": 13460574575424209609, - "venv/lib/python3.13/site-packages/pandas/tests/apply/common.py": 1113935558495455492, - "venv/lib/python3.13/site-packages/pyasn1/codec/ber/decoder.py": 12653470212935324322, - "venv/lib/python3.13/site-packages/_pytest/_py/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/extension/test_numpy.py": 4073641912755651877, - "venv/lib/python3.13/site-packages/pandas/tests/extension/base/reduce.py": 14976712507854054776, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/_py_util.py": 12836989066113400538, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/instrumentation.py": 14882045449667214075, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/request.py": 10492090878715126550, - "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_internal/distributions/base.py": 16714704323747942110, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_timezones.py": 8042029178538467146, - "frontend/src/routes/admin/roles/+page.svelte": 12213033002088655108, - "backend/src/app.py": 1030174853208129525, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/resource_protector.py": 11539718751174980004, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/OSA_py.py": 2494967094400350388, - "venv/lib/python3.13/site-packages/pygments/formatters/rtf.py": 5850574956253747036, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_formats.py": 3525283725314253763, - "frontend/src/lib/components/ui/MultiSelect.svelte": 13967450784969599105, - "backend/src/services/dataset_review/repositories/__tests__/test_session_repository.py": 18317443814450756666, - "venv/lib/python3.13/site-packages/pygments/lexers/unicon.py": 1155454077052833821, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/_public_dtype_api_table.h": 8933016749764021181, - "venv/lib/python3.13/site-packages/idna/__init__.py": 6489437464172324468, - "venv/lib/python3.13/site-packages/pillow.libs/libsharpyuv-95d8a097.so.0.1.2": 5320647379976541240, - "venv/lib/python3.13/site-packages/pandas/core/interchange/dataframe_protocol.py": 12857147443873820285, - "venv/lib/python3.13/site-packages/pandas/_libs/json.pyi": 10989301892466547548, - "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/WHEEL": 7795541085444298627, - "venv/lib/python3.13/site-packages/numpy/ctypeslib/_ctypeslib.pyi": 10360538024015064036, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/baked.py": 6911138208603240867, - "venv/lib/python3.13/site-packages/websockets/legacy/server.py": 5390090919193784186, - "venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/_pytest/_argcomplete.py": 3586514420674089892, - "venv/lib/python3.13/site-packages/cryptography/x509/verification.py": 1079694784860492682, - "venv/lib/python3.13/site-packages/pandas/tests/frame/test_nonunique_indexes.py": 15468078561381939405, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_repeat.py": 16971624301893342868, - "venv/lib/python3.13/site-packages/PIL/_imagingmorph.cpython-313-x86_64-linux-gnu.so": 11171810899664471137, - "backend/src/api/routes/dataset_review.py": 3689614039699023362, - "venv/lib/python3.13/site-packages/iniconfig/__init__.py": 12623265899068631092, - "venv/lib/python3.13/site-packages/apscheduler/jobstores/mongodb.py": 5310116401542377882, - "venv/lib/python3.13/site-packages/pygments/styles/xcode.py": 14124729477757765388, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_null_file.py": 6885565068723353414, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_dlpack.py": 7908102652282922952, - "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/code.py": 9700811903057180696, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/array_constructors.pyi": 4993066609272697419, - "venv/lib/python3.13/site-packages/pandas/io/pickle.py": 5418646169167774144, - "venv/lib/python3.13/site-packages/pygments/lexers/stata.py": 7249891970174867363, - "venv/lib/python3.13/site-packages/anyio/_core/_synchronization.py": 7050001375718876608, - "venv/lib/python3.13/site-packages/pygments/lexers/elpi.py": 5736689911777977822, - "backend/src/api/routes/profile.py": 16065196073183170065, - "backend/src/scripts/create_admin.py": 11258281301071059367, - "venv/lib/python3.13/site-packages/pandas/tests/extension/base/groupby.py": 12749730954888633240, - "venv/lib/python3.13/site-packages/pip/_internal/metadata/pkg_resources.py": 14271077832999370068, - "venv/lib/python3.13/site-packages/_pytest/threadexception.py": 10464996327276961035, - "venv/lib/python3.13/site-packages/pandas/tests/series/test_ufunc.py": 669019702416198889, - "venv/lib/python3.13/site-packages/passlib/crypto/des.py": 14699826058580193499, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/test_reductions.py": 8258332365408303156, - "venv/lib/python3.13/site-packages/certifi/__main__.py": 13417658012431779061, - "venv/lib/python3.13/site-packages/pandas/io/sas/sas_constants.py": 14492427939536692313, - "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_construct_object_arr.py": 4725156416161661681, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/exc.py": 1448374203226983757, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/assumed_shape/foo_use.f90": 2657057181044959432, - "venv/lib/python3.13/site-packages/PIL/MicImagePlugin.py": 13540523615822507963, - "venv/lib/python3.13/site-packages/uvicorn/_compat.py": 2593000889619875759, - "venv/lib/python3.13/site-packages/packaging/markers.py": 11602308203217831543, - "venv/lib/python3.13/site-packages/pydantic/plugin/_schema_validator.py": 857640644840976862, - "venv/lib/python3.13/site-packages/requests/models.py": 9104898985870652256, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/ufuncobject.h": 5112456258078662871, - "venv/lib/python3.13/site-packages/pygments/lexers/rust.py": 8605690716125176329, - "backend/src/api/routes/environments.py": 6892252055515346170, - "frontend/src/components/TaskLogViewer.svelte": 14310893311791502213, - "backend/src/plugins/translate/_token_budget.py": 7640610492252771386, - "backend/src/api/routes/dashboards/_helpers.py": 16683849709430404975, - "venv/lib/python3.13/site-packages/numpy/_typing/__init__.py": 18242238390157333247, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/pickleable.py": 7712040860601343075, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_get_set.py": 14375107704596905983, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/usecols/test_strings.py": 7379299916213794543, - "venv/lib/python3.13/site-packages/gitdb/pack.py": 7828244200815444166, - "venv/lib/python3.13/site-packages/pyasn1/codec/ber/__init__.py": 15728752901274520502, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_x64_msvc.h": 17581467060937454503, - "venv/lib/python3.13/site-packages/httpcore/_async/interfaces.py": 18250473733460571816, - "venv/lib/python3.13/site-packages/pygments/lexers/apl.py": 16767474673619335683, - "backend/src/api/routes/assistant/_history.py": 16318881016647964852, - "venv/lib/python3.13/site-packages/PIL/features.py": 3481835375516797487, - "backend/src/models/llm.py": 14295626272101666880, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/panel.py": 17832701246248000383, - "venv/lib/python3.13/site-packages/numpy/random/tests/data/pcg64dxsm-testset-1.csv": 9129730764673472086, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/period/test_arithmetic.py": 13320788210970132239, - "venv/lib/python3.13/site-packages/pygments/lexers/rita.py": 8105458520706587972, - "venv/lib/python3.13/site-packages/pandas/core/arrays/integer.py": 7775055011080964709, - "frontend/build/_app/immutable/chunks/DVeZEXwF.js": 16066942382203165258, - "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/METADATA": 3814104793342833872, - "venv/lib/python3.13/site-packages/pygments/lexers/futhark.py": 10102535873433759899, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_numpy_array_equal.py": 2089426719574307767, - "venv/lib/python3.13/site-packages/pip/_internal/network/auth.py": 6159841209618753296, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/datasource.pyi": 16752667877866430577, - "frontend/build/_app/immutable/nodes/29.C8yatGIj.js": 7788955111119786799, - "venv/lib/python3.13/site-packages/greenlet/tests/fail_cpp_exception.py": 11851283355840567373, - "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_julian_date.py": 850085757774959003, - "venv/lib/python3.13/site-packages/numpy/testing/overrides.py": 11819432487830192978, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/__init__.py": 16146480198665866916, - "venv/lib/python3.13/site-packages/PIL/XbmImagePlugin.py": 12256750478268246137, - "venv/lib/python3.13/site-packages/numpy/typing/__init__.pyi": 10058149460938883683, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/test_holiday.py": 8541197358003711845, - "frontend/src/lib/stores/__tests__/assistantChat.test.js": 11822882112255142537, - "venv/lib/python3.13/site-packages/pygments/lexers/vyper.py": 6477559246065994199, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/__init__.py": 14571251344510763303, - "venv/lib/python3.13/site-packages/uvicorn/config.py": 17317823506849880916, - "venv/lib/python3.13/site-packages/urllib3-2.6.2.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/numpy/f2py/src/fortranobject.c": 2519219289444051739, - "venv/lib/python3.13/site-packages/pandas/_libs/window/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/__init__.py": 2397613800206300456, - "backend/logs/app.log.4": 11598841362861329809, - "venv/lib/python3.13/site-packages/websockets/http11.py": 11022534176398053082, - "venv/lib/python3.13/site-packages/dateutil/parser/isoparser.py": 18015430204844361067, - "venv/lib/python3.13/site-packages/jaraco/functools/__init__.py": 15334412919279565528, - "venv/lib/python3.13/site-packages/greenlet/greenlet_msvc_compat.hpp": 12504008513945919250, - "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/METADATA": 13633829318759752611, - "venv/lib/python3.13/site-packages/numpy/exceptions.py": 10981418339663118022, - "venv/lib/python3.13/site-packages/greenlet/tests/test_generator.py": 14156412320760444199, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-exp2.csv": 10950201682596097452, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/dtypes/test_categorical.py": 9615571808720893016, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_cpu_features.py": 955759654189150497, - "venv/lib/python3.13/site-packages/pygments/styles/fruity.py": 7925019839136894457, - "venv/lib/python3.13/site-packages/numpy/random/__init__.pxd": 7355772669172093814, - "venv/lib/python3.13/site-packages/keyring/testing/util.py": 11195868112805409554, - "venv/lib/python3.13/site-packages/pip/_vendor/idna/core.py": 2199607970842512780, - "venv/lib/python3.13/site-packages/pandas/io/formats/templates/typst.tpl": 5055419073126793137, - "venv/lib/python3.13/site-packages/pygments/styles/gruvbox.py": 9489017112545247388, - "venv/lib/python3.13/site-packages/numpy/linalg/__init__.py": 15647756307608142577, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_log_render.py": 18076931145915444473, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/rsa.py": 7852235015155694076, - "venv/lib/python3.13/site-packages/numpy/_core/_operand_flag_tests.cpython-313-x86_64-linux-gnu.so": 12296711931541109624, - "venv/lib/python3.13/site-packages/yaml/cyaml.py": 9157893742065554693, - "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/WHEEL": 7454950858448014158, - "venv/lib/python3.13/site-packages/pydantic/_internal/_core_metadata.py": 5704137311404303574, - "venv/lib/python3.13/site-packages/pyasn1/codec/cer/encoder.py": 3261739474564948330, - "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/INSTALLER": 17282701611721059870, - "scripts/build_offline_docker_bundle.sh": 18334040481218597997, - "venv/lib/python3.13/site-packages/attr/_version_info.py": 3850449653182103457, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/Levenshtein.pyi": 12925006572914814268, - "venv/lib/python3.13/site-packages/pip/_internal/utils/appdirs.py": 539688259643447487, - "venv/lib/python3.13/site-packages/pydantic/_internal/_validate_call.py": 4078236486720616395, - "venv/lib/python3.13/site-packages/pandas/_libs/writers.pyi": 10494773026133244183, - "venv/lib/python3.13/site-packages/pandas/tests/extension/test_sparse.py": 14343335524508450058, - "venv/lib/python3.13/site-packages/httpcore/_ssl.py": 6665087294869504820, - "venv/lib/python3.13/site-packages/pycparser/ply/cpp.py": 1665654017894222868, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc64_aix.h": 8706347224105630468, - "venv/lib/python3.13/site-packages/pip/_internal/locations/__init__.py": 8147012724727395488, - "venv/lib/python3.13/site-packages/urllib3/exceptions.py": 9687187566231423953, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_f2py2e.py": 8571347023940385644, - "venv/lib/python3.13/site-packages/ecdsa/test_jacobi.py": 1249543655136186433, - "venv/lib/python3.13/site-packages/tzlocal-5.3.1.dist-info/WHEEL": 5076688779572520166, - "venv/lib/python3.13/site-packages/pygments/styles/lightbulb.py": 12433916113773598760, - "backend/src/scripts/clean_release_tui.py": 7514485779948079886, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_map.py": 4761668276463940924, - "frontend/src/lib/components/dataset-review/ValidationFindingsPanel.svelte": 2403276296409515448, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7662/__init__.py": 17454177076687312424, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7009/parameters.py": 1647490964392525933, - "backend/src/services/__tests__/test_rbac_permission_catalog.py": 5190751380981933250, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/comparisons.pyi": 9338084426044982038, - "backend/src/core/plugin_base.py": 11649432288706102843, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/scalars.pyi": 3130685119595923378, - "venv/lib/python3.13/site-packages/pandas/tests/strings/test_api.py": 10514120091521589282, - "backend/src/services/__tests__/test_llm_plugin_persistence.py": 2413185961042174999, - "venv/lib/python3.13/site-packages/pandas/core/indexes/base.py": 496956059910401121, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arrayterator.pyi": 7439348655567232744, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalar_ctors.py": 631744056514965940, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/__ufunc_api.c": 11535375410441493281, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_quarter.py": 11099677280196239755, - "venv/lib/python3.13/site-packages/pygments/lexers/hdl.py": 6772823608124143123, - "venv/lib/python3.13/site-packages/numpy/matrixlib/defmatrix.pyi": 17903213294220335051, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_logical.py": 6242457515917145500, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh23598Warn.f90": 7589258200398878529, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_groupby_dropna.py": 3620959914439334511, - "venv/lib/python3.13/site-packages/pygments/token.py": 6987328478153445584, - "venv/lib/python3.13/site-packages/sqlalchemy/pool/__init__.py": 4337679908168515343, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_emoji_replace.py": 8166203537440976347, - "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/cffi/cffi_opcode.py": 8411344362428947268, - "venv/lib/python3.13/site-packages/click/shell_completion.py": 5858110451169927373, - "venv/lib/python3.13/site-packages/cryptography/hazmat/asn1/__init__.py": 4290669519959060720, - "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/resource_protector.py": 9147671710440653567, - "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/json.py": 15373167408891671190, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/datetimes/test_constructors.py": 3440572832185940666, - "venv/lib/python3.13/site-packages/pandas/core/_numba/executor.py": 2205130934861422769, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_describe.py": 362374422228593281, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/string/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/METADATA": 6557531107125553027, - "venv/lib/python3.13/site-packages/keyring/credentials.py": 14515496037842724455, - "venv/lib/python3.13/site-packages/idna-3.11.dist-info/RECORD": 11541505360973709787, - "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/WHEEL": 16097436423493754389, - "venv/lib/python3.13/site-packages/pygments/lexers/sql.py": 15566262873151658034, - "backend/src/api/routes/dashboards/_listing_routes.py": 1750634467656242702, - "venv/lib/python3.13/site-packages/jsonschema/tests/test_format.py": 1947585389944838076, - "venv/lib/python3.13/site-packages/numpy/testing/__init__.py": 2831275254313750978, - "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/WHEEL": 2357997949040430835, - "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/METADATA": 1862765380818895200, - "venv/lib/python3.13/site-packages/numpy/f2py/_backends/meson.build.template": 9935732744553086652, - "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/filewrapper.py": 17786759398959482432, - "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_timedeltas.py": 1175883320586860493, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/attributes.py": 5068814626384132900, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py": 6152202474302791232, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/names.py": 705261158040926128, - "backend/src/api/auth.py": 16577622718621592661, - "venv/lib/python3.13/site-packages/pygments/lexers/snobol.py": 414946539602526513, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/client_credentials.py": 256154392957334831, - "venv/lib/python3.13/site-packages/httpx/_config.py": 8800538050293498928, - "venv/lib/python3.13/site-packages/numpy/_core/getlimits.py": 7842717073693731093, - "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_set_value.py": 17480833128128893268, - "venv/lib/python3.13/site-packages/dateutil/utils.py": 7067026915090881998, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ufunclike.py": 12077553320554633586, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_month.py": 14597470286884431085, - "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/dotenv.py": 5872848911499749500, - "venv/lib/python3.13/site-packages/pip/_internal/network/session.py": 293771075394156394, - "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/core": 6622984507059115517, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_value_counts.py": 15633881149834196174, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/tree.py": 4991806303236874829, - "venv/lib/python3.13/site-packages/numpy/random/tests/data/pcg64-testset-1.csv": 16078879475693341404, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_comparisons.py": 2764694394636775220, - "venv/lib/python3.13/site-packages/git/types.py": 13960696584646279283, - "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/response.py": 9594165377270752433, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_custom_dtypes.py": 12322100282959605055, - "backend/tests/test_log_persistence.py": 11073909507089982937, - "backend/src/api/routes/storage.py": 15226523387798112491, - "dist/docker/frontend.v1.0.0-rc2-docker.tar": 1705027241971137937, - "frontend/build/_app/immutable/chunks/rZT47aGk.js": 16973416575478295852, - "venv/lib/python3.13/site-packages/pandas/core/array_algos/take.py": 3170415198452493008, - "venv/lib/python3.13/site-packages/passlib/tests/test_apache.py": 12515001998770565375, - "venv/lib/python3.13/site-packages/gitdb/db/git.py": 13552203494737962026, - "venv/lib/python3.13/site-packages/numpy/f2py/use_rules.pyi": 18395688193449688360, - "venv/lib/python3.13/site-packages/passlib/tests/test_utils_md4.py": 15270721044910698449, - "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_libfrequencies.py": 16302676625743291594, - "venv/lib/python3.13/site-packages/pandas/_testing/_io.py": 14264259716673715185, - "venv/lib/python3.13/site-packages/pydantic/_internal/_signature.py": 17075003201648027250, - "venv/lib/python3.13/site-packages/pip/_internal/operations/build/wheel.py": 7728646523045538484, - "frontend/src/components/MissingMappingModal.svelte": 11264881226066623003, - "backend/src/core/cot_logger.py": 3113579786931231764, - "venv/lib/python3.13/site-packages/uvicorn/workers.py": 7213290478118197047, - "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/heuristics.py": 1422768761337195135, - "venv/lib/python3.13/site-packages/pandas/tests/series/test_formats.py": 13752366280743004410, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_size.py": 12449835577388069407, - "venv/lib/python3.13/site-packages/pandas/tests/config/test_localization.py": 9524481848419616725, - "venv/lib/python3.13/site-packages/pip/_vendor/certifi/cacert.pem": 15624463015628939254, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_indexing.py": 4334578480714520407, - "venv/lib/python3.13/site-packages/httpcore/_sync/http11.py": 5947339024588907032, - "venv/lib/python3.13/site-packages/python_multipart/multipart.py": 5677735019292537174, - "venv/lib/python3.13/site-packages/websockets/speedups.cpython-313-x86_64-linux-gnu.so": 10941658763526595989, - "venv/lib/python3.13/site-packages/greenlet/tests/fail_switch_two_greenlets.py": 11156275429806391390, - "venv/lib/python3.13/site-packages/click/_utils.py": 16491408631876616271, - "venv/lib/python3.13/site-packages/gitdb/db/loose.py": 17467413653016810702, - "venv/lib/python3.13/site-packages/numpy/__init__.pxd": 13527602429695748857, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/spinner.py": 5564789578696016201, - "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/METADATA": 3179724236887811680, - "venv/lib/python3.13/site-packages/numpy/f2py/common_rules.pyi": 2104100025130695295, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/ansi.py": 948249091929588017, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/x448.py": 3960540415600165213, - "venv/lib/python3.13/site-packages/fastapi/background.py": 16533963020573865222, - "venv/lib/python3.13/site-packages/numpy/lib/_index_tricks_impl.py": 13574106461973044500, - "venv/lib/python3.13/site-packages/rpds/__init__.pyi": 12037474523494903587, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/styles/__init__.py": 9482393721453335937, - "venv/lib/python3.13/site-packages/pandas/_libs/algos.cpython-313-x86_64-linux-gnu.so": 15706331654215762588, - "venv/lib/python3.13/site-packages/fastapi/security/utils.py": 2616633862993539558, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/flatiter.pyi": 6885824496927786205, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/routines/subrout.pyf": 4660465266594480405, - "venv/lib/python3.13/site-packages/itsdangerous/_json.py": 4872267972688724005, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_replace.py": 4953527309376861139, - "venv/lib/python3.13/site-packages/pygments/styles/borland.py": 17570558758932580659, - "venv/lib/python3.13/site-packages/PIL/ImageDraw2.py": 13610162107593278891, - "venv/lib/python3.13/site-packages/pandas/tests/io/xml/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/starlette/_exception_handler.py": 9892172656847200124, - "venv/lib/python3.13/site-packages/numpy/polynomial/chebyshev.pyi": 5269136485429780038, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/__init__.py": 371829636800613137, - "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/__main__.py": 11917862648584782420, - "venv/lib/python3.13/site-packages/PIL/FpxImagePlugin.py": 18245056799205041866, - "venv/lib/python3.13/site-packages/packaging/version.py": 13470993734108007779, - "frontend/build/_app/immutable/chunks/ChLJ80AE.js": 8890526053620586309, - "frontend/build/_app/immutable/chunks/CM6FoQ_S.js": 4999908718789214708, - "venv/lib/python3.13/site-packages/numpy/fft/tests/test_pocketfft.py": 18025182347224285050, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/gh25337/data.f90": 13833561828029901615, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_round.py": 1299086932398824299, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/formatters/__init__.py": 3247870839323520754, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_string.py": 10141066226714805009, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/dtype_api.h": 17040779421165903019, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/progress.py": 5951745251426856398, - "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/WHEEL": 9100692507274722091, - "venv/lib/python3.13/site-packages/numpy/ma/tests/test_arrayobject.py": 9578555381494297966, - "venv/lib/python3.13/site-packages/numpy/f2py/__init__.pyi": 3566887042414273892, - "venv/lib/python3.13/site-packages/pandas/core/arrays/sparse/array.py": 3517673819082574078, - "venv/lib/python3.13/site-packages/pygments/styles/coffee.py": 17584414468786822371, - "venv/lib/python3.13/site-packages/pygments/lexers/json5.py": 9736695186548899403, - "venv/lib/python3.13/site-packages/packaging/licenses/_spdx.py": 16440031845441362300, - "backend/src/api/routes/settings.py": 1899503837234642538, - "backend/src/services/dataset_review/clarification_engine.py": 13640221555439415988, - "venv/lib/python3.13/site-packages/fastapi/security/http.py": 8465565118555441408, - "venv/lib/python3.13/site-packages/apscheduler/schedulers/gevent.py": 4811840397266785551, - "venv/lib/python3.13/site-packages/fastapi/middleware/asyncexitstack.py": 7733356903092860495, - "frontend/src/routes/translate/dictionaries/[id]/+page.svelte": 14484918248250087235, - "venv/lib/python3.13/site-packages/secretstorage/defines.py": 9590959702075554048, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_kurt.py": 2898715045429898166, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/conftest.py": 12368472226536104037, - "backend/src/services/clean_release/__tests__/test_compliance_orchestrator.py": 6332087444349093252, - "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/WHEEL": 11630459739183915695, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh23533.f": 12558972205518833024, - "venv/lib/python3.13/site-packages/_pytest/reports.py": 13930709338396699351, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_series.py": 16418555817529711079, - "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/RECORD": 1689342214025776630, - "venv/lib/python3.13/site-packages/itsdangerous/url_safe.py": 13454753900702274266, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_real.f90": 9097998998863007705, - "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/licenses/LICENSE": 3996324383113221529, - "venv/lib/python3.13/site-packages/pandas/core/indexes/extension.py": 7193879749426425951, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/path_registry.py": 8410829659513707067, - "venv/lib/python3.13/site-packages/pygments/unistring.py": 18037463865539157041, - "venv/lib/python3.13/site-packages/fastapi/param_functions.py": 14585101566697773072, - "venv/lib/python3.13/site-packages/numpy/_core/memmap.pyi": 14124415711399771715, - "venv/lib/python3.13/site-packages/pip/_vendor/packaging/markers.py": 5247208668583898949, - "venv/lib/python3.13/site-packages/pandas/tests/computation/test_compat.py": 11655000938111420543, - "venv/lib/python3.13/site-packages/pandas/io/excel/_odfreader.py": 2760916559416783928, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/box.py": 14303526978791498662, - "backend/src/core/encryption_key.py": 10697135200011385036, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/scalar_string.f90": 15018631706178918578, - "backend/src/api/routes/translate/_run_list_routes.py": 13032962834082893523, - "backend/src/services/clean_release/audit_service.py": 9534298777117548502, - "frontend/build/_app/immutable/nodes/8.CoZYS_r2.js": 15980650324428132567, - "frontend/build/_app/immutable/chunks/ClTV31tE.js": 9373217372896609602, - "venv/lib/python3.13/site-packages/pyasn1/type/opentype.py": 340146737126677655, - "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/errors.py": 12935154705443176852, - "venv/lib/python3.13/site-packages/pygments/lexers/carbon.py": 6753624244809529841, - "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/_implementation.py": 12245524932757110911, - "venv/lib/python3.13/site-packages/numpy/fft/_helper.py": 15906444100774706395, - "venv/lib/python3.13/site-packages/sqlalchemy/util/compat.py": 16148553252010089561, - "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/licenses/AUTHORS": 2987771679926243782, - "frontend/build/_app/immutable/nodes/27.COAKd8S0.js": 18157514999440870259, - "venv/lib/python3.13/site-packages/pip/_internal/utils/filesystem.py": 7716285033598020316, - "backend/src/core/superset_client/_datasets_preview_filters.py": 12835417730902013107, - "venv/lib/python3.13/site-packages/pip/_internal/commands/inspect.py": 1401259241736437656, - "venv/lib/python3.13/site-packages/passlib/crypto/scrypt/__init__.py": 4390908730288159455, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_cpu_dispatcher.py": 2063037275809439611, - "venv/lib/python3.13/site-packages/dotenv/variables.py": 5438726379749803751, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_highlight.py": 7573043358244876807, - "venv/lib/python3.13/site-packages/pip/_vendor/packaging/__init__.py": 96341051676048910, - "venv/lib/python3.13/site-packages/pandas/core/indexes/datetimes.py": 14331984919364185787, - "venv/lib/python3.13/site-packages/pygments/formatters/_mapping.py": 13335227913146542481, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi": 10784666243744187693, - "venv/lib/python3.13/site-packages/numpy/_core/records.py": 11414828908088050950, - "backend/src/models/storage.py": 1218824901001897736, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/request.py": 10484280068366411541, - "venv/lib/python3.13/site-packages/pydantic/v1/decorator.py": 6124748023704700724, - "venv/lib/python3.13/site-packages/numpy/lib/_utils_impl.pyi": 15767546107856827543, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/multiarray.pyi": 6368268452184570195, - "venv/lib/python3.13/site-packages/pandas/tests/io/test_orc.py": 1248059610437937895, - "venv/lib/python3.13/site-packages/click/testing.py": 15973659312284678327, - "venv/lib/python3.13/site-packages/pip/_vendor/packaging/utils.py": 9959199071030996679, - "venv/lib/python3.13/site-packages/pydantic/decorator.py": 6984214881365537811, - "venv/lib/python3.13/site-packages/numpy/core/_utils.py": 14108063453670701289, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_dst.py": 12243642467695371088, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_array.py": 16867692337986161626, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/exceptions.pyi": 9294219058621261971, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_records.py": 6252761812228230408, - "venv/lib/python3.13/site-packages/pandas/tests/series/test_logical_ops.py": 4438104524064299182, - "venv/lib/python3.13/site-packages/pycparser/plyparser.py": 5251740466238035035, - "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/METADATA": 15658158392301945427, - "frontend/src/services/toolsService.js": 1568142461283466080, - "venv/lib/python3.13/site-packages/pip/_internal/locations/_sysconfig.py": 4773855595767526182, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/test_cython.py": 2933400021016349431, - "venv/lib/python3.13/site-packages/numpy/_core/multiarray.pyi": 3494871767602648807, - "venv/lib/python3.13/site-packages/PIL/TarIO.py": 13651401276968618561, - "venv/lib/python3.13/site-packages/pygments/lexers/tablegen.py": 2917626373516779857, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/palette.py": 17383863392192572184, - "backend/src/scripts/seed_permissions.py": 12022710984424584961, - "backend/alembic/script.py.mako": 7041141123739810216, - "venv/lib/python3.13/site-packages/rsa/parallel.py": 4968566722541778371, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/Indel.pyi": 16372699564794732463, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/dtypes.pyi": 15114028503984522176, - "venv/lib/python3.13/site-packages/pygments/lexers/ruby.py": 6898093948224302592, - "backend/src/plugins/translate/__tests__/__init__.py": 2490542523242946173, - "frontend/build/_app/immutable/chunks/B9Q3NV6S.js": 302719787108962938, - "venv/lib/python3.13/site-packages/rsa/cli.py": 1753949198467694190, - "venv/lib/python3.13/site-packages/passlib/handlers/mysql.py": 11165762635383041460, - "venv/lib/python3.13/site-packages/pandas/core/arrays/base.py": 664515424699746697, - "venv/lib/python3.13/site-packages/PIL/TgaImagePlugin.py": 9208942494595222259, - "venv/lib/python3.13/site-packages/pydantic/env_settings.py": 18250976255197243083, - "venv/lib/python3.13/site-packages/pandas/tests/io/test_http_headers.py": 13187746870209705951, - "venv/lib/python3.13/site-packages/pydantic/plugin/_loader.py": 792663962985957671, - "venv/lib/python3.13/site-packages/numpy/random/_philox.pyi": 7503018432880404291, - "venv/lib/python3.13/site-packages/passlib/tests/test_utils.py": 10362977406431569031, - "venv/lib/python3.13/site-packages/cryptography/hazmat/backends/openssl/__init__.py": 4870269250323682576, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pygments/styles/default.py": 13992125975366109635, - "venv/lib/python3.13/site-packages/pandas/io/formats/_color_data.py": 15614976586613738953, - "frontend/src/components/git/__tests__/git_manager.unfinished_merge.integration.test.js": 2437475749409257490, - "backend/src/core/superset_client/_user_projection.py": 16484323195475306883, - "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/RECORD": 5169907629260560698, - "backend/src/models/dashboard.py": 8479838979214366697, - "venv/lib/python3.13/site-packages/numpy/rec/__init__.py": 7467092880535460658, - "venv/lib/python3.13/site-packages/_pytest/recwarn.py": 15312759837838083596, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_mixed.py": 3476101699679108025, - "venv/lib/python3.13/site-packages/pandas/core/arrays/sparse/scipy_sparse.py": 2091608752719976909, - "venv/lib/python3.13/site-packages/pandas/tests/generic/test_label_or_level_utils.py": 3423644585913150841, - "venv/bin/dotenv": 953953349803507198, - "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/WHEEL": 2357997949040430835, - "venv/lib/python3.13/site-packages/keyring/completion.py": 1027436016070040568, - "venv/lib/python3.13/site-packages/dateutil/_common.py": 12492546559232079071, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/index_tricks.pyi": 6035507586990711471, - "venv/lib/python3.13/site-packages/pandas/core/util/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/base_key.py": 10402800587070352851, - "venv/lib/python3.13/site-packages/pydantic/error_wrappers.py": 11273827025986230629, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/f77fixedform.f95": 10898637805043867370, - "venv/lib/python3.13/site-packages/pandas/_libs/byteswap.cpython-313-x86_64-linux-gnu.so": 17856848989827220388, - "venv/lib/python3.13/site-packages/pandas/io/xml.py": 326466573926392764, - "venv/lib/python3.13/site-packages/fastapi/_compat/model_field.py": 392699021682253569, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_equals.py": 11041884432990762650, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ndarray_conversion.pyi": 11580106670226366710, - "venv/lib/python3.13/site-packages/pytest_asyncio/__init__.py": 8162213292669110211, - "venv/lib/python3.13/site-packages/pip/_vendor/requests/packages.py": 11689856177725665974, - "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_ssl_constants.py": 14834514243239777933, - "venv/lib/python3.13/site-packages/jsonschema/tests/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pluggy/_tracing.py": 7276210024011809655, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7591/errors.py": 17581857895562494222, - "venv/lib/python3.13/site-packages/fastapi/staticfiles.py": 4094330072433302614, - "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/RECORD": 7266315886702289726, - "venv/lib/python3.13/site-packages/pandas/core/internals/__init__.py": 1377108808392195313, - "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_to_offset.py": 3929599794655343911, - "venv/lib/python3.13/site-packages/httpcore/_utils.py": 3255581092836273826, - "venv/lib/python3.13/site-packages/pandas/_libs/pandas_parser.cpython-313-x86_64-linux-gnu.so": 18056339336364727359, - "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/WHEEL": 691462085217888236, - "venv/lib/python3.13/site-packages/pygments/lexers/ambient.py": 18106929781201758080, - "venv/lib/python3.13/site-packages/pygments/lexers/teraterm.py": 16132676290138105984, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/lib_utils.py": 4612923732868929770, - "venv/lib/python3.13/site-packages/pygments/lexers/sophia.py": 15971500155124949058, - "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/WHEEL": 18203500019759199992, - "venv/bin/pip3": 13861749540792881808, - "venv/lib/python3.13/site-packages/pygments/lexers/x10.py": 6167378515780115912, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7662/models.py": 11521700876708601977, - "frontend/src/routes/tools/backups/+page.svelte": 6796050751535238723, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/OSA.py": 17817123894903120316, - "venv/lib/python3.13/site-packages/pip/_vendor/tomli/_re.py": 1296579393600719224, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_partial_slicing.py": 16219611534574666182, - "venv/lib/python3.13/site-packages/pandas/tests/tools/test_to_datetime.py": 3499461736474530062, - "venv/lib/python3.13/site-packages/pandas/tests/strings/test_get_dummies.py": 14871264482622327003, - "venv/lib/python3.13/site-packages/pygments/lexers/_postgres_builtins.py": 2383906454995727700, - "venv/lib/python3.13/site-packages/jeepney/low_level.py": 6546206679858571608, - "venv/lib/python3.13/site-packages/typing_extensions.py": 8402965285733247527, - "venv/lib/python3.13/site-packages/_pytest/mark/expression.py": 1821437025841201912, - "venv/lib/python3.13/site-packages/pandas/core/apply.py": 17080038932032802984, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_matplotlib.py": 12775850858284584296, - "frontend/src/assets/svelte.svg": 13872699371039797074, - "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/WHEEL": 9131187629260560775, - "venv/lib/python3.13/site-packages/smmap/mman.py": 9091562788592406032, - "venv/lib/python3.13/site-packages/pandas/tests/extension/decimal/array.py": 1919242530821725197, - "venv/lib/python3.13/site-packages/pandas/io/formats/templates/latex_longtable.tpl": 12723621983797415444, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/dml.py": 6567627855667533645, - "venv/lib/python3.13/site-packages/PIL/ImtImagePlugin.py": 17599267755504817169, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/__init__.py": 8093984834068317399, - "venv/lib/python3.13/site-packages/passlib/handlers/fshp.py": 13298827601291507295, - "frontend/build/_app/immutable/nodes/15.pFIXscWy.js": 13476852226803725758, - "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/RECORD": 11604408378998955169, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_apply.py": 11248068903302454630, - "backend/src/models/filter_state.py": 6470311179852241297, - "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py3-objarr.npz": 12369168483236619421, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/proxy.py": 13008557041076030198, - "venv/lib/python3.13/site-packages/jsonschema/exceptions.py": 15651767069704734674, - "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/licenses/LICENSE": 17284252174641192866, - "venv/lib/python3.13/site-packages/dotenv/main.py": 7408889670575271484, - "backend/src/api/routes/__tests__/test_git_status_route.py": 6306531435114264696, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_size.py": 8527839563560550806, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_boxplot_method.py": 7635131059308651529, - "venv/lib/python3.13/site-packages/numpy/f2py/cfuncs.pyi": 8232620851756907417, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_integer/foo90.f90": 3492659529812762861, - "venv/lib/python3.13/site-packages/pandas/io/excel/__init__.py": 6662687963241471393, - "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/licenses/LICENSE": 14524289631770661180, - "venv/lib/python3.13/site-packages/itsdangerous/exc.py": 11181421963755661477, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/constrain.py": 6513876973118703677, - "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py2-objarr.npz": 9481735723557962988, - "venv/lib/python3.13/site-packages/rsa/pem.py": 3118524021576082054, - "frontend/src/routes/dashboards/[id]/components/DashboardTaskHistory.svelte": 8800115118935646769, - "venv/lib/python3.13/site-packages/pydantic/_internal/_serializers.py": 12077180322353709930, - "backend/src/core/superset_client/_databases.py": 14837101840847724937, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_repeat.py": 11360772447747837958, - "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/WHEEL": 18203500019759199992, - "venv/lib/python3.13/site-packages/numpy/tests/test_scripts.py": 5790352482583964348, - "venv/lib/python3.13/site-packages/jose/backends/rsa_backend.py": 13507186353881931758, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/JaroWinkler.pyi": 9003794318682878317, - "venv/lib/python3.13/site-packages/git/objects/submodule/base.py": 10140490301897269395, - "venv/lib/python3.13/site-packages/fastapi/exception_handlers.py": 9907950997607808699, - "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/exceptions.py": 2873060848310644552, - "venv/lib/python3.13/site-packages/pandas/tests/base/test_transpose.py": 1686867045869336370, - "venv/lib/python3.13/site-packages/click/formatting.py": 6694583529073729642, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/linalg.pyi": 7217817172953767893, - "backend/src/core/utils/dataset_mapper.py": 13413818977924738147, - "venv/lib/python3.13/site-packages/git/remote.py": 1694919255653049944, - "venv/lib/python3.13/site-packages/cffi/commontypes.py": 11198107299826138465, - "venv/lib/python3.13/site-packages/pydantic_settings/__init__.py": 4374954204580208673, - "venv/lib/python3.13/site-packages/numpy/ma/extras.py": 7559838309481824664, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_array_from_pyobj.py": 9596224861290975079, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_intervalindex.py": 5053113227747333759, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_strings.py": 7168544888340296373, - "venv/lib/python3.13/site-packages/PIL/report.py": 9428754440615681790, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/plugin/bootstrap.py": 3865947239497500815, - "frontend/build/_app/immutable/nodes/9.CpD5O4dB.js": 2507508435328749555, - "venv/lib/python3.13/site-packages/pandas/_libs/testing.cpython-313-x86_64-linux-gnu.so": 16758333404587340103, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/auth.py": 13542332344403032059, - "venv/lib/python3.13/site-packages/_pytest/warning_types.py": 10695097290648045427, - "venv/lib/python3.13/site-packages/h11/__init__.py": 222801976520197308, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7009/revocation.py": 16178499278312777474, - "venv/lib/python3.13/site-packages/authlib/oauth1/__init__.py": 3692257288065292607, - "venv/lib/python3.13/site-packages/pandas/_libs/index.cpython-313-x86_64-linux-gnu.so": 18409579812171549318, - "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/RECORD": 8971487317739420905, - "venv/lib/python3.13/site-packages/pandas/tests/test_downstream.py": 5635510753354256507, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_custom_business_day.py": 2200008998040663785, - "venv/lib/python3.13/site-packages/pygments/lexers/pointless.py": 17552020039609007881, - "frontend/src/lib/components/translate/TranslationPreview.svelte": 15144385993961969187, - "venv/lib/python3.13/site-packages/authlib/oidc/discovery/__init__.py": 308178910015974550, - "venv/lib/python3.13/site-packages/pyasn1/type/__init__.py": 15728752901274520502, - "venv/lib/python3.13/site-packages/pandas/tests/window/test_online.py": 11850497659869773510, - "venv/lib/python3.13/site-packages/ecdsa/ecdsa.py": 9770689913380927623, - "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/zip-safe": 15240312484046875203, - "venv/lib/python3.13/site-packages/numpy/testing/_private/utils.pyi": 17639497083041129225, - "venv/lib/python3.13/site-packages/numpy/lib/__init__.pyi": 1537495515469182226, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py": 15060063324909302240, - "venv/lib/python3.13/site-packages/pygments/lexers/fantom.py": 1986459352773446836, - "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/f2py/crackfortran.pyi": 9206355685192026844, - "venv/lib/python3.13/site-packages/pandas/_config/__init__.py": 3577026529387563519, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_sample.py": 16877779557071324115, - "venv/lib/python3.13/site-packages/pip/_internal/utils/datetime.py": 6816292030061301011, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/numeric.py": 14451517189908259173, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/console.py": 10217327186846649646, - "venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/METADATA": 732041908491732594, - "venv/lib/python3.13/site-packages/pandas/io/stata.py": 14370692318835340323, - "venv/lib/python3.13/site-packages/gitdb/test/test_util.py": 541144638852210407, - "venv/lib/python3.13/site-packages/PIL/PalmImagePlugin.py": 13008868719182630239, - "venv/lib/python3.13/site-packages/pandas/api/executors/__init__.py": 16954693181142010028, - "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/licenses/LICENSE": 13479831069780783137, - "frontend/src/components/tools/DebugTool.svelte": 17267560034225794881, - "venv/lib/python3.13/site-packages/apscheduler/triggers/base.py": 1170652622104554892, - "venv/lib/python3.13/site-packages/websockets/asyncio/connection.py": 17044409627448400723, - "venv/lib/python3.13/site-packages/pyasn1/type/tagmap.py": 14075859042659927673, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/strptime.pyi": 5973671421648618563, - "venv/lib/python3.13/site-packages/git/objects/util.py": 691018806932355307, - "venv/lib/python3.13/site-packages/jeepney/auth.py": 10565040329507087892, - "venv/lib/python3.13/site-packages/pygments/lexers/pony.py": 2720635393743617141, - "venv/lib/python3.13/site-packages/pandas/core/internals/concat.py": 12151675567885981464, - "venv/lib/python3.13/site-packages/pip/_vendor/packaging/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_vendor/distlib/database.py": 7111764828004587758, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/poly1305.py": 10854598965202354516, - "venv/lib/python3.13/site-packages/numpy/lib/_nanfunctions_impl.pyi": 12566839271245057531, - "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_meson.py": 5735043585893007971, - "venv/lib/python3.13/site-packages/pandas/tests/extension/list/__init__.py": 10072943986583771248, - "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/__init__.py": 12290228927283601067, - "venv/lib/python3.13/site-packages/PIL/_imagingft.pyi": 1385456134120145584, - "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/fetch.py": 13937019222549208796, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/connectionpool.py": 10453724680327835821, - "venv/lib/python3.13/site-packages/numpy/_typing/_extended_precision.py": 4201820494689784136, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/ed448.pyi": 13016654355866474644, - "venv/lib/python3.13/site-packages/numpy/_core/function_base.pyi": 8343632640078378312, - "frontend/src/routes/migration/mappings/+page.svelte": 4566398049366943407, - "venv/lib/python3.13/site-packages/dateutil/tz/tz.py": 5258008267965780817, - "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/licenses/LICENSE.APACHE": 11041304845352917971, - "frontend/src/routes/datasets/+page.svelte": 18132315883450880052, - "venv/lib/python3.13/site-packages/py.py": 16248211404003181569, - "frontend/build/_app/immutable/chunks/ByztTpgj.js": 4913577152951971044, - "venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/RECORD": 173225030102092319, - "venv/lib/python3.13/site-packages/pip/_internal/build_env.py": 3614358934066127900, - "venv/lib/python3.13/site-packages/pandas/core/shared_docs.py": 2173578869755325502, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_real/foo90.f90": 58572216018544419, - "venv/lib/python3.13/site-packages/_pytest/terminalprogress.py": 5490989904517343259, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_half.py": 3121836756584726126, - "backend/src/api/routes/dataset_review_pkg/_routes.py": 11040245149296528009, - "venv/lib/python3.13/site-packages/numpy/f2py/func2subr.py": 338595621218646492, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_timezones.py": 4771674179164304731, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/aiomysql.py": 12999962380333482189, - "frontend/src/lib/components/layout/Breadcrumbs.svelte": 15202032505744987943, - "venv/lib/python3.13/site-packages/numpy/core/_internal.py": 14816989375912210674, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_formats.py": 17821648708413143557, - "venv/lib/python3.13/site-packages/pandas/_libs/ops.pyi": 1192312467209548763, - "venv/lib/python3.13/site-packages/jose/jwk.py": 2781217726458801910, - "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/core/indexes/frozen.py": 1419685664276640120, - "venv/lib/python3.13/site-packages/httpcore/_sync/http2.py": 11167798787131917524, - "venv/lib/python3.13/site-packages/greenlet/greenlet_refs.hpp": 8525862687669040510, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_pyf_src.py": 12351476647369971852, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_select.py": 7083040959665006634, - "venv/lib/python3.13/site-packages/PIL/PdfImagePlugin.py": 16082854250442815862, - "venv/lib/python3.13/site-packages/pygments/lexers/xorg.py": 14591144191879110061, - "venv/lib/python3.13/site-packages/pygments/lexers/asm.py": 13861952972248758785, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7662/introspection.py": 14645217065508644154, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_shift.py": 8547819448301023303, - "venv/lib/python3.13/site-packages/pandas/core/dtypes/api.py": 9829629144629841277, - "venv/lib/python3.13/site-packages/uvicorn/protocols/http/flow_control.py": 4822804840057360506, - "venv/lib/python3.13/site-packages/anyio/streams/tls.py": 4191898645554875562, - "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_distutils.pyi": 3595910367556664837, - "venv/lib/python3.13/site-packages/_pytest/freeze_support.py": 494952714451267295, - "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/_arrow_utils.py": 17808805047762566525, - "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/hybrid.py": 14287665090144592501, - "venv/lib/python3.13/site-packages/numpy/random/tests/data/philox-testset-1.csv": 2202360898679162333, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_setops.py": 14246225281428284850, - "venv/lib/python3.13/site-packages/referencing/tests/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_month.py": 8485374160446988786, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/twodim_base.pyi": 3773329770170248877, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_indexing.py": 6539365174681852769, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_info.py": 15151894356374015812, - "venv/lib/python3.13/site-packages/urllib3/util/__init__.py": 2848870790459558599, - "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/RECORD": 6488682447051657004, - "venv/lib/python3.13/site-packages/pandas/io/formats/templates/html_table.tpl": 17198355067645888735, - "venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/METADATA": 8128818962678047497, - "venv/lib/python3.13/site-packages/idna-3.11.dist-info/WHEEL": 8600534672961461758, - "venv/lib/python3.13/site-packages/gitdb/stream.py": 3035738824550231197, - "venv/lib/python3.13/site-packages/pandas/io/sql.py": 12592024569011796790, - "venv/lib/python3.13/site-packages/numpy/random/tests/test_randomstate_regression.py": 17425202198134409689, - "venv/lib/python3.13/site-packages/pygments/lexers/sieve.py": 15757825442941567629, - "venv/lib/python3.13/site-packages/pygments/__init__.py": 14493583771211110135, - "venv/lib/python3.13/site-packages/numpy/dtypes.py": 14128421398870718692, - "venv/lib/python3.13/site-packages/_pytest/capture.py": 17850967053989495422, - "venv/lib/python3.13/site-packages/authlib/oidc/core/models.py": 1370998944213578392, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arithmetic.pyi": 467927803068643024, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_defchararray.py": 15135904718007443306, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_dtype.py": 5336980126536664360, - "frontend/build/_app/immutable/nodes/37.ztsr65__.js": 622371390299823461, - "venv/lib/python3.13/site-packages/pydantic/_internal/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/greenlet/tests/test_greenlet_trash.py": 6191655521667576604, - "venv/lib/python3.13/site-packages/pandas/core/internals/managers.py": 13547912653290063698, - "venv/lib/python3.13/site-packages/jeepney/bus_messages.py": 5871341372541525842, - "venv/lib/python3.13/site-packages/pydantic/v1/main.py": 213087273729911492, - "venv/lib/python3.13/site-packages/rapidfuzz/utils_py.py": 12341806772632276946, - "venv/lib/python3.13/site-packages/pip/_internal/metadata/__init__.py": 8924316361489544973, - "venv/lib/python3.13/site-packages/passlib/crypto/_blowfish/_gen_files.py": 6273314671315377131, - "frontend/src/routes/translate/dictionaries/+page.svelte": 11204836397236633754, - "venv/lib/python3.13/site-packages/numpy/random/tests/test_random.py": 4179188367630060654, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/selectable.py": 14646717349365560549, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/period/test_period.py": 12593777226419608212, - "venv/lib/python3.13/site-packages/numpy/random/mtrand.pyi": 17144590106028661128, - "venv/lib/python3.13/site-packages/numpy/_core/_add_newdocs.py": 15657897994221955882, - "venv/lib/python3.13/site-packages/pandas/_libs/testing.pyi": 16691791330088523786, - "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_construct_from_scalar.py": 16520136036631155842, - "venv/bin/pytest": 2593802493707545818, - "venv/lib/python3.13/site-packages/keyring/backends/kwallet.py": 3071915635647280308, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/hmac.py": 18132740541139891824, - "venv/lib/python3.13/site-packages/h11/_util.py": 9362339074207904329, - "venv/lib/python3.13/site-packages/websockets/frames.py": 4901850477414613953, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/authorization_server.py": 2491654903543600678, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/securetransport.py": 12104888897121018676, - "venv/lib/python3.13/site-packages/pandas/core/base.py": 10262717073058743378, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_period.py": 9715843209581883915, - "backend/src/api/routes/__tests__/test_git_api.py": 43259826036955162, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/enumerated.py": 16623643153933348755, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_multithreading.py": 12547048606098186681, - "backend/tests/test_core_scheduler.py": 6589618269087393661, - "venv/lib/python3.13/site-packages/git/objects/tag.py": 7954808535585493300, - "venv/lib/python3.13/site-packages/itsdangerous/encoding.py": 205863946173486958, - "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/dtypes/test_empty.py": 6845813091876023610, - "backend/src/services/clean_release/candidate_service.py": 14044982155441302890, - "backend/src/services/clean_release/repositories/report_repository.py": 17952038790457725175, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_groupby_shift_diff.py": 1210657479716368827, - "venv/lib/python3.13/site-packages/rapidfuzz/process_cpp_impl.cpython-313-x86_64-linux-gnu.so": 11767771662042404251, - "venv/lib/python3.13/site-packages/pydantic/functional_serializers.py": 15285359935059345032, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90": 8079594129222364031, - "venv/lib/python3.13/site-packages/pandas/tests/io/test_spss.py": 4865360315909532603, - "venv/lib/python3.13/site-packages/numpy/f2py/use_rules.py": 17277594393032382485, - "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/WHEEL": 16097436423493754389, - "venv/lib/python3.13/site-packages/fastapi/params.py": 14263655860695381481, - "venv/lib/python3.13/site-packages/numpy/random/tests/test_randomstate.py": 11205714006000849926, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh17797.f90": 17319074662077763768, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_timestamp_method.py": 11393911418463808195, - "venv/lib/python3.13/site-packages/pandas/core/window/common.py": 17956497339875932377, - "frontend/src/lib/api/datasetReview.js": 3023829599261929428, - "frontend/build/_app/immutable/chunks/Bu8doFLC.js": 13169888001190175706, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_quantile.py": 17110581927381599978, - "venv/lib/python3.13/site-packages/passlib/tests/test_ext_django_source.py": 15577951591316518967, - "venv/lib/python3.13/site-packages/anyio/_core/_testing.py": 14024940365851109155, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_c_parser_only.py": 3038797485572319804, - "venv/lib/python3.13/site-packages/uvicorn/protocols/http/httptools_impl.py": 10367325397209016951, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/styles/_mapping.py": 11752660241391232497, - "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/_toml_compat.py": 10196543528439925412, - "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/unix.py": 13808187640638677050, - "venv/lib/python3.13/site-packages/requests/hooks.py": 9888227370911151341, - "venv/lib/python3.13/site-packages/pygments/lexers/supercollider.py": 15306357945850389082, - "backend/src/api/routes/git/_helpers.py": 6888678759460652166, - "frontend/tailwind.config.js": 13139381085024634801, - "venv/lib/python3.13/site-packages/pygments/lexers/matlab.py": 1880915927722177654, - "venv/lib/python3.13/site-packages/pandas/tests/computation/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_core_functionalities.py": 10449747865888948579, - "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libldap-2974a1ba.so.2.0.200": 13590569080612602445, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_droplevel.py": 2071197388394658690, - "frontend/src/lib/ui/index.ts": 6883965364006817450, - "venv/lib/python3.13/site-packages/numpy/f2py/symbolic.py": 16854377502491291093, - "venv/lib/python3.13/site-packages/pycparser/ply/ctokens.py": 1599952198962458730, - "backend/tests/test_auth.py": 6167020718035755646, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_array.py": 12514884344165043136, - "venv/lib/python3.13/site-packages/numpy/strings/__init__.py": 6523674574341354095, - "venv/lib/python3.13/site-packages/pygments/styles/gh_dark.py": 7717523746712391809, - "venv/lib/python3.13/site-packages/pygments/lexers/lean.py": 14518351619544450286, - "venv/lib/python3.13/site-packages/gitdb/db/mem.py": 15823812455996199993, - "venv/lib/python3.13/site-packages/pandas/core/tools/times.py": 6560679305255812809, - "venv/lib/python3.13/site-packages/multipart/decoders.py": 11346752866822986212, - "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_chebyshev.py": 8054411443686791426, - "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth1/resource_protector.py": 17080006010679257864, - "venv/lib/python3.13/site-packages/pygments/formatters/img.py": 18230180171537565208, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arraypad.pyi": 12178766981280242620, - "venv/lib/python3.13/site-packages/greenlet/greenlet_cpython_compat.hpp": 8396413256279803400, - "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/cli.py": 6382193953727339271, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_join.py": 17508073052750406350, - "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/METADATA": 4954909612926293404, - "venv/lib/python3.13/site-packages/click/__init__.py": 9261629899056870564, - "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_laguerre.py": 7475592201750602042, - "venv/lib/python3.13/site-packages/fastapi/_compat/v2.py": 15078491685917047095, - "venv/lib/python3.13/site-packages/rsa/pkcs1_v2.py": 3533398238491175229, - "venv/lib/python3.13/site-packages/pip/_vendor/pkg_resources/__init__.py": 1677532855362260338, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_simd.py": 7577408467041941595, - "venv/lib/python3.13/site-packages/pandas/tests/window/test_timeseries_window.py": 1973365560758236222, - "venv/lib/python3.13/site-packages/httpcore/_sync/connection_pool.py": 8159971229245441880, - "frontend/src/routes/datasets/[id]/+page.svelte": 3377235098319163133, - "venv/lib/python3.13/site-packages/numpy/fft/__init__.pyi": 10354990065626209946, - "scripts/scan_secrets.sh": 599173385111063848, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/util.py": 9373891872370603585, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_constructors.py": 12628643543371952431, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_data_list.py": 1131520422778420758, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_interval_tree.py": 15789443159423302291, - "venv/lib/python3.13/site-packages/psycopg2/extras.py": 7510107741729866600, - "venv/lib/python3.13/site-packages/pandas/tests/frame/test_unary.py": 2573825678342936734, - "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/jose/backends/native.py": 50023158618000658, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/declarative_asn1.pyi": 16934250836612138541, - "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/timeseries.py": 17641722582848932332, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_constructors.py": 2786493777737472376, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_ops.py": 14420421526781215500, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/strategy_options.py": 16342048970907383117, - "venv/lib/python3.13/site-packages/pycparser/c_generator.py": 14922277346364091122, - "frontend/src/lib/stores/__tests__/test_sidebar.js": 113566022614194798, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh23598.f90": 1409455010615482779, - "backend/src/services/clean_release/compliance_execution_service.py": 3379474749353250488, - "venv/lib/python3.13/site-packages/pandas/tests/tools/test_to_time.py": 10463741033950978270, - "venv/lib/python3.13/site-packages/_pytest/assertion/truncate.py": 14000392306994773741, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/nested_sequence.pyi": 10985533017688918283, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_join.py": 1131792466825856990, - "backend/src/services/dataset_review/orchestrator_pkg/_commands.py": 15474996500928063708, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_arraysetops.py": 10588903945244480732, - "venv/lib/python3.13/site-packages/attrs/__init__.py": 9502968706258875910, - "venv/bin/pyrsa-verify": 6762739642629904442, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_item_selection.py": 1027989019709029615, - "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/INSTALLER": 17282701611721059870, - "frontend/src/lib/components/translate/BulkReplaceModal.svelte": 8039616128453714824, - "venv/lib/python3.13/site-packages/numpy/lib/_arraysetops_impl.py": 5583478355093966990, - "venv/lib/python3.13/site-packages/requests/utils.py": 17045260098091371478, - "venv/lib/python3.13/site-packages/passlib/handlers/md5_crypt.py": 7669328623914474137, - "venv/lib/python3.13/site-packages/pandas/core/reshape/melt.py": 14109947554124551986, - "venv/lib/python3.13/site-packages/pandas/core/array_algos/replace.py": 1708865864686705833, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_matmul.py": 9323220618335072725, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_interval_pyarrow.py": 3849382723890414899, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/oct_key.py": 11504245602045724, - "venv/lib/python3.13/site-packages/pygments/lexers/ncl.py": 14838368780033177943, - "venv/lib/python3.13/site-packages/pydantic_settings/version.py": 17263591404988984480, - "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/LICENSE": 12064892310002036996, - "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/cython/meson.build": 9642189398934130247, - "venv/lib/python3.13/site-packages/greenlet/tests/test_greenlet.py": 10727595500186011102, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_append.py": 13152738905565588661, - "venv/lib/python3.13/site-packages/pygments/lexers/c_like.py": 13004061780700827047, - "venv/lib/python3.13/site-packages/pydantic/v1/color.py": 14545509649623975912, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_diff.py": 7420674239386436885, - "venv/lib/python3.13/site-packages/starlette/middleware/gzip.py": 4321371046149637632, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/cli/gh_22819.pyf": 14717748358749934995, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/dtypes/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_comparison.py": 5348781442514871089, - "venv/lib/python3.13/site-packages/pandas/core/computation/engines.py": 1889823242704769952, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_float.py": 10455718110956856820, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/__init__.py": 11526998905763262175, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_asfreq.py": 12721047184483392773, - "venv/lib/python3.13/site-packages/authlib/integrations/sqla_oauth2/tokens_mixins.py": 9923721909178724437, - "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py": 5995058808539530576, - "venv/lib/python3.13/site-packages/pandas/util/_decorators.py": 14780166101442507665, - "venv/lib/python3.13/site-packages/keyring/__init__.py": 991260689223167957, - "venv/lib/python3.13/site-packages/numpy/_core/defchararray.py": 15550230459945996915, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_convert_dtypes.py": 13612212066710266457, - "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libgssapi_krb5-497db0c6.so.2.2": 6199424505696679197, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/lib_utils.pyi": 12312677132342982866, - "venv/lib/python3.13/site-packages/numpy/polynomial/legendre.py": 1731362089136926666, - "venv/lib/python3.13/site-packages/pygments/lexers/phix.py": 16775285097768256238, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/jwe_encs.py": 9703572751543253904, - "venv/lib/python3.13/site-packages/pip/_vendor/idna/codec.py": 14814999235499530522, - "venv/lib/python3.13/site-packages/pandas/_libs/join.pyi": 369262334342439364, - "venv/lib/python3.13/site-packages/authlib/common/encoding.py": 52296066492753953, - "venv/lib/python3.13/site-packages/numpy/random/c_distributions.pxd": 16574161095720077595, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_chaining_and_caching.py": 15814259766479305290, - "venv/lib/python3.13/site-packages/numpy/_core/_type_aliases.py": 1644743742545329282, - "venv/lib/python3.13/site-packages/pandas/core/window/online.py": 13551140636252302201, - "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/WHEEL": 14550174241288068152, - "venv/lib/python3.13/site-packages/ecdsa/_compat.py": 13034064768731879065, - "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/oauth2_session.py": 7076806577412682835, - "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/licenses/LICENSE": 1641332741515411734, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/jwe_zips.py": 5184894018177148648, - "venv/lib/python3.13/site-packages/numpy/random/_philox.cpython-313-x86_64-linux-gnu.so": 9916143171057774705, - "venv/lib/python3.13/site-packages/pandas/tests/extension/date/array.py": 18073740473413382768, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-exp.csv": 601782991752922510, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_almost_equal.py": 9333355453468475330, - "venv/lib/python3.13/site-packages/sqlalchemy/util/langhelpers.py": 1246582552828542841, - "venv/lib/python3.13/site-packages/apscheduler/executors/__init__.py": 15130871412783076140, - "venv/bin/activate.fish": 5275961582873298085, - "backend/src/core/plugin_loader.py": 245217431000027879, - "venv/lib/python3.13/site-packages/h11/_version.py": 9334144031400715479, - "venv/lib/python3.13/site-packages/_pytest/pytester.py": 5423287282155948827, - "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/WHEEL": 16097436423493754389, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/routines/funcfortranname.pyf": 1361426175133186231, - "venv/lib/python3.13/site-packages/pandas/tests/extension/list/array.py": 8065856342131357421, - "backend/src/core/middleware/__init__.py": 13917394130915533209, - "venv/lib/python3.13/site-packages/PIL/ExifTags.py": 6869879826623916830, - "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/greenlet/greenlet_internal.hpp": 13173115501223013762, - "venv/lib/python3.13/site-packages/ecdsa/test_keys.py": 17117188373419689467, - "venv/lib/python3.13/site-packages/pandas/tseries/offsets.py": 13750652921710295115, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/base.py": 3250660921154829815, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/decl_api.py": 5287018911951723034, - "venv/lib/python3.13/site-packages/numpy/random/_pcg64.cpython-313-x86_64-linux-gnu.so": 5759445712745875888, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ndarray_shape_manipulation.py": 12598431412396627042, - "venv/lib/python3.13/site-packages/anyio/__init__.py": 12752386096259972231, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/warnings.py": 2552021607611112605, - "frontend/src/lib/components/reports/__tests__/reports_list.ux.test.js": 16252194679528846126, - "venv/lib/python3.13/site-packages/git/db.py": 6680123567509774609, - "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/setup.py": 5482352991573617756, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_antijoin.py": 14435396877404907826, - "venv/lib/python3.13/site-packages/pycparser/ply/yacc.py": 4218889705926129841, - "venv/lib/python3.13/site-packages/pandas/tests/base/common.py": 13335865314907577354, - "venv/lib/python3.13/site-packages/pandas/core/interchange/dataframe.py": 16525846817331842080, - "venv/lib/python3.13/site-packages/yaml/__init__.py": 11044333164208875121, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_compat.py": 11481259393140789881, - "venv/lib/python3.13/site-packages/tzlocal/windows_tz.py": 11696765495002954868, - "venv/lib/python3.13/site-packages/_pytest/assertion/__init__.py": 16392348866405910618, - "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/METADATA": 6960169108624303030, - "venv/lib/python3.13/site-packages/authlib/integrations/base_client/registry.py": 13306388361671753373, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_api.py": 1910541672533352625, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_dtypes.py": 7550022036887594386, - "venv/lib/python3.13/site-packages/pygments/style.py": 17393199235575070210, - "frontend/src/components/tools/ConnectionList.svelte": 15981533028345710336, - "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/validation": 13992741783834278677, - "venv/lib/python3.13/site-packages/numpy/ma/mrecords.pyi": 8945514863366384484, - "venv/lib/python3.13/site-packages/rapidfuzz/utils_cpp.cpython-313-x86_64-linux-gnu.so": 16145829319198889672, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/common/gh19161.f90": 7691871466158049079, - "venv/lib/python3.13/site-packages/pandas/_libs/indexing.pyi": 90995502095752726, - "venv/lib/python3.13/site-packages/pygments/lexers/wren.py": 6259586056260713984, - "venv/lib/python3.13/site-packages/attrs/__init__.pyi": 14353885498883901855, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/modeline.py": 6194365452131561478, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/evaluator.py": 6348022789899831255, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_comparison.py": 11333735187162513512, - "frontend/src/components/__tests__/task_log_viewer.test.js": 6512653335179659416, - "backend/src/core/auth/__init__.py": 16435384828055133073, - "venv/lib/python3.13/site-packages/rapidfuzz/fuzz.pyi": 7410507092040239447, - "venv/lib/python3.13/site-packages/sqlalchemy/util/_collections.py": 7772437080414835462, - "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/numpy/typing/__init__.py": 3608665862759745048, - "venv/lib/python3.13/site-packages/pandas/tseries/api.py": 14785127136180503704, - "backend/src/services/clean_release/__tests__/test_manifest_builder.py": 9320699981861675127, - "backend/alembic_test.db": 12608323163910954537, - "venv/lib/python3.13/site-packages/pandas/tests/frame/test_arithmetic.py": 17043958604607035425, - "venv/lib/python3.13/site-packages/idna/package_data.py": 6583909243002417298, - "venv/lib/python3.13/site-packages/pydantic/v1/json.py": 16596969681914729251, - "backend/tests/services/clean_release/test_compliance_task_integration.py": 682622548217611215, - "venv/lib/python3.13/site-packages/authlib/jose/__init__.py": 317573635113539563, - "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_dt_accessor.py": 2229616362327032253, - "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libssl-81ffa89e.so.3": 13913673119166658781, - "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/__init__.py": 1798074863773727377, - "venv/lib/python3.13/site-packages/pandas/tests/strings/test_find_replace.py": 262184394614748386, - "venv/lib/python3.13/site-packages/sqlalchemy/engine/strategies.py": 14007486769065345085, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_ratio.py": 940213488194452623, - "venv/lib/python3.13/site-packages/jose/__init__.py": 15575670403380555945, - "venv/lib/python3.13/site-packages/pandas/tests/interchange/test_spec_conformance.py": 16448324304809345527, - "venv/lib/python3.13/site-packages/pandas/tests/frame/test_npfuncs.py": 6132674295193898715, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_latex.py": 15077617224435782028, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_pickle.py": 3419420815386925630, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/dtype.pyi": 12178008080078679769, - "venv/lib/python3.13/site-packages/pyasn1/error.py": 11036037300994516747, - "venv/lib/python3.13/site-packages/dotenv/parser.py": 17651523026132242005, - "venv/lib/python3.13/site-packages/numpy/lib/_nanfunctions_impl.py": 11621577915097515056, - "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/resource_protector.py": 4823504113176750140, - "venv/lib/python3.13/site-packages/psycopg2/_ipaddress.py": 12332672835751787869, - "venv/lib/python3.13/site-packages/numpy/_core/_internal.py": 13056946834347643109, - "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_value_counts.py": 12340872812120847127, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_indexing.py": 16291207621268530224, - "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/__init__.py": 3619091571279924576, - "venv/lib/python3.13/site-packages/jeepney/io/tests/test_threading.py": 6656552495241857519, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_is_homogeneous_dtype.py": 15378147393056707851, - "venv/lib/python3.13/site-packages/_pytest/faulthandler.py": 13329320306353718649, - "venv/lib/python3.13/site-packages/pandas/tests/generic/test_duplicate_labels.py": 10663105616336167414, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_deprecations.py": 16124509063246256847, - "venv/lib/python3.13/site-packages/PIL/ImageQt.py": 6607270889359138659, - "venv/lib/python3.13/site-packages/pygments/lexers/ooc.py": 14540210212631538007, - "venv/lib/python3.13/site-packages/authlib/jose/drafts/_jwe_enc_cryptodome.py": 15753279711312689193, - "venv/lib/python3.13/site-packages/numpy/lib/_format_impl.py": 1809069379864985298, - "venv/lib/python3.13/site-packages/pandas/_libs/internals.pyi": 11662356720550765508, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_complex/foo90.f90": 15981076495193915107, - "venv/lib/python3.13/site-packages/PIL/PaletteFile.py": 4104323659569809769, - "venv/lib/python3.13/site-packages/cryptography/__about__.py": 10471312538528457144, - "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/__init__.py": 18036348770966744795, - "venv/lib/python3.13/site-packages/pygments/lexers/_lasso_builtins.py": 4006621424665751347, - "venv/lib/python3.13/site-packages/pygments/lexers/berry.py": 4540479522141160472, - "venv/lib/python3.13/site-packages/numpy/core/_dtype_ctypes.py": 17055498803745289016, - "venv/lib/python3.13/site-packages/httpcore/_backends/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/WHEEL": 16097436423493754389, - "frontend/src/lib/ui/Icon.svelte": 2201964532717139995, - "backend/src/api/routes/connections.py": 3871707738958709690, - "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/WHEEL": 7454950858448014158, - "venv/lib/python3.13/site-packages/numpy/tests/test_numpy_version.py": 849232015288488204, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_arithmetic.py": 4858019700859362660, - "venv/lib/python3.13/site-packages/authlib/__init__.py": 8957417237987377675, - "venv/lib/python3.13/site-packages/git/util.py": 7424113599506269603, - "backend/src/plugins/llm_analysis/service.py": 13348026269882094952, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/modes.py": 6832635056228445650, - "venv/lib/python3.13/site-packages/_pytest/_code/code.py": 5248836309618416369, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_numpy_compat.py": 9112925138440787555, - "frontend/src/components/Toast.svelte": 340258331315696736, - "venv/lib/python3.13/site-packages/pandas/_libs/indexing.cpython-313-x86_64-linux-gnu.so": 13188040757764159731, - "backend/src/core/utils/__init__.py": 12454773556575864508, - "venv/lib/python3.13/site-packages/pyasn1/type/error.py": 1479878696626082697, - "venv/lib/python3.13/site-packages/authlib/integrations/base_client/async_openid.py": 8708980645667847439, - "venv/lib/python3.13/site-packages/pip/_internal/models/direct_url.py": 4619204214785230341, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_x86_unix.h": 13709837360414450184, - "venv/lib/python3.13/site-packages/numpy/_core/__init__.py": 14951958843029076911, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7591/__init__.py": 348469143777130970, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_na_indexing.py": 8712547126522523899, - "venv/lib/python3.13/site-packages/pip/_vendor/typing_extensions.py": 10158933506062403688, - "venv/lib/python3.13/site-packages/pandas/api/types/__init__.py": 3995030354191071797, - "venv/lib/python3.13/site-packages/pandas/tests/io/test_feather.py": 13613400750755530364, - "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/METADATA": 1266134223155266488, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/Indel.py": 17112989332785349705, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/__init__.py": 11157967642611612522, - "venv/lib/python3.13/site-packages/numpy/random/bit_generator.pxd": 14261507718442469988, - "venv/lib/python3.13/site-packages/apscheduler/schedulers/__init__.py": 16211693040174992594, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_indexerrors.py": 4434868847540549873, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_indexing.py": 8943385096811168079, - "venv/lib/python3.13/site-packages/starlette/schemas.py": 697416731579555195, - "venv/lib/python3.13/site-packages/pydantic/_migration.py": 17982816821930887921, - "venv/lib/python3.13/site-packages/pandas/tests/frame/constructors/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_multi.py": 4612816468258071810, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/horizontal_shard.py": 17615732108308858890, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_clip.py": 13498704233745189154, - "venv/lib/python3.13/site-packages/httpcore/_backends/base.py": 5491727479625093183, - "venv/lib/python3.13/site-packages/pygments/lexers/_usd_builtins.py": 8671446144574174964, - "venv/bin/pyrsa-decrypt": 10929163076272054227, - "backend/src/core/async_superset_client.py": 17097960069181151584, - "venv/lib/python3.13/site-packages/PIL/ImImagePlugin.py": 15452956038794399492, - "venv/lib/python3.13/site-packages/pandas/tests/extension/json/array.py": 7437107031079833232, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/string_/test_string_arrow.py": 10008395772220468318, - "backend/src/services/clean_release/__tests__/test_audit_service.py": 1679130450221264383, - "backend/src/services/clean_release/stages/data_purity.py": 775548350590498835, - "backend/tests/scripts/test_clean_release_tui_v2.py": 16893299982170941753, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_index_new.py": 796607958391882182, - "venv/lib/python3.13/site-packages/gitdb/db/ref.py": 1176701624460337371, - "venv/lib/python3.13/site-packages/pip/_vendor/packaging/version.py": 5000350193835202949, - "venv/lib/python3.13/site-packages/pandas/_config/config.py": 1494288055210911451, - "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_ujson.py": 12184194085993665945, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_convert_dtypes.py": 5005259275646154894, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_character.py": 17168707712220699738, - "venv/lib/python3.13/site-packages/pygments/lexers/testing.py": 17148598391210353576, - "venv/lib/python3.13/site-packages/pandas/core/dtypes/inference.py": 2786441797589123900, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/__init__.py": 260774374497653876, - "venv/lib/python3.13/site-packages/keyring/backend_complete.zsh": 14339032329370660432, - "venv/lib/python3.13/site-packages/pandas/core/api.py": 3390809109543982410, - "venv/lib/python3.13/site-packages/pandas/tests/internals/test_api.py": 11217428888457119601, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/_orm_types.py": 5508682532707462217, - "backend/src/core/database.py": 7064138501006682572, - "venv/lib/python3.13/site-packages/rapidfuzz/_common_py.py": 15410157970973169427, - "venv/lib/python3.13/site-packages/pip/_internal/utils/subprocess.py": 3095012838116670328, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_loop.py": 6502725909989655118, - "venv/lib/python3.13/site-packages/numpy/testing/_private/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/gitdb/exc.py": 13975852664048821278, - "venv/lib/python3.13/site-packages/git/exc.py": 14278238357119816365, - "venv/lib/python3.13/site-packages/sqlalchemy/connectors/__init__.py": 17194870661869873083, - "backend/src/api/routes/git/_repo_operations_routes.py": 17252968422647919723, - "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/reporter.py": 6510864297510700136, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_sort.py": 11941630642630249576, - "venv/lib/python3.13/site-packages/pandas/_libs/groupby.pyi": 6154952803757623626, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_packbits.py": 7592956764084658562, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/ec.py": 8864112842559211971, - "backend/src/models/config.py": 7631082065091961320, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/ssh.py": 16262079536832961001, - "venv/lib/python3.13/site-packages/numpy/_core/multiarray.py": 4484782354376574355, - "venv/lib/python3.13/site-packages/pandas/core/arrays/numpy_.py": 16641729409992576358, - "venv/lib/python3.13/site-packages/pygments/lexers/_vim_builtins.py": 6842381248727719900, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/unistring.py": 18037463865539157041, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/bulk_persistence.py": 2307818727114646866, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_chunksize.py": 7107619871245389835, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/__init__.py": 15487893533770969571, - "backend/src/services/clean_release/dto.py": 11031410734734770552, - "venv/lib/python3.13/site-packages/numpy.libs/libgfortran-040039e1-0352e75f.so.5.0.0": 13946067868274850557, - "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/RECORD": 3205266407680661753, - "venv/lib/python3.13/site-packages/pip/_internal/commands/download.py": 7533669665002975823, - "venv/lib/python3.13/site-packages/numpy/linalg/_linalg.py": 9654828595008925976, - "venv/lib/python3.13/site-packages/numpy/random/tests/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_quarter.py": 6795026338946382805, - "backend/src/plugins/translate/__tests__/test_preview.py": 12246698485015379020, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/config.py": 10707678943298497676, - "backend/tests/core/test_defensive_guards.py": 1048600814279591148, - "venv/lib/python3.13/site-packages/pydantic/root_model.py": 20625057828723317, - "venv/lib/python3.13/site-packages/rsa/key.py": 4783269051050521475, - "venv/lib/python3.13/site-packages/websockets/auth.py": 499195617702591757, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/mariadb.py": 3109042476851791996, - "venv/lib/python3.13/site-packages/PIL/IptcImagePlugin.py": 14329453455296600824, - "frontend/src/routes/dashboards/__tests__/dashboard-profile-override.integration.test.js": 15198772446275187033, - "venv/lib/python3.13/site-packages/numpy/_core/_umath_tests.pyi": 4587511199710546030, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/connection.py": 5582413226288987808, - "venv/lib/python3.13/site-packages/pip/_internal/network/lazy_wheel.py": 12936988990566680659, - "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/RECORD": 11904769847385571600, - "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/RECORD": 7320381591791379627, - "venv/lib/python3.13/site-packages/pip/_internal/distributions/installed.py": 18153165899841229597, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/index_tricks.py": 10051261976498916957, - "venv/bin/activate.csh": 14513616043256836238, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_info.py": 10615285239043745712, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_datetime.py": 11417836378782978454, - "venv/lib/python3.13/site-packages/yaml/loader.py": 18284689412149643959, - "venv/lib/python3.13/site-packages/pandas/tests/base/test_misc.py": 9190561773853901527, - "venv/lib/python3.13/site-packages/pandas/tests/base/test_fillna.py": 9297637486401098611, - "venv/lib/python3.13/site-packages/rapidfuzz/__pyinstaller/__init__.py": 1229691061011958769, - "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/licenses/LICENSE": 6808958893921859106, - "venv/lib/python3.13/site-packages/fastapi/encoders.py": 1914192268055730299, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_common.py": 3559416690270529904, - "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/METADATA": 3474626408138844944, - "venv/lib/python3.13/site-packages/websockets/connection.py": 5168795926684067030, - "venv/lib/python3.13/site-packages/packaging/requirements.py": 2896326326372719999, - "venv/lib/python3.13/site-packages/dotenv/cli.py": 7952654621986067973, - "venv/lib/python3.13/site-packages/rapidfuzz/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/testing/overrides.pyi": 17408923209056015964, - "venv/lib/python3.13/site-packages/pandas/_libs/hashing.cpython-313-x86_64-linux-gnu.so": 16124435225170610034, - "frontend/src/lib/i18n/index.ts": 2428391315568750665, - "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/yaml.py": 17801117405950663611, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/result.py": 8306497889916212025, - "venv/lib/python3.13/site-packages/fastapi/dependencies/utils.py": 7687214523082385505, - "venv/lib/python3.13/site-packages/pandas/tests/extension/conftest.py": 16886862391161243448, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/diagnose.py": 17275977405061138181, - "backend/src/api/routes/admin.py": 16164005699911103765, - "venv/lib/python3.13/site-packages/pip/_internal/utils/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_hist_box_by.py": 16197297231683144299, - "venv/lib/python3.13/site-packages/pandas/_libs/sparse.cpython-313-x86_64-linux-gnu.so": 2051484129454294720, - "venv/lib/python3.13/site-packages/pandas/tests/frame/test_stack_unstack.py": 3737891757817696405, - "venv/lib/python3.13/site-packages/pandas/core/series.py": 11618272682977710696, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_reindex.py": 15794750188594767026, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/interval/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/lib/_ufunclike_impl.py": 12251264586530536622, - "venv/lib/python3.13/site-packages/sqlalchemy/engine/base.py": 6509914623926583629, - "venv/lib/python3.13/site-packages/pandas/tests/io/sas/test_sas.py": 9446226619493404132, - "venv/lib/python3.13/site-packages/numpy/lib/stride_tricks.py": 548928042543500365, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_copy_deprecation.py": 16045426957636349035, - "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pandas/core/strings/__init__.py": 13025387151657797130, - "frontend/src/routes/admin/users/+page.svelte": 18167787254767604761, - "venv/lib/python3.13/site-packages/jeepney/tests/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/cffi/ffiplatform.py": 6782148110863549472, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/fields.pyi": 15420142722808118826, - "venv/lib/python3.13/site-packages/pandas/core/computation/pytables.py": 16326122536715961388, - "venv/lib/python3.13/site-packages/pydantic/deprecated/parse.py": 819235411736647763, - "venv/lib/python3.13/site-packages/passlib/utils/compat/_ordered_dict.py": 14248790502300368024, - "venv/lib/python3.13/site-packages/anyio/_core/_eventloop.py": 6853955946028131785, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/dependency.py": 7300594038182867460, - "backend/src/services/notifications/service.py": 7032100258837946310, - "venv/lib/python3.13/site-packages/pandas/util/_test_decorators.py": 17930801441803090445, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/period/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/jaraco/functools/__init__.pyi": 2872039192528394677, - "venv/lib/python3.13/site-packages/passlib/registry.py": 5050675058011850564, - "venv/lib/python3.13/site-packages/numpy/fft/__init__.py": 9343449448737026658, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_indexing.py": 5910217172351020811, - "venv/lib/python3.13/site-packages/keyring/backend_complete.bash": 16589214602970214174, - "venv/lib/python3.13/site-packages/numpy/polynomial/__init__.py": 15558318749939680074, - "backend/src/models/dataset_review_pkg/_clarification_models.py": 1561486208194983219, - "venv/lib/python3.13/site-packages/numpy/polynomial/chebyshev.py": 1590647503660777156, - "frontend/build/_app/immutable/nodes/25.BTe1wdeo.js": 8998144152410680482, - "venv/lib/python3.13/site-packages/pydantic/_internal/_fields.py": 2692892815545218335, - "venv/lib/python3.13/site-packages/pygments/lexers/yang.py": 7409365668425173823, - "venv/lib/python3.13/site-packages/referencing/typing.py": 8296636464219681747, - "venv/lib/python3.13/site-packages/numpy/random/tests/data/generator_pcg64_np126.pkl.gz": 9677994062701347206, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arctan.csv": 4581185622290535488, - "venv/lib/python3.13/site-packages/passlib/tests/__main__.py": 16477180140297957650, - "venv/lib/python3.13/site-packages/numpy/lib/mixins.pyi": 15597536290223628777, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_setops.py": 16240008859650640717, - "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/boxplot.py": 7090586111222952862, - "venv/lib/python3.13/site-packages/fastapi/routing.py": 466387159689567541, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_dialect.py": 6294522482440261756, - "frontend/src/lib/stores/__tests__/test_activity.js": 15599963775430388097, - "venv/lib/python3.13/site-packages/passlib/handlers/cisco.py": 15004707325761459775, - "venv/lib/python3.13/site-packages/pandas/core/array_algos/masked_accumulations.py": 11428556645065711062, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_retain_attributes.py": 16210262356844956764, - "venv/lib/python3.13/site-packages/numpy/_typing/_array_like.py": 2161873439361281488, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/test_arithmetic.py": 14858832264660410908, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/test_astype.py": 1961831758405941258, - "venv/lib/python3.13/site-packages/pygments/lexers/bibtex.py": 14652372822443154388, - "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_setitem.py": 10389770446834773837, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_constructors.py": 7466113171256856591, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_indexing.py": 11572911419313573163, - "frontend/src/lib/components/reports/reportTypeProfiles.js": 10752964062056890725, - "backend/src/services/clean_release/__tests__/test_policy_engine.py": 9953185933720550640, - "venv/lib/python3.13/site-packages/pyasn1/type/char.py": 16518487114777185541, - "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_missing.py": 1963705411068820866, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_casting_unittests.py": 18157503533859249155, - "venv/lib/python3.13/site-packages/git/objects/base.py": 11498407361286170399, - "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/zip-safe": 15240312484046875203, - "venv/lib/python3.13/site-packages/sqlalchemy/pool/impl.py": 4687705587963980337, - "backend/src/plugins/translate/__init__.py": 10614338387079190520, - "venv/lib/python3.13/site-packages/jsonschema/benchmarks/const_vs_enum.py": 12873459583943748931, - "venv/lib/python3.13/site-packages/websockets/http.py": 9406523480132204760, - "frontend/src/lib/components/dataset-review/__tests__/us3_execution_batch.ux.test.js": 13416996904332574966, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/ssl_.py": 644667973700652263, - "venv/lib/python3.13/site-packages/pandas/io/parsers/readers.py": 7899068668225389287, - "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/connection.py": 15405047955974108860, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_css.py": 17765129030290410902, - "venv/lib/python3.13/site-packages/pygments/lexers/tls.py": 3552078393009383412, - "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pydantic_settings/utils.py": 14396350455520958703, - "venv/lib/python3.13/site-packages/greenlet/greenlet_slp_switch.hpp": 1694714764745718414, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/authenticate_client.py": 16886645731942472285, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/__init__.py": 8632038387100622009, - "venv/lib/python3.13/site-packages/_pytest/runner.py": 5772610501857496741, - "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/METADATA": 18410956221497090898, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/__init__.py": 15130871412783076140, - "frontend/src/routes/settings/automation/+page.svelte": 15129032082642700205, - "backend/src/services/clean_release/stages/base.py": 7739111130895140155, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/conftest.py": 25473177671450048, - "frontend/src/lib/auth/__tests__/permissions.test.js": 13555349356008297952, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arrayprint.pyi": 2053388407376896377, - "venv/lib/python3.13/site-packages/pandas/tests/internals/test_internals.py": 2049484047553296860, - "venv/lib/python3.13/site-packages/pygments/lexers/parasail.py": 7758704230750989282, - "venv/lib/python3.13/site-packages/pandas/_libs/interval.cpython-313-x86_64-linux-gnu.so": 8964760352224019544, - "venv/lib/python3.13/site-packages/PIL/BmpImagePlugin.py": 16682567630621529903, - "frontend/build/_app/immutable/chunks/ikwS1dR6.js": 3267599179274813039, - "backend/src/models/git.py": 6898938895423263836, - "backend/src/plugins/translate/sql_generator.py": 13328440537803602154, - "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/base.py": 13454394827268856575, - "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/LICENSE": 2032205056284080825, - "venv/lib/python3.13/site-packages/starlette/applications.py": 13591448461234020757, - "venv/lib/python3.13/site-packages/pip/_internal/utils/filetypes.py": 4415340223268174913, - "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_interaction.py": 12216477658994324787, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh15035.f": 13126319439858352711, - "venv/lib/python3.13/site-packages/passlib/hash.py": 5238710192614935875, - "venv/lib/python3.13/site-packages/uvicorn/__init__.py": 11517239807926185665, - "venv/lib/python3.13/site-packages/pygments/lexers/soong.py": 10273453675034306814, - "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/METADATA": 11419135077900073883, - "venv/lib/python3.13/site-packages/yaml/representer.py": 10550136298978225013, - "venv/lib/python3.13/site-packages/pygments/lexers/hexdump.py": 10665271113239513484, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/__init__.py": 15130871412783076140, - "frontend/src/routes/settings/+page.svelte": 3103346197225933395, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/lib_utils.pyi": 3708905060001289515, - "venv/lib/python3.13/site-packages/pygments/lexers/dsls.py": 11696359794961833087, - "venv/lib/python3.13/site-packages/httpx/_transports/mock.py": 13564349939188292363, - "venv/lib/python3.13/site-packages/numpy/lib/_scimath_impl.py": 14696841109142419143, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame_legend.py": 13094583566764796297, - "venv/lib/python3.13/site-packages/httpcore/__init__.py": 5897259569277532401, - "venv/lib/python3.13/site-packages/anyio/_core/_exceptions.py": 11969894261631227715, - "venv/lib/python3.13/site-packages/PIL/ContainerIO.py": 7551929914241379005, - "venv/lib/python3.13/site-packages/gitdb/utils/encoding.py": 1668793658272579497, - "venv/lib/python3.13/site-packages/passlib/crypto/_blowfish/unrolled.py": 12651425412640834530, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/requirements.py": 2362917888844255805, - "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/immutabledict.pxd": 13413785818999584986, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/lib/_user_array_impl.pyi": 7171810177801103765, - "frontend/src/lib/components/reports/ReportsList.svelte": 15460090587871611258, - "frontend/src/components/backups/BackupList.svelte": 14706629542956875064, - "venv/lib/python3.13/site-packages/attrs/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/cffi/_cffi_include.h": 13094899814611950155, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/live_render.py": 14619617939683800204, - "venv/lib/python3.13/site-packages/_pytest/_io/__init__.py": 1510478951261938348, - "venv/lib/python3.13/site-packages/pygments/lexers/jmespath.py": 7426464251945393925, - "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_backend.pyi": 13083543811193933305, - "backend/src/core/task_manager/models.py": 749015551222331342, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_indexing.py": 1926721846569184112, - "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/factory.py": 3042005457138956499, - "venv/lib/python3.13/site-packages/websockets/legacy/exceptions.py": 16025779645869134942, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timestamps.pyi": 51728851886466199, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_dropna.py": 17272771246760486947, - "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/RECORD": 16342326945648353387, - "venv/lib/python3.13/site-packages/pandas/api/internals.py": 5188134630996087511, - "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/nested_secrets.py": 15691917061715429369, - "backend/src/models/__tests__/test_clean_release.py": 3448406855108346883, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9207/__init__.py": 8434616194114282088, - "venv/lib/python3.13/site-packages/pip/_internal/metadata/importlib/_dists.py": 16746363359320577809, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/gh25337/use_data.f90": 14624074967635860696, - "venv/lib/python3.13/site-packages/numpy/lib/introspect.pyi": 12239924839764265507, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_append_common.py": 2377351120083195530, - "backend/src/api/routes/dashboards/_action_routes.py": 11814954258886577640, - "backend/src/models/dataset_review_pkg/_filter_models.py": 8426742165406106645, - "backend/tests/test_smoke_plugins.py": 10704454611361370435, - "venv/lib/python3.13/site-packages/passlib/crypto/_md4.py": 379335134151814809, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_ticks.py": 11649965080303468085, - "venv/lib/python3.13/site-packages/jeepney/wrappers.py": 15234251727654692435, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_errors.py": 3301889847545579393, - "frontend/build/_app/immutable/chunks/D6Fz1J1p.js": 10270384133479184115, - "venv/lib/python3.13/site-packages/pandas/core/computation/scope.py": 16859504937881548797, - "venv/lib/python3.13/site-packages/pip/_internal/models/link.py": 7172346414535657925, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_common_basic.py": 1945891789924713537, - "venv/lib/python3.13/site-packages/cffi/_cffi_errors.h": 1479575326813300292, - "venv/lib/python3.13/site-packages/pygments/lexers/nit.py": 18262907536841158657, - "venv/lib/python3.13/site-packages/dateutil/__init__.py": 17666544837260663800, - "venv/lib/python3.13/site-packages/jeepney/io/tests/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_internal/locations/base.py": 7966628150470073365, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_recfunctions.py": 16014503284544747867, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_bin_groupby.py": 14831211659124136806, - "venv/lib/python3.13/site-packages/secretstorage/item.py": 15486045386471912693, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_deprecate.py": 16723865897349422996, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/kbkdf.py": 1359143503575245224, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_series_equal.py": 1223890028205011021, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/frequencies/test_freq_code.py": 13758353172962109140, - "venv/lib/python3.13/site-packages/pygments/styles/manni.py": 11853576691280294949, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_ddl.py": 3690189094298044728, - "venv/lib/python3.13/site-packages/websockets/sync/utils.py": 15135020989207191168, - "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/WHEEL": 8600534672961461758, - "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/RECORD": 11976403473353722969, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_iloc.py": 16160558158155038350, - "venv/lib/python3.13/site-packages/pandas/_libs/arrays.cpython-313-x86_64-linux-gnu.so": 8634234308863090562, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/numpy_/test_indexing.py": 13703573544185051910, - "venv/lib/python3.13/site-packages/greenlet/TGreenlet.cpp": 4121171004360760212, - "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/core.py": 14576109242055156193, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/sqltypes.py": 2952996080192295188, - "frontend/build/_app/immutable/chunks/BmPq9SJR.js": 15603957767748490749, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/numerictypes.pyi": 15443101937711720707, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_numeric_only.py": 13610631681447961840, - "venv/lib/python3.13/site-packages/numpy/_core/_umath_tests.cpython-313-x86_64-linux-gnu.so": 3478629877770507853, - "backend/src/services/llm_prompt_templates.py": 10835300145692648460, - "backend/src/services/clean_release/repositories/publication_repository.py": 11208425895213508165, - "venv/lib/python3.13/site-packages/numpy/lib/introspect.py": 5706729538356302335, - "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py3-objarr.npy": 17303060773267383537, - "frontend/src/routes/settings/git/+page.svelte": 9547035239167234477, - "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/shared.py": 1162754506656505196, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_compression.py": 8061288329598682752, - "venv/lib/python3.13/site-packages/pandas/core/indexes/api.py": 13750417165301467381, - "venv/pyvenv.cfg": 2513607356761047446, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/console.py": 3540660073442483692, - "venv/lib/python3.13/site-packages/httpx/_transports/wsgi.py": 11981127094916412794, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/__init__.py": 4014740126161973332, - "venv/lib/python3.13/site-packages/pandas/__init__.py": 793698514004377486, - "venv/lib/python3.13/site-packages/numpy/polynomial/polyutils.py": 12355826783958402233, - "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_vendor/certifi/__main__.py": 8412594868333244844, - "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_windows.py": 9171347078900057357, - "backend/src/api/routes/datasets.py": 10960880516483380521, - "backend/src/services/clean_release/mappers.py": 8684357784135236729, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_util.py": 6573034224727513309, - "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/__main__.py": 6480933938145689964, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-sinh.csv": 12358602501260667480, - "venv/lib/python3.13/site-packages/pandas/_libs/ops_dispatch.pyi": 16176428602589420913, - "venv/lib/python3.13/site-packages/uvicorn/protocols/http/h11_impl.py": 1419719055394402145, - "venv/lib/python3.13/site-packages/pygments/lexers/grammar_notation.py": 9009644754106884095, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_iterator.py": 13869355993837330406, - "venv/lib/python3.13/site-packages/pandas/core/ops/invalid.py": 10186546927135277579, - "frontend/build/_app/immutable/nodes/5.ASUv2wEk.js": 11537528209294787573, - "venv/lib/python3.13/site-packages/uvicorn/supervisors/multiprocess.py": 10047012560534876149, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/ndarraytypes.h": 6765088137325865789, - "venv/lib/python3.13/site-packages/pandas/core/internals/api.py": 14632030170441237968, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/period.pyi": 13110894861187422750, - "venv/lib/python3.13/site-packages/pandas/core/computation/common.py": 5369352684655954608, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_interp_fillna.py": 5530041283991655415, - "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/licenses/LICENSE": 3868190977070717994, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_series.py": 17126297747681689408, - "backend/src/schemas/dataset_review_pkg/_dtos.py": 13301885458265748263, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ndarray_misc.py": 8706265665356094801, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/tzconversion.pyi": 10947021928755741366, - "venv/lib/python3.13/site-packages/pandas/tests/window/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_hashing.py": 11119284926039008503, - "venv/lib/python3.13/site-packages/pip/_vendor/requests/exceptions.py": 14982764273485726199, - "venv/lib/python3.13/site-packages/PIL/EpsImagePlugin.py": 1824020964179364491, - "venv/lib/python3.13/site-packages/pandas/core/sorting.py": 689057022713741051, - "venv/lib/python3.13/site-packages/numpy/_core/_add_newdocs_scalars.pyi": 1826323011169529229, - "venv/lib/python3.13/site-packages/pygments/lexers/diff.py": 5930189593946259160, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_groupby_subclass.py": 5540948578269213810, - "frontend/build/favicon.png": 16740551781088792605, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-log.csv": 221209423454319618, - "venv/lib/python3.13/site-packages/pygments/lexer.py": 3658450949169647228, - "backend/src/api/routes/__tests__/test_profile_api.py": 1724401885939803766, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/JaroWinkler.py": 1341849861184131135, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm32_ios.h": 6751259472945638998, - "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/licenses/LICENSE": 4672913476475760762, - "venv/lib/python3.13/site-packages/pydantic/_internal/_internal_dataclass.py": 13206778611516171760, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/numerictypes.pyi": 15565573472138344755, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/cli/hiworld.f90": 6321872653169140461, - "venv/lib/python3.13/site-packages/numpy/matlib.pyi": 8017902013455539981, - "venv/lib/python3.13/site-packages/h11/_writers.py": 8585823094975171480, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/fields.cpython-313-x86_64-linux-gnu.so": 16927263232848238698, - "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/__init__.py": 17630019785411546070, - "venv/lib/python3.13/site-packages/jsonschema/_utils.py": 14237077105384631097, - "venv/lib/python3.13/site-packages/pandas/plotting/_misc.py": 10202078355301731720, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_datetimelike.py": 10294379314868108649, - "venv/lib/python3.13/site-packages/websockets/sync/connection.py": 2791040669094103200, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/operators.py": 5584982192355398255, - "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/METADATA": 10707390829735099042, - "venv/lib/python3.13/site-packages/pygments/styles/bw.py": 869630132791421268, - "venv/lib/python3.13/site-packages/pygments/lexers/mime.py": 7768464764849718825, - "venv/lib/python3.13/site-packages/pandas/tests/resample/test_time_grouper.py": 3203729024111501071, - "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/licenses/LICENSE": 8438117004702803716, - "venv/bin/httpx": 6651007446865716794, - "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_manylinux.py": 12272275001961360101, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/measure.py": 18327922742808984428, - "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/parameters.py": 247312908510013930, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_week.py": 5756727157937218128, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/lib_user_array.py": 8711697474193296376, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/string_/test_string.py": 3834067244989779682, - "frontend/src/lib/api.js": 12667793754050845906, - "backend/test.db": 15130871412783076140, - "venv/lib/python3.13/site-packages/jeepney/io/tests/conftest.py": 13381752264278264218, - "venv/lib/python3.13/site-packages/cffi/cparser.py": 5246372077864988755, - "venv/lib/python3.13/site-packages/uvicorn/middleware/wsgi.py": 9179913252056394958, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/jupyter.py": 4446535289156468239, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_nanfunctions.py": 2356468092336024365, - "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/METADATA": 9586902338916246692, - "venv/lib/python3.13/site-packages/pip/_internal/operations/install/editable_legacy.py": 8145740626773638218, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/ranges.py": 14549386056660231279, - "venv/lib/python3.13/site-packages/pip/_internal/utils/retry.py": 15244280495983216204, - "venv/lib/python3.13/site-packages/pip/_vendor/idna/__init__.py": 6489437464172324468, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_truncate.py": 9623613657871046837, - "venv/lib/python3.13/site-packages/pygments/lexers/verification.py": 16645885125604874183, - "venv/lib/python3.13/site-packages/pandas/io/json/_table_schema.py": 3103776773020058805, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh2848.f90": 5799106109999071412, - "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/groupby.py": 14661033005768429774, - "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_where.py": 3272402211717453881, - "frontend/src/lib/components/reports/ReportCard.svelte": 15186215132458187779, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ufunc_config.pyi": 11754104063443791746, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/dtype.pyi": 465999539608816848, - "venv/lib/python3.13/site-packages/numpy/f2py/rules.py": 9322914583460630877, - "backend/src/services/resource_service.py": 4718644821742397530, - "venv/lib/python3.13/site-packages/pip/_internal/utils/temp_dir.py": 8657533190026387896, - "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/__init__.py": 8880435562116660648, - "venv/lib/python3.13/site-packages/pygments/lexers/srcinfo.py": 16466766917840327610, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_is_monotonic.py": 12899848089975919515, - "venv/lib/python3.13/site-packages/pygments/lexers/varnish.py": 3608370156692616959, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/color_triplet.py": 17264298271771184, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/__init__.py": 8811477458865810434, - "venv/lib/python3.13/site-packages/numpy/lib/_scimath_impl.pyi": 8879196542984811747, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_2_compat.h": 6512969159139431485, - "venv/lib/python3.13/site-packages/pandas/core/internals/construction.py": 893951849732478990, - "venv/lib/python3.13/site-packages/pygments/formatters/__init__.py": 8009871891954370829, - "venv/lib/python3.13/site-packages/cffi/setuptools_ext.py": 30796527302561458, - "venv/lib/python3.13/site-packages/urllib3/http2/__init__.py": 62108352209996836, - "venv/lib/python3.13/site-packages/pillow.libs/libwebpdemux-747f2b49.so.2.0.17": 7615380692384566654, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_util.py": 16908393806993809474, - "venv/lib/python3.13/site-packages/pandas/tests/series/test_unary.py": 8046543893978198672, - "venv/lib/python3.13/site-packages/numpy/lib/tests/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/core/arrays/__init__.py": 10460719978124302175, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_interval.py": 1228451182688768814, - "venv/lib/python3.13/site-packages/pandas/tests/base/test_value_counts.py": 9352540710376306520, - "venv/lib/python3.13/site-packages/pygments/formatters/bbcode.py": 8614391937525677922, - "venv/lib/python3.13/site-packages/requests/help.py": 1885413874621672882, - "venv/lib/python3.13/site-packages/urllib3/util/util.py": 12490259045660543460, - "backend/src/core/ws_log_handler.py": 7507069843556560249, - "venv/lib/python3.13/site-packages/pip/_vendor/tomli/py.typed": 9796674040111366709, - "venv/lib/python3.13/site-packages/pandas/tests/io/test_fsspec.py": 6936167344144998172, - "venv/lib/python3.13/site-packages/rapidfuzz/_utils.py": 14374663810542207121, - "venv/lib/python3.13/site-packages/pygments/console.py": 3540660073442483692, - "venv/lib/python3.13/site-packages/yaml/events.py": 745772917931702910, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/x509.pyi": 17458894097215345719, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_hashtable.py": 2620207240930665390, - "venv/lib/python3.13/site-packages/apscheduler/schedulers/twisted.py": 16059862619165885730, - "venv/lib/python3.13/site-packages/more_itertools/recipes.py": 5254043689078173976, - "venv/lib/python3.13/site-packages/numpy/_globals.pyi": 12839879732484756979, - "venv/lib/python3.13/site-packages/passlib/crypto/scrypt/_salsa.py": 1756536674254931838, - "venv/lib/python3.13/site-packages/pandas/tests/frame/test_iteration.py": 2118501258411211851, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame_subplots.py": 4596089143375088346, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_index_as_string.py": 292438690259156869, - "venv/lib/python3.13/site-packages/pip/_internal/network/xmlrpc.py": 5064964778750366059, - "venv/lib/python3.13/site-packages/pandas/tests/series/test_constructors.py": 6515602441449955627, - "venv/lib/python3.13/site-packages/pandas/arrays/__init__.py": 10005095663840461954, - "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/licenses/LICENSE": 9235234428907927646, - "venv/lib/python3.13/site-packages/numpy/fft/tests/test_helper.py": 5362180645056413158, - "venv/lib/python3.13/site-packages/pip/_vendor/certifi/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_internal/resolution/legacy/resolver.py": 2492962412506082234, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/isocintrin/isoCtests.f90": 6208802899442270399, - "venv/lib/python3.13/site-packages/numpy/random/tests/test_smoke.py": 7476432112986643847, - "venv/lib/python3.13/site-packages/numpy/ctypeslib/_ctypeslib.py": 12636954896699095212, - "venv/lib/python3.13/site-packages/pip/_internal/req/req_install.py": 7181005402818830655, - "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/WHEEL": 18203500019759199992, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/literal.py": 5641382379370828704, - "venv/lib/python3.13/site-packages/fastapi/concurrency.py": 17937688838625807004, - "venv/lib/python3.13/site-packages/pip/_internal/commands/debug.py": 13528633965821062950, - "venv/lib/python3.13/site-packages/pydantic/v1/schema.py": 10008526732895436361, - "venv/lib/python3.13/site-packages/numpy/lib/_function_base_impl.pyi": 2628035888703031029, - "venv/lib/python3.13/site-packages/pandas/api/typing/aliases.py": 11194270368147942988, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_getitem.py": 11882213323878588707, - "venv/lib/python3.13/site-packages/git/refs/symbolic.py": 14996822770181935589, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/arrayobject.h": 4345432890284821918, - "venv/lib/python3.13/site-packages/dateutil/tzwin.py": 5149446703746204349, - "venv/lib/python3.13/site-packages/pygments/lexers/kusto.py": 16285533608924436308, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/__init__.py": 15130871412783076140, - "frontend/src/components/TaskRunner.svelte": 18014857434320509117, - "venv/lib/python3.13/site-packages/pandas/util/__init__.py": 4070574585004336241, - "frontend/build/_app/immutable/nodes/22.j448M3vH.js": 17913524864494885194, - "backend/src/api/routes/__tests__/test_clean_release_legacy_compat.py": 10703957986116846695, - "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/INSTALLER": 17282701611721059870, - "backend/src/api/routes/__tests__/test_clean_release_v2_api.py": 13464989331176891726, - "backend/src/api/routes/dashboards/_schemas.py": 10686942001147126057, - "backend/src/services/profile_service.py": 10016788771873430731, - "venv/lib/python3.13/site-packages/attr/_cmp.py": 3297594878548179300, - "venv/lib/python3.13/site-packages/pandas/tests/test_optional_dependency.py": 7930709646653025355, - "backend/tests/test_translate_history.py": 14504549443376034614, - "venv/lib/python3.13/site-packages/PIL/_imaging.pyi": 17119084207765761921, - "venv/lib/python3.13/site-packages/PIL/_deprecate.py": 15076725072094847812, - "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/__init__.py": 12975130533860125272, - "frontend/static/favicon.png": 16740551781088792605, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh25211.f": 1486878017876900890, - "venv/lib/python3.13/site-packages/httpcore/_sync/__init__.py": 7676937747094511752, - "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/licenses/numpy/ma/LICENSE": 6723325434476453127, - "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/licenses/LICENSE": 17675192170670564526, - "venv/lib/python3.13/site-packages/PIL/ImageFilter.py": 10974179993355630141, - "venv/lib/python3.13/site-packages/httpcore/_sync/socks_proxy.py": 4418971149260853240, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/__init__.py": 9106887608906281686, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_endian.h": 2761502363895204652, - "venv/lib/python3.13/site-packages/numpy/_core/__init__.pyi": 2783897020308040960, - "venv/lib/python3.13/site-packages/pandas/_libs/reshape.pyi": 88721900806893992, - "venv/lib/python3.13/site-packages/itsdangerous/__init__.py": 6969210114978365656, - "venv/lib/python3.13/site-packages/PIL/ImageMode.py": 2361901066832921091, - "venv/lib/python3.13/site-packages/pandas/tests/window/test_dtypes.py": 2313400030798822026, - "venv/lib/python3.13/site-packages/pandas/core/reshape/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/inout.f90": 1521999519583206538, - "backend/tests/services/clean_release/test_policy_resolution_service.py": 3471271299977247598, - "venv/lib/python3.13/site-packages/pandas/core/ops/dispatch.py": 7041711677358147534, - "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/__init__.py": 15340047930888693984, - "venv/lib/python3.13/site-packages/passlib/handlers/des_crypt.py": 15304795681178011265, - "venv/lib/python3.13/site-packages/pygments/lexers/_googlesql_builtins.py": 12251289884604745945, - "venv/lib/python3.13/site-packages/git/repo/__init__.py": 6173604284490891047, - "backend/src/services/clean_release/repositories/audit_repository.py": 9617813121624417458, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/pubprivmod.f90": 8680230823849248800, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/OSA.pyi": 2700568594438441246, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_shares_memory.py": 2911029123657970431, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/timedeltas/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/sqlalchemy/engine/url.py": 1558176735588971829, - "venv/lib/python3.13/site-packages/pandas/_libs/byteswap.pyi": 6723628093359375823, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/authlib/jose/drafts/__init__.py": 4770885427721822507, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_routines.py": 4860173574365060471, - "venv/lib/python3.13/site-packages/numpy/_core/printoptions.py": 3897105663572772838, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_stack.py": 5316826578695144945, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh23879.f90": 13174951794239860144, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/common/block.f": 10727418304254548946, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/lib_polynomial.pyi": 4266795948450921502, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_dropna.py": 3168969662216766293, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_dialect.py": 4700488504252803159, - "venv/lib/python3.13/site-packages/pygments/lexers/usd.py": 934820244673741695, - "venv/lib/python3.13/site-packages/authlib/oidc/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/fixed_string.f90": 8654788371538544793, - "venv/lib/python3.13/site-packages/pydantic/_internal/_generate_schema.py": 7343380095251236503, - "venv/lib/python3.13/site-packages/PIL/PixarImagePlugin.py": 12061717157676819554, - "frontend/src/components/storage/FileUpload.svelte": 14805293086068620697, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/url.py": 9692934100602135106, - "venv/lib/python3.13/site-packages/apscheduler/triggers/cron/expressions.py": 8015786996064244656, - "venv/lib/python3.13/site-packages/apscheduler/triggers/calendarinterval.py": 12481650996882675949, - "venv/lib/python3.13/site-packages/jose/jwt.py": 3405491994268385178, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_combine_first.py": 11425059090050867171, - "venv/lib/python3.13/site-packages/apscheduler/schedulers/qt.py": 12828696264909048448, - "backend/src/services/__tests__/test_encryption_manager.py": 7097521778855634174, - "frontend/src/components/tools/MapperTool.svelte": 16528529568914906720, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7515/models.py": 17356033861792227817, - "venv/lib/python3.13/site-packages/pygments/regexopt.py": 16073437303824961930, - "frontend/build/_app/immutable/chunks/C2fyd9aw.js": 14162123587373788258, - "venv/lib/python3.13/site-packages/pip/_internal/locations/_distutils.py": 13559457590971821771, - "venv/lib/python3.13/site-packages/pip/_vendor/requests/help.py": 3124654001287175629, - "venv/lib/python3.13/site-packages/git/objects/commit.py": 12317865358846331802, - "venv/lib/python3.13/site-packages/pygments/lexers/installers.py": 5083244110640899732, - "venv/lib/python3.13/site-packages/pip/_internal/commands/show.py": 11839987586497822300, - "frontend/src/lib/auth/permissions.js": 12787489292887903923, - "venv/lib/python3.13/site-packages/pandas/core/arrays/sparse/accessor.py": 8373575175447947401, - "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth1/cache.py": 15037055977924167732, - "venv/lib/python3.13/site-packages/pandas/core/missing.py": 13332302791063948992, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_setitem.py": 2059440410065814114, - "venv/lib/python3.13/site-packages/idna/core.py": 7725813731640753267, - "venv/lib/python3.13/site-packages/pydantic/_internal/_decorators_v1.py": 16723743964226526155, - "venv/lib/python3.13/site-packages/passlib/tests/utils.py": 15403198680231294263, - "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/REQUESTED": 15130871412783076140, - "backend/src/models/__init__.py": 13280325675752905975, - "frontend/src/components/tasks/LogEntryRow.svelte": 10992388311554587653, - "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/requests.py": 6703055041957748929, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_normalize.py": 11373923576259976755, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_aarch64_gcc.h": 8140470539757491899, - "venv/lib/python3.13/site-packages/gitdb/test/test_stream.py": 18159319442241857857, - "backend/src/plugins/llm_analysis/plugin.py": 13563674795958736723, - "backend/src/core/superset_profile_lookup.py": 7009220677319131100, - "venv/lib/python3.13/site-packages/passlib/utils/pbkdf2.py": 15802959653228956404, - "venv/lib/python3.13/site-packages/numpy/polynomial/hermite_e.py": 3654583356259850174, - "venv/lib/python3.13/site-packages/pandas/_libs/hashtable.cpython-313-x86_64-linux-gnu.so": 16963890771704942465, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_index.py": 10837492069089787028, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_custom_business_hour.py": 14128508606361694814, - "venv/lib/python3.13/site-packages/pandas/io/parsers/c_parser_wrapper.py": 5841064965672872661, - "venv/lib/python3.13/site-packages/tzlocal-5.3.1.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pygments/formatters/terminal256.py": 11473927781167132440, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/resource_owner_password_credentials.py": 9559295461619813890, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/padding.py": 13763154154862871596, - "venv/lib/python3.13/site-packages/passlib/handlers/sha1_crypt.py": 5752556581809938954, - "venv/bin/pygmentize": 2166491742035772877, - "venv/lib/python3.13/site-packages/pandas/tests/extension/base/methods.py": 8059372834301557565, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_rename_axis.py": 12432900682994622455, - "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/RECORD": 8104089156015954779, - "venv/lib/python3.13/site-packages/pandas/io/formats/style.py": 13235403689320479165, - "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/PIL/SgiImagePlugin.py": 6916200065790425497, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/token_validator.py": 2932866595454490527, - "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/assertion_session.py": 18109848200936213195, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/region.py": 12579403230062395563, - "venv/lib/python3.13/site-packages/pandas/core/indexers/objects.py": 409599993084996593, - "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/METADATA": 9458019064618635438, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/base.py": 5924592154431932923, - "venv/lib/python3.13/site-packages/pip/_vendor/distlib/markers.py": 8297667990263004097, - "venv/lib/python3.13/site-packages/pandas/core/arrays/_arrow_string_mixins.py": 16862663427780315543, - "venv/lib/python3.13/site-packages/pygments/styles/abap.py": 11543320440974964547, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_x32_unix.h": 9165722966153119887, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/validator.py": 14200019408839159476, - "venv/lib/python3.13/site-packages/numpy/testing/_private/utils.py": 3646474165295296669, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_type_check.py": 3935091606923106753, - "venv/lib/python3.13/site-packages/PIL/BlpImagePlugin.py": 7209218638257731375, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/errors.py": 4817746830102488448, - "venv/lib/python3.13/site-packages/numpy/random/tests/test_generator_mt19937_regressions.py": 8981142329261965538, - "venv/lib/python3.13/site-packages/pygments/lexers/fortran.py": 6859638690245583968, - "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/limited_api1.c": 8494977275215578998, - "frontend/src/routes/settings/git/__tests__/git_settings_page.ux.test.js": 5334904955024018051, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_pickle.py": 388513670243918273, - "venv/lib/python3.13/site-packages/anyio/_core/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/testing.pyi": 16263777835572515739, - "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/RECORD": 2024211292009381421, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_date_range.py": 16128552513324017349, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_repr.py": 7552782621374439569, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-cbrt.csv": 8929553891827331780, - "venv/lib/python3.13/site-packages/pluggy/_result.py": 16790448391766505769, - "venv/lib/python3.13/site-packages/jose/backends/base.py": 12795468809472351388, - "venv/lib/python3.13/site-packages/pygments/lexers/q.py": 15426466074881683794, - "venv/lib/python3.13/site-packages/pycparser/ply/__init__.py": 5040371336745852622, - "venv/lib/python3.13/site-packages/numpy/_expired_attrs_2_0.pyi": 1424133074692438241, - "venv/lib/python3.13/site-packages/starlette/middleware/__init__.py": 9524277524025372856, - "venv/lib/python3.13/site-packages/pyasn1/codec/__init__.py": 15728752901274520502, - "venv/lib/python3.13/site-packages/cffi/api.py": 5325821560978502135, - "venv/lib/python3.13/site-packages/numpy/core/getlimits.py": 14257687540182552408, - "venv/lib/python3.13/site-packages/urllib3-2.6.2.dist-info/METADATA": 2624107638694809013, - "venv/lib/python3.13/site-packages/numpy/f2py/f90mod_rules.py": 2953876934840155920, - "venv/lib/python3.13/site-packages/pandas/core/computation/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pygments/styles/lilypond.py": 12486578704132023691, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7515/__init__.py": 2791238481813240414, - "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/licenses/LICENSE": 14316979437290727897, - "backend/src/services/git/_branch.py": 17338017626270161139, - "venv/lib/python3.13/site-packages/greenlet/slp_platformselect.h": 10428201768098464386, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_extension.py": 4831602527247293866, - "venv/lib/python3.13/site-packages/jeepney/tests/test_wrappers.py": 4813328996575597980, - "venv/lib/python3.13/site-packages/pip/_vendor/requests/structures.py": 2668010839316715865, - "venv/lib/python3.13/site-packages/pygments/lexers/rebol.py": 10460732731157940232, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_reductions.py": 17810094294132819208, - "venv/lib/python3.13/site-packages/rsa/util.py": 13423880475585138638, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_types.py": 4083297168618981717, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_array_utils.py": 14682148205379122638, - "venv/lib/python3.13/site-packages/pandas/tests/test_algos.py": 11860014896449369497, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/DamerauLevenshtein.pyi": 2700568594438441246, - "venv/lib/python3.13/site-packages/pip/_vendor/requests/api.py": 12339139862411341381, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/mapper.py": 16715864918034312591, - "venv/lib/python3.13/site-packages/pip/__pip-runner__.py": 1138979712722199296, - "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/RECORD": 10552906886624188222, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_chained_assignment_deprecation.py": 7694137945143129474, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/hybrid.py": 5793056975404534989, - "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/WHEEL": 12146818530001975731, - "frontend/src/lib/components/reports/__tests__/reports_filter_performance.test.js": 10583581505638859039, - "venv/lib/python3.13/site-packages/passlib/tests/test_totp.py": 9150389741890748343, - "backend/delete_running_tasks.py": 4453015771820664913, - "venv/lib/python3.13/site-packages/rapidfuzz/process_py.py": 17563673072076876125, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/multiarray.pyi": 17232959648651278910, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_unstack.py": 11834917665446437163, - "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/_cmd.py": 14954780419054588164, - "venv/lib/python3.13/site-packages/rsa/randnum.py": 13958355153634534526, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_first_valid_index.py": 15763400665851423183, - "frontend/src/routes/settings/connections/+page.svelte": 276661107137418305, - "frontend/build/_app/immutable/chunks/BqoVXGj7.js": 4487374658501570122, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_fillna.py": 13675584998644907265, - "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/METADATA": 14070889071949105584, - "venv/lib/python3.13/site-packages/pandas/tests/construction/test_extract_array.py": 3100523370314150013, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_datetimeindex.py": 14816894350435545024, - "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/licenses/LICENSE": 14610443802372107702, - "venv/lib/python3.13/site-packages/passlib/ext/django/__init__.py": 11713862539944289631, - "venv/lib/python3.13/site-packages/rapidfuzz/fuzz.py": 1094797446508902066, - "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/METADATA": 3786116428839780263, - "venv/lib/python3.13/site-packages/urllib3/util/request.py": 9432067988603015849, - "venv/lib/python3.13/site-packages/numpy/_core/tests/_natype.py": 12013743717306900860, - "venv/lib/python3.13/site-packages/pandas/tests/libs/test_libalgos.py": 13934861984871432400, - "venv/lib/python3.13/site-packages/pandas/testing.py": 18352975429944961593, - "venv/lib/python3.13/site-packages/pip/_vendor/idna/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/test_numba.py": 1548992314517942530, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_mangle_dupes.py": 15613858733226279352, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/numpy_/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_period.py": 3419297908709788013, - "venv/lib/python3.13/site-packages/pygments/lexers/dotnet.py": 17970884907837213099, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7516/jwe.py": 10478268710546063196, - "venv/lib/python3.13/site-packages/passlib/tests/__init__.py": 16543763165305017760, - "venv/lib/python3.13/site-packages/pandas/tests/io/sas/test_xport.py": 14080914637071212225, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/object/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/array.py": 13840510238256626632, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/_psycopg_common.py": 4111797647365870137, - "venv/lib/python3.13/site-packages/starlette/config.py": 16509394679506300256, - "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/assertion_client.py": 4261295109880943573, - "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/WHEEL": 13232065379159720345, - "venv/lib/python3.13/site-packages/pyasn1/codec/ber/eoo.py": 5126566925877730303, - "venv/lib/python3.13/site-packages/websockets/speedups.pyi": 10322382420215791091, - "venv/lib/python3.13/site-packages/websockets/legacy/handshake.py": 376095144657994920, - "venv/lib/python3.13/site-packages/pygments/formatters/terminal.py": 14380579279194052030, - "backend/src/schemas/__init__.py": 8700952869915187087, - "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/common.py": 9354442374897565498, - "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/METADATA": 12747626683405487434, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_mips_unix.h": 17373389962405490482, - "venv/lib/python3.13/site-packages/pydantic/_internal/_namespace_utils.py": 5237766366340181382, - "venv/lib/python3.13/site-packages/PIL/_avif.pyi": 18222325750818585549, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_join.py": 4213933887062089605, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/frequencies/test_frequencies.py": 14039315221824123200, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/ed25519.pyi": 16312114056447366970, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7521/__init__.py": 635200170992032966, - "venv/lib/python3.13/site-packages/pygments/lexers/pascal.py": 5992422120590352714, - "frontend/src/lib/utils.js": 5436516952434475239, - "backend/src/models/dataset_review_pkg/_enums.py": 2243691494729792539, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/char.pyi": 1639810799219814643, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/schema.py": 8358664670620586363, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/twofactor/hotp.py": 18325640697829098192, - "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_xs.py": 1897144171324167738, - "venv/lib/python3.13/site-packages/pygments/lexers/felix.py": 2334148799642808111, - "venv/lib/python3.13/site-packages/pydantic_core/__init__.py": 10563134104783445328, - "venv/lib/python3.13/site-packages/passlib/crypto/_blowfish/__init__.py": 3521833849634327520, - "venv/lib/python3.13/site-packages/pip/_internal/resolution/base.py": 10514193453447954780, - "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/validation": 5398883285871046811, - "venv/lib/python3.13/site-packages/numpy/ma/tests/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/test_na_scalar.py": 13950899907067372014, - "venv/lib/python3.13/site-packages/pip/_internal/models/candidate.py": 3099785363867247334, - "venv/lib/python3.13/site-packages/pandas/tests/window/test_rolling_functions.py": 2255133375699086300, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_setops.py": 15365064654930699428, - "venv/lib/python3.13/site-packages/pandas/core/interchange/from_dataframe.py": 8278998381856028462, - "venv/lib/python3.13/site-packages/jeepney/fds.py": 16573439672758641560, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/interval/test_interval.py": 18040371224712437126, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/yaml/emitter.py": 6036657460416912844, - "venv/lib/python3.13/site-packages/pygments/lexers/dylan.py": 16246299896150112270, - "venv/lib/python3.13/site-packages/httpx/_urlparse.py": 8270294590945652412, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_rank.py": 5398520257852104723, - "venv/lib/python3.13/site-packages/pydantic/_internal/_git.py": 8760779092674434712, - "venv/lib/python3.13/site-packages/pygments/__main__.py": 13200500591994479045, - "backend/src/plugins/storage/__init__.py": 5046554941488079204, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/io/excel/_pyxlsb.py": 10035587889954731645, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/histograms.pyi": 9255620158831643201, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/ec.pyi": 9835891299056543360, - "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_resolution.py": 18198858926948468112, - "venv/lib/python3.13/site-packages/pygments/lexers/devicetree.py": 9820277168995231927, - "venv/lib/python3.13/site-packages/pandas/tests/series/test_arithmetic.py": 17427754419626622853, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_at.py": 1029744344133153888, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_groupby.py": 16180421154734310873, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/_initialize_py.py": 6518425342376455821, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_quoting.py": 1147992698412929658, - "venv/lib/python3.13/site-packages/authlib/oidc/registration/__init__.py": 9448552677419908109, - "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/RECORD": 7844752443022514265, - "venv/lib/python3.13/site-packages/numpy/core/numerictypes.py": 5776941405348611027, - "venv/lib/python3.13/site-packages/keyring/backends/SecretService.py": 17482492072907438453, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_astype.py": 15275720655739710249, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_size.py": 16658280641516916790, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_ipython_compat.py": 12632271159842988561, - "frontend/build/_app/immutable/chunks/Ce0bZqFT.js": 15458334940864777489, - "venv/lib/python3.13/site-packages/ecdsa/test_sha3.py": 12459459298663975730, - "backend/src/core/__tests__/test_config_manager_compat.py": 656412918792001580, - "frontend/src/services/connectionService.js": 16613277497380191542, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/hmac.pyi": 9405122752084210696, - "venv/lib/python3.13/site-packages/pygments/styles/colorful.py": 15708848112363953394, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_function.py": 14142346897145169685, - "venv/lib/python3.13/site-packages/passlib/hosts.py": 11171402820797380938, - "venv/lib/python3.13/site-packages/pandas/api/extensions/__init__.py": 882327406374020760, - "venv/lib/python3.13/site-packages/pip/_internal/__init__.py": 7060345458485901709, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/openssl/__init__.py": 14571251344510763303, - "venv/lib/python3.13/site-packages/pandas/tests/tools/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/PIL/PsdImagePlugin.py": 4347581352716313298, - "frontend/build/_app/immutable/nodes/6.LcHOtDGX.js": 6856038459830890051, - "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_parser.py": 8145921552236189367, - "backend/src/core/scheduler.py": 2472649939852521889, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/_numpyconfig.h": 18150055639397773687, - "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-tan.csv": 6233924374281534211, - "venv/lib/python3.13/site-packages/numpy/core/umath.py": 4476812261188108155, - "venv/lib/python3.13/site-packages/_pytest/_version.py": 4890545974654141536, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/openssl/_conditional.py": 14190849361275154667, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_pick.py": 15760492005471315814, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_asof.py": 18383318159051131669, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/polynomial_polyutils.pyi": 3841660741524427413, - "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/WHEEL": 2357997949040430835, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_iloc.py": 7586049606891014270, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_round_trip.py": 14684057343786032776, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/relationships.py": 8401569216905291119, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/chararray.pyi": 17340224970247832290, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/ext.py": 8361831054662096695, - "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/RECORD": 5612689057373270213, - "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/rule.py": 5318344538761246105, - "venv/lib/python3.13/site-packages/pandas/tests/extension/test_arrow.py": 10068866425352207113, - "venv/lib/python3.13/site-packages/pandas/tests/extension/test_string.py": 13234624995755549329, - "venv/lib/python3.13/site-packages/pygments/lexers/ampl.py": 4594260378653369985, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_tolist.py": 8343058000369672317, - "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_pandas.py": 10894229569442891394, - "venv/lib/python3.13/site-packages/pandas/tests/io/test_stata.py": 3030675968330529905, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/timedeltas/test_cumulative.py": 8178093067175155877, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_docs.py": 17898499890274685198, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_timegrouper.py": 276805119790266454, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_normalize.py": 7378656958631172603, - "venv/lib/python3.13/site-packages/pandas/io/json/_json.py": 1393095374713367445, - "venv/lib/python3.13/site-packages/pandas/core/array_algos/quantile.py": 17341029201525362074, - "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/sqlalchemy/event/base.py": 18238453132776154057, - "venv/lib/python3.13/site-packages/pip/_vendor/packaging/tags.py": 254599446317461188, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_libgroupby.py": 9985769511561272200, - "venv/lib/python3.13/site-packages/pygments/lexers/comal.py": 769727871242464458, - "venv/lib/python3.13/site-packages/ecdsa/test_malformed_sigs.py": 2606295770491528880, - "venv/lib/python3.13/site-packages/fastapi/responses.py": 6092572095549573593, - "venv/lib/python3.13/site-packages/apscheduler/events.py": 10748346950729364899, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/_cipheralgorithm.py": 10057637461647348368, - "venv/lib/python3.13/site-packages/_pytest/_io/wcwidth.py": 13515196388826152383, - "venv/lib/python3.13/site-packages/numpy/_core/_internal.pyi": 6840742333427164920, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-cosh.csv": 9287774220881887502, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7519/__init__.py": 16532856661318424631, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_npfuncs.py": 8238385897366878558, - "venv/lib/python3.13/site-packages/uvicorn/main.py": 5843333502356171120, - "backend/src/services/clean_release/source_isolation.py": 10193276492118254392, - "venv/lib/python3.13/site-packages/pip/_vendor/distlib/__init__.py": 15735839022111230173, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/pysqlite.py": 16550134594771291234, - "venv/lib/python3.13/site-packages/PIL/BdfFontFile.py": 10811640174253687845, - "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/WHEEL": 2357997949040430835, - "venv/lib/python3.13/site-packages/PIL/GifImagePlugin.py": 16073125611077200693, - "venv/lib/python3.13/site-packages/pygments/lexers/gleam.py": 5161116162065925222, - "venv/lib/python3.13/site-packages/pygments/lexers/prolog.py": 599539463980699865, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/lib_version.pyi": 18093228021414910594, - "venv/lib/python3.13/site-packages/gitdb/db/base.py": 3375449584942578385, - "venv/lib/python3.13/site-packages/greenlet/tests/test_contextvars.py": 6077482318964702132, - "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_legendre.py": 18266595775500927868, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test__version.py": 9037916251087760255, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_simd_module.py": 7122050193390298178, - "venv/lib/python3.13/site-packages/pandas/core/window/__init__.py": 15180240812077877933, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_tz_convert.py": 77283525137564255, - "venv/lib/python3.13/site-packages/sqlalchemy/event/legacy.py": 13465911776953636949, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/routines/funcfortranname.f": 9330535808093475892, - "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_api.py": 7131036004750554905, - "venv/lib/python3.13/site-packages/git/objects/__init__.py": 2110615482320355676, - "venv/lib/python3.13/site-packages/click/termui.py": 7022374827798605437, - "frontend/build/_app/immutable/chunks/BxhFButn.js": 4448858164012016666, - "venv/lib/python3.13/site-packages/pydantic/tools.py": 8931184638883701008, - "frontend/build/_app/immutable/chunks/BBh5Ucdi.js": 9301800916108664548, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timezones.pyi": 17528421279543420867, - "venv/lib/python3.13/site-packages/gitdb/base.py": 7927279446353696534, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/random/distributions.h": 17162252287980242413, - "venv/lib/python3.13/site-packages/numpy/lib/_format_impl.pyi": 15745512451486888537, - "venv/lib/python3.13/site-packages/pandas/core/tools/timedeltas.py": 7221393731712061943, - "venv/lib/python3.13/site-packages/PIL/_imagingtk.cpython-313-x86_64-linux-gnu.so": 1708198947135304326, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_all_methods.py": 18227706645906325527, - "venv/lib/python3.13/site-packages/uvicorn/protocols/http/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/f2py/cfuncs.py": 10803011906582324302, - "venv/lib/python3.13/site-packages/numpy/_core/einsumfunc.pyi": 4729765666018003634, - "venv/lib/python3.13/site-packages/sqlalchemy/future/engine.py": 4639404437703898767, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/pysqlcipher.py": 11225173272050906977, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_at_time.py": 15352346149584081864, - "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth1/__init__.py": 13749066369790839334, - "venv/lib/python3.13/site-packages/attr/validators.py": 4453080662115911998, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_nth.py": 17151595277666975085, - "venv/lib/python3.13/site-packages/pandas/core/indexes/multi.py": 9115751979327393200, - "venv/lib/python3.13/site-packages/PIL/_imagingmorph.pyi": 18222325750818585549, - "venv/lib/python3.13/site-packages/fastapi/openapi/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/ssltransport.py": 8148652555908329980, - "venv/lib/python3.13/site-packages/numpy/lib/_function_base_impl.py": 14034239842770171660, - "venv/lib/python3.13/site-packages/urllib3/_request_methods.py": 13671055114247516883, - "backend/src/core/logger/__tests__/test_logger.py": 4188397720199242180, - "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_datetime.py": 4179112383995346046, - "venv/lib/python3.13/site-packages/psycopg2/sql.py": 18041240927130590808, - "venv/lib/python3.13/site-packages/greenlet/TUserGreenlet.cpp": 16258622236210473101, - "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_infer_datetimelike.py": 17304541521108700317, - "venv/lib/python3.13/site-packages/tzlocal/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/io/excel/_openpyxl.py": 6676451564208867775, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/associationproxy.py": 7421910137064160936, - "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/RECORD": 2688648742701423549, - "venv/lib/python3.13/site-packages/pydantic/deprecated/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_repeat.py": 9155935990114743583, - "venv/lib/python3.13/site-packages/pandas/tests/io/test_s3.py": 17425535047477778484, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/base.py": 7855217087916771270, - "venv/lib/python3.13/site-packages/pygments/lexers/yara.py": 17510792615476493957, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_logical.py": 6818185860296232476, - "venv/lib/python3.13/site-packages/starlette/endpoints.py": 3379755567024530053, - "venv/lib/python3.13/site-packages/numpy/polynomial/polyutils.pyi": 8195943561787777127, - "venv/lib/python3.13/site-packages/pygments/sphinxext.py": 2768161754523156130, - "frontend/src/lib/ui/Card.svelte": 3442526978752993023, - "venv/lib/python3.13/site-packages/attr/filters.pyi": 13942974755090135724, - "venv/lib/python3.13/site-packages/anyio/functools.py": 4300781896135050327, - "backend/src/core/task_manager/__tests__/test_task_logger.py": 8175976176924379623, - "venv/lib/python3.13/site-packages/jeepney/io/tests/test_asyncio.py": 2820168745710754136, - "venv/lib/python3.13/site-packages/numpy/_typing/_nbit_base.py": 7446626038222262489, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_function.py": 13492077564015386528, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_timer.py": 8196003526646080498, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/interfaces.py": 5371646629319169153, - "venv/lib/python3.13/site-packages/uvicorn/importer.py": 5449629250971153435, - "venv/lib/python3.13/site-packages/pygments/lexers/graphql.py": 2307854666015224677, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/astype_copy.pkl": 4470155972891419163, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_drop_duplicates.py": 12601598844977346213, - "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/RECORD": 12555714734722889695, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/warnings_and_errors.pyi": 9019577563960071498, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_interpolate.py": 7354685880215444946, - "venv/lib/python3.13/site-packages/pandas/io/common.py": 12088195203620154171, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_f2cmap.py": 5863341586534531594, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/x448.pyi": 11733449165276720901, - "frontend/build/_app/immutable/chunks/Cb8PHtdN.js": 5528961359985342557, - "venv/lib/python3.13/site-packages/cryptography/hazmat/decrepit/ciphers/__init__.py": 63497920264089252, - "venv/lib/python3.13/site-packages/numpy/lib/user_array.pyi": 1968484998382771986, - "venv/lib/python3.13/site-packages/PIL/ImageCms.py": 5610897002957128546, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/reserved_words.py": 8022121780993497971, - "venv/lib/python3.13/site-packages/numpy/lib/_datasource.py": 18136853038949826147, - "venv/lib/python3.13/site-packages/pandas/core/reshape/reshape.py": 5387892304726762127, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_character.py": 850554362222586199, - "venv/lib/python3.13/site-packages/pygments/lexers/nimrod.py": 8457135214131458774, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_construction.py": 10619501873883861745, - "backend/src/scripts/test_dataset_dashboard_relations.py": 6373309008834670516, - "venv/lib/python3.13/site-packages/cryptography/x509/__init__.py": 4066756344049307453, - "backend/src/core/task_manager/__init__.py": 15991802770215124472, - "backend/src/services/health_service.py": 7295235621662158359, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_setitem.py": 15731267129055947469, - "venv/lib/python3.13/site-packages/pluggy/_version.py": 7195758686717994475, - "venv/lib/python3.13/site-packages/pandas/_config/dates.py": 3863381688916127265, - "venv/lib/python3.13/site-packages/pillow.libs/libopenjp2-94e588ba.so.2.5.4": 2483101806045986252, - "venv/lib/python3.13/site-packages/pygments/lexers/archetype.py": 8995143180482517233, - "frontend/build/_app/immutable/chunks/BEid6Q9Q.js": 16254084752087873732, - "venv/lib/python3.13/site-packages/pandas/tests/apply/conftest.py": 13798335354961261346, - "venv/lib/python3.13/site-packages/websockets/exceptions.py": 12048063047468402740, - "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/WHEEL": 8600534672961461758, - "venv/lib/python3.13/site-packages/ecdsa/test_der.py": 7117444285097824495, - "venv/lib/python3.13/site-packages/pillow.libs/libfreetype-ee1c40c4.so.6.20.4": 12301510769231120312, - "venv/lib/python3.13/site-packages/pandas/core/groupby/__init__.py": 3015263524218708013, - "venv/lib/python3.13/site-packages/pandas/tests/io/sas/test_byteswap.py": 5090287710338893350, - "venv/lib/python3.13/site-packages/pip/_vendor/requests/status_codes.py": 17005213506461710202, - "venv/lib/python3.13/site-packages/ecdsa/_sha3.py": 10353612776869489378, - "venv/lib/python3.13/site-packages/cryptography/__init__.py": 641702726372647770, - "venv/lib/python3.13/site-packages/numpy/lib/_arrayterator_impl.py": 4037074830103951000, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_array_interface.py": 13648006002292914247, - "venv/lib/python3.13/site-packages/sqlalchemy/util/_py_collections.py": 16825222625411635946, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_interval_array_equal.py": 15654625365223535344, - "venv/lib/python3.13/site-packages/pycparser/lextab.py": 16045770806700381661, - "venv/lib/python3.13/site-packages/pip/_internal/commands/check.py": 6937252393012787214, - "venv/lib/python3.13/site-packages/numpy/_typing/_nbit.py": 15498810174380798405, - "venv/lib/python3.13/site-packages/pygments/lexers/compiled.py": 8215290039991205531, - "venv/lib/python3.13/site-packages/charset_normalizer/models.py": 9917300217816275821, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/lib/mixins.py": 7404729635424818497, - "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/RECORD": 1556051687830913019, - "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/apscheduler/jobstores/etcd.py": 4078354986605069279, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/strategies.py": 15673926142454922581, - "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_matmul.py": 16169282225324014901, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_combine_first.py": 3100691245280812910, - "venv/lib/python3.13/site-packages/pygments/styles/onedark.py": 17580335614588531275, - "venv/lib/python3.13/site-packages/pygments/lexers/css.py": 517586374264113606, - "backend/src/core/middleware/trace.py": 13093835356377196397, - "venv/lib/python3.13/site-packages/passlib/tests/test_crypto_scrypt.py": 17378030264314664250, - "backend/src/services/clean_release/__init__.py": 18311663871116449547, - "venv/lib/python3.13/site-packages/pydantic/aliases.py": 14481980467204711659, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/random/libdivide.h": 5314232500579481313, - "run_clean_tui.sh": 14305120550349644601, - "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth1/nonce.py": 18219168479887197733, - "venv/lib/python3.13/site-packages/websockets/extensions/base.py": 2457233337788783873, - "venv/lib/python3.13/site-packages/pip/_vendor/distlib/locators.py": 7638945613579396718, - "venv/lib/python3.13/site-packages/numpy/linalg/lapack_lite.cpython-313-x86_64-linux-gnu.so": 11074560904305737689, - "venv/lib/python3.13/site-packages/pandas/_libs/groupby.cpython-313-x86_64-linux-gnu.so": 14931394220112658268, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_join.py": 2585969863606902743, - "venv/lib/python3.13/site-packages/anyio/_core/_fileio.py": 4507100568401692983, - "venv/lib/python3.13/site-packages/PIL/WebPImagePlugin.py": 5378349556563611996, - "frontend/src/services/gitService.js": 7044825476968825357, - "venv/lib/python3.13/site-packages/numpy/_core/_string_helpers.pyi": 12043292763005874815, - "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/android.py": 8607703347015852195, - "venv/lib/python3.13/site-packages/pandas/core/computation/ops.py": 18250656489649699560, - "venv/lib/python3.13/site-packages/pandas/core/dtypes/generic.py": 17755579497690180620, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_astype.py": 8633811117672837999, - "venv/lib/python3.13/site-packages/starlette/websockets.py": 13834731343216764204, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_update_delete.py": 1317337950621091021, - "venv/lib/python3.13/site-packages/urllib3/util/ssl_match_hostname.py": 7411350247004265632, - "venv/lib/python3.13/site-packages/greenlet/tests/test_leaks.py": 1219835696230215605, - "venv/lib/python3.13/site-packages/pip/_vendor/distro/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/response.py": 353446217435156470, - "venv/lib/python3.13/site-packages/numpy/random/tests/data/generator_pcg64_np121.pkl.gz": 4708588000144933291, - "venv/lib/python3.13/site-packages/numpy/tests/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/_libs/ops.cpython-313-x86_64-linux-gnu.so": 10490009128553397250, - "venv/lib/python3.13/site-packages/pandas/tests/series/test_reductions.py": 2816859231048302619, - "venv/lib/python3.13/site-packages/starlette/responses.py": 14081178833432955042, - "venv/lib/python3.13/site-packages/pip/_internal/wheel_builder.py": 3893922370396791826, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_infer_objects.py": 6769980076977692890, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/assumed_shape/precision.f90": 5518911932373565642, - "venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/authlib/oauth2/auth.py": 8455258275234626534, - "venv/lib/python3.13/site-packages/numpy/lib/_polynomial_impl.py": 12771179468704314203, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_check_indexer.py": 2929031395357057009, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_series.py": 10922287546912569276, - "venv/lib/python3.13/site-packages/pip/_internal/models/__init__.py": 13482731985065116750, - "venv/lib/python3.13/site-packages/h11/_abnf.py": 10456996134895429201, - "venv/lib/python3.13/site-packages/numpy/__init__.cython-30.pxd": 1476688171642957054, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/psycopg2cffi.py": 5997687240967250164, - "venv/lib/python3.13/site-packages/numpy/ma/tests/test_core.py": 12712110303898046818, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_astype.py": 11995587502880659624, - "venv/lib/python3.13/site-packages/pygments/lexers/email.py": 4355246279485460399, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_no_deprecated_api.h": 7896028550808252043, - "venv/lib/python3.13/site-packages/pandas/tests/extension/test_common.py": 9446944526144164255, - "backend/src/schemas/settings.py": 7182606947764184429, - "backend/src/api/routes/__tests__/test_reports_openapi_conformance.py": 14282751162289385516, - "backend/src/models/dataset_review_pkg/__init__.py": 17789694606496652579, - "venv/lib/python3.13/site-packages/pandas/plotting/_core.py": 6766059152026241747, - "backend/src/services/__tests__/test_llm_provider.py": 8882903833125900085, - "venv/lib/python3.13/site-packages/pandas/core/reshape/api.py": 16364136812252343076, - "venv/lib/python3.13/site-packages/pygments/lexers/actionscript.py": 8829560731160428621, - "venv/lib/python3.13/site-packages/pandas/tests/io/__init__.py": 15130871412783076140, - "frontend/build/_app/immutable/nodes/2.CPPJxXwI.js": 17556014813501798121, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ufunc_config.py": 14728417910466146460, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_deprecate_nonkeyword_arguments.py": 11676809974120007408, - "venv/lib/python3.13/site-packages/httpx/__version__.py": 9473642134297828811, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_count.py": 16947194157984708529, - "backend/src/core/utils/superset_context_extractor/_recovery.py": 13298493527065532076, - "backend/src/core/logger.py": 2069537382060633888, - "venv/lib/python3.13/site-packages/apscheduler/triggers/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_subclass.py": 11096337912872573314, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/markup.py": 5413800947725916538, - "venv/lib/python3.13/site-packages/referencing/py.typed": 15130871412783076140, - "merge_kilo.py": 4282227344165325430, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/util.py": 387985965709546512, - "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/LICENSE": 14599279238716790189, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_pydatetime.py": 16228315407662560992, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_searchsorted.py": 11208047646304753715, - "backend/src/api/routes/__tests__/test_clean_release_source_policy.py": 15242462571646635922, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_io.py": 4199750143323741326, - "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/gcp.py": 12328409672947966867, - "venv/lib/python3.13/site-packages/sqlalchemy/util/topological.py": 11586868018611359415, - "venv/lib/python3.13/site-packages/pip/_internal/models/selection_prefs.py": 14700113736620314923, - "venv/lib/python3.13/site-packages/httpx/_types.py": 12461152436147308761, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/assignOnlyModule.f90": 15967199601254912096, - "venv/lib/python3.13/site-packages/pygments/lexers/automation.py": 8021926838024836904, - "venv/lib/python3.13/site-packages/dateutil/parser/_parser.py": 9443336890192151397, - "docker/nginx.conf": 16884137323072604795, - "venv/lib/python3.13/site-packages/ecdsa/util.py": 10543788809724099209, - "venv/lib/python3.13/site-packages/httpx/_models.py": 6516278895118988231, - "venv/lib/python3.13/site-packages/gitdb/fun.py": 55226330810782184, - "venv/lib/python3.13/site-packages/pillow.libs/libtiff-295fd75c.so.6.2.0": 17866578820357536656, - "venv/lib/python3.13/site-packages/pandas/tests/apply/test_invalid_arg.py": 610891871484326055, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_missing.py": 6224750552277937853, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/hstore.py": 9700253004947691961, - "venv/lib/python3.13/site-packages/numpy/linalg/_umath_linalg.cpython-313-x86_64-linux-gnu.so": 17652852308919396403, - "backend/src/plugins/llm_analysis/__tests__/test_screenshot_service.py": 17792688368296989200, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/abstract_interface/foo.f90": 14491312943942432024, - "venv/lib/python3.13/site-packages/pandas/_libs/missing.cpython-313-x86_64-linux-gnu.so": 1990755879067132155, - "venv/lib/python3.13/site-packages/authlib/oidc/core/util.py": 5364455058429522633, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalar_methods.py": 14881910898871057761, - "frontend/src/lib/stores/__tests__/mocks/env_public.js": 2540122820969872185, - "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/METADATA": 11759004913807981650, - "backend/src/schemas/translate.py": 12829370350127265103, - "backend/src/core/migration_engine.py": 1303635539349402052, - "backend/src/api/routes/translate/_metrics_routes.py": 18396200266145781983, - "frontend/build/_app/immutable/assets/9.tn0RQdqM.css": 15130871412783076140, - "venv/lib/python3.13/site-packages/passlib/tests/_test_bad_register.py": 5446848310854472376, - "frontend/src/lib/api/reports.js": 2328857814720054000, - "backend/src/scripts/__init__.py": 5400372851656282343, - "venv/lib/python3.13/site-packages/jose/jws.py": 11592462993417182096, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/registration.py": 14639972512303032712, - "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_np_datetime.py": 18363183516409621205, - "venv/lib/python3.13/site-packages/ecdsa/test_ecdh.py": 3338834550392548171, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/Indel_py.py": 9112851333217812996, - "venv/lib/python3.13/site-packages/pip/_internal/commands/configuration.py": 1608697090566485893, - "venv/lib/python3.13/site-packages/pandas/tests/window/moments/conftest.py": 6137462119729731945, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/offsets.pyi": 13173581775000480811, - "venv/lib/python3.13/site-packages/pandas/tests/libs/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pygments/styles/rainbow_dash.py": 12236746494379891602, - "frontend/src/types/dashboard.ts": 9718666955722367566, - "venv/lib/python3.13/site-packages/numpy/_core/lib/libnpymath.a": 17555816778997028283, - "venv/lib/python3.13/site-packages/pygments/lexers/textfmts.py": 17438453283146671997, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/sync.py": 6189260178302531376, - "frontend/build/_app/immutable/nodes/17.DQejmqiq.js": 17001830891938974854, - "venv/lib/python3.13/site-packages/pandas/core/interchange/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/lib/_stride_tricks_impl.pyi": 9243829615414967057, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_append.py": 17016125916761365423, - "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/collections.pyx": 17138729833735744777, - "venv/lib/python3.13/site-packages/git/cmd.py": 8854786163152637148, - "venv/lib/python3.13/site-packages/numpy/ma/tests/test_extras.py": 16160090335191788104, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm64_msvc.h": 14580207065003376324, - "venv/lib/python3.13/site-packages/referencing/tests/test_retrieval.py": 10782087416909177703, - "venv/lib/python3.13/site-packages/pip/_internal/network/cache.py": 10606522397693824641, - "venv/lib/python3.13/site-packages/pandas/tests/io/test_clipboard.py": 12674078499544938252, - "venv/lib/python3.13/site-packages/PIL/PpmImagePlugin.py": 7107324729714470853, - "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/METADATA": 16700674024421191168, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/errors.py": 2147619440137604907, - "venv/lib/python3.13/site-packages/_pytest/config/__init__.py": 12787579251203510616, - "venv/lib/python3.13/site-packages/numpy/__config__.py": 15794735729525094396, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_html.py": 7947998260347730581, - "venv/lib/python3.13/site-packages/PIL/FtexImagePlugin.py": 8196606399875185931, - "venv/lib/python3.13/site-packages/jsonschema/benchmarks/issue232.py": 6498198296113395367, - "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/WHEEL": 7414522633964952515, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7591/claims.py": 11853156183819186599, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py": 7624316342162916928, - "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/env.py": 1254612137164491329, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/lib_version.pyi": 3636944488233043883, - "venv/lib/python3.13/site-packages/numpy/random/_common.pyi": 5094115692952609118, - "venv/lib/python3.13/site-packages/pygments/lexers/jsx.py": 13855228003748707341, - "venv/bin/numpy-config": 17104619511899110252, - "venv/lib/python3.13/site-packages/numpy/lib/_histograms_impl.py": 13446184230476677032, - "venv/lib/python3.13/site-packages/pandas/tests/extension/test_masked.py": 5380551301916549925, - "frontend/src/lib/components/layout/__tests__/test_topNavbar.svelte.js": 11053755879172333925, - "venv/lib/python3.13/site-packages/httpcore/_backends/auto.py": 10488908050307887802, - "dist/docker/postgres.v1.0.0-rc2-docker.tar": 5933711120559789473, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/keywrap.py": 10424037418528425800, - "venv/lib/python3.13/site-packages/keyring/compat/__init__.py": 7578020229796085753, - "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/licenses/LICENSE": 1126906383149772681, - "frontend/src/routes/settings/__tests__/settings_page.ux.test.js": 8756428349518151160, - "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/WHEEL": 16097436423493754389, - "backend/src/plugins/translate/__tests__/test_scheduler.py": 4988970087981965515, - "frontend/src/lib/ui/PageHeader.svelte": 3800784212388586861, - "backend/src/core/__init__.py": 8673978627093182792, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_drop.py": 17940792593116540139, - "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/RECORD": 17341460504914308184, - "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_writers.py": 103545128256076790, - "venv/lib/python3.13/site-packages/fastapi/middleware/wsgi.py": 3706578020491442104, - "venv/lib/python3.13/site-packages/numpy/_typing/_ufunc.py": 16859854811012717088, - "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/numpy/lib/_ufunclike_impl.pyi": 9854069702366900663, - "venv/lib/python3.13/site-packages/greenlet/tests/test_weakref.py": 6780204527427742510, - "venv/lib/python3.13/site-packages/referencing/jsonschema.py": 14596871117484757502, - "venv/lib/python3.13/site-packages/pandas/tests/strings/__init__.py": 5060190599837877599, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_decimal.py": 3515468590005709183, - "venv/lib/python3.13/site-packages/pandas/_typing.py": 17795648994662434211, - "venv/lib/python3.13/site-packages/pydantic/v1/annotated_types.py": 12925825196690299531, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/cells.py": 8299309127027168194, - "venv/lib/python3.13/site-packages/passlib/handlers/__init__.py": 3424087230285514388, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_common.py": 2223069451949206319, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/__init__.py": 3577295959173028042, - "venv/lib/python3.13/site-packages/pandas/compat/_optional.py": 12714208019736797073, - "venv/lib/python3.13/site-packages/passlib/tests/test_apps.py": 10454136535890937237, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/transform/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/keyring/errors.py": 4587094338672775040, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_fillna.py": 16297834601116528166, - "venv/lib/python3.13/site-packages/requests/adapters.py": 17161109043243436200, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_head_tail.py": 1906121476322841736, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_values.py": 430620320423334461, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_read.py": 8825002468745406134, - "venv/lib/python3.13/site-packages/passlib/utils/decor.py": 21351391767102899, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/psycopg2.py": 1331438198531942242, - "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/WHEEL": 8600534672961461758, - "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/licenses/LICENSE": 12684353321716745791, - "venv/lib/python3.13/site-packages/charset_normalizer/cd.py": 8687667152597941021, - "venv/lib/python3.13/site-packages/urllib3/_base_connection.py": 14495079097019980154, - "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_classes.py": 1440926036579216168, - "venv/lib/python3.13/site-packages/uvicorn/loops/uvloop.py": 5385425357504191161, - "venv/lib/python3.13/site-packages/pygments/styles/murphy.py": 8177992406082781615, - "frontend/build/_app/immutable/chunks/DsnmJJEf.js": 17416107759626312632, - "venv/lib/python3.13/site-packages/pygments/lexers/functional.py": 15896849233007178031, - "venv/lib/python3.13/site-packages/pandas/_libs/internals.cpython-313-x86_64-linux-gnu.so": 2008633361686956377, - "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_getitem.py": 8414677531950073373, - "frontend/src/routes/reports/llm/[taskId]/report_page.contract.test.js": 4825093389030464765, - "venv/lib/python3.13/site-packages/authlib/common/errors.py": 16082974228565515177, - "venv/lib/python3.13/site-packages/attr/_next_gen.py": 16353246941851015420, - "backend/src/services/notifications/__init__.py": 13930898146447654299, - "venv/lib/python3.13/site-packages/sqlalchemy/pool/events.py": 13473858896579666058, - "backend/src/services/clean_release/preparation_service.py": 7557861288058237966, - "venv/lib/python3.13/site-packages/authlib/oidc/core/__init__.py": 16029653645350087968, - "frontend/src/lib/components/reports/__tests__/report_card.ux.test.js": 14899927226278257748, - "venv/lib/python3.13/site-packages/keyring/backend.py": 14185808762437650951, - "venv/lib/python3.13/site-packages/websockets/extensions/permessage_deflate.py": 12957105912018691390, - "venv/lib/python3.13/site-packages/numpy/_pytesttester.py": 17737911110576747508, - "venv/lib/python3.13/site-packages/PIL/TiffImagePlugin.py": 6845043550424565106, - "venv/lib/python3.13/site-packages/pytest/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pygments/lexers/make.py": 5345282370426217663, - "backend/src/services/dataset_review/repositories/repository_pkg/_mutations.py": 11718998093543631478, - "venv/lib/python3.13/site-packages/pandas/tests/window/test_rolling.py": 18221459425751198218, - "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_fields.py": 16222559851336781264, - "venv/lib/python3.13/site-packages/numpy/lib/_shape_base_impl.pyi": 12052895927933479005, - "venv/lib/python3.13/site-packages/cffi/recompiler.py": 17809252277700094304, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_case_when.py": 4133174129660834805, - "venv/lib/python3.13/site-packages/passlib/exc.py": 15559705487889657091, - "venv/lib/python3.13/site-packages/_pytest/config/findpaths.py": 7867603756389940562, - "venv/lib/python3.13/site-packages/pandas/core/strings/object_array.py": 17631047188839635539, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_freq_attr.py": 7685756734926749093, - "venv/lib/python3.13/site-packages/passlib/utils/md4.py": 4521366665754877351, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/_orm_constructors.py": 4276726508722638048, - "venv/lib/python3.13/site-packages/pillow.libs/libjpeg-32d42e18.so.62.4.0": 11717944412021329207, - "venv/lib/python3.13/site-packages/numpy/f2py/__version__.py": 8588600299261398598, - "backend/src/plugins/git/llm_extension.py": 9347391649685791102, - "venv/lib/python3.13/site-packages/starlette/__init__.py": 3252794766897205870, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_categorical.py": 8844412630511751140, - "venv/bin/py.test": 2593802493707545818, - "venv/lib/python3.13/site-packages/passlib/crypto/digest.py": 15890463288512025688, - "venv/lib/python3.13/site-packages/PIL/_imagingcms.cpython-313-x86_64-linux-gnu.so": 15198265718775753589, - "venv/lib/python3.13/site-packages/pygments/lexers/trafficscript.py": 776604244051744646, - "venv/lib/python3.13/site-packages/pygments/lexers/arrow.py": 6699009974224818979, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/repr.py": 839417422880281122, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_insert.py": 17383986803728810587, - "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pandas/core/generic.py": 10174952306641057447, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/__init__.py": 15130871412783076140, - "backend/src/api/routes/dashboards/_detail_routes.py": 12522696473630508473, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_fillna.py": 8802093795040069423, - "backend/src/api/routes/dashboards/_router.py": 8641007051243802224, - "venv/lib/python3.13/site-packages/pandas/_libs/sparse.pyi": 12526865400413362140, - "venv/lib/python3.13/site-packages/starlette/datastructures.py": 12097180838087229563, - "venv/lib/python3.13/site-packages/authlib/integrations/base_client/sync_openid.py": 5670082466989878756, - "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/WHEEL": 7314207500206292683, - "venv/lib/python3.13/site-packages/httpx/_transports/asgi.py": 12335675489870745729, - "frontend/build/_app/immutable/nodes/31.C2pdSWrJ.js": 8877169612979767666, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_scalar_compat.py": 10534925655070162459, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_records.py": 18167578114159312327, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/frequencies/test_inference.py": 5741637509343419942, - "venv/lib/python3.13/site-packages/authlib/jose/drafts/_jwe_algorithms.py": 15219408648894515493, - "frontend/build/favicon.svg": 6451919037497541980, - "venv/lib/python3.13/site-packages/pygments/lexers/business.py": 10410439210806697214, - "venv/lib/python3.13/site-packages/urllib3/_version.py": 839747992523118887, - "venv/lib/python3.13/site-packages/greenlet/TBrokenGreenlet.cpp": 10822436772777706192, - "venv/lib/python3.13/site-packages/websockets/utils.py": 17624459810483092475, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_map.py": 10769974470610467636, - "venv/lib/python3.13/site-packages/passlib/apps.py": 4633269405597895766, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_assumed_shape.py": 18361009188431483164, - "venv/lib/python3.13/site-packages/pycparser/_c_ast.cfg": 2649342580905806389, - "venv/lib/python3.13/site-packages/pygments/styles/zenburn.py": 1031869867933871309, - "backend/src/core/utils/superset_context_extractor/__init__.py": 1074191108198498747, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_replace.py": 15992095120302643273, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_unicode.py": 1103608932321322989, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_isna.py": 18394053826166267096, - "venv/lib/python3.13/site-packages/attrs/validators.py": 10346563361083429998, - "venv/lib/python3.13/site-packages/jeepney/tests/test_bus.py": 4260827599660763641, - "frontend/build/_app/immutable/chunks/CX0pjb_y.js": 1050355978995628415, - "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_xlrd.py": 9982457234958102003, - "venv/lib/python3.13/site-packages/pydantic/_internal/_core_utils.py": 13248004771466837645, - "venv/lib/python3.13/site-packages/websockets/client.py": 5229500079651465772, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_exceptions.py": 12145393002202744314, - "venv/lib/python3.13/site-packages/PIL/ImageTransform.py": 7825940907094338808, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_crackfortran.py": 10278720705326601943, - "frontend/src/routes/datasets/review/+page.svelte": 1567550142023887137, - "venv/lib/python3.13/site-packages/gitdb/util.py": 645937410168583692, - "venv/lib/python3.13/site-packages/numpy/ctypeslib/__init__.pyi": 13208953770241664384, - "backend/src/models/dataset_review_pkg/_execution_models.py": 9810012962062422666, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/testing.pyi": 9317922890783549326, - "venv/lib/python3.13/site-packages/pandas/core/interchange/utils.py": 11401792151107207834, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_iterrows.py": 3791886201566670087, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_categorical.py": 10863578845754547294, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/traceback.py": 2535227583726271746, - "venv/lib/python3.13/site-packages/tzlocal/utils.py": 7893867974548929154, - "venv/lib/python3.13/site-packages/numpy/_core/_asarray.py": 3468915833437229425, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/string/test_indexing.py": 2274965639578580723, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_equals.py": 6429101196875333574, - "venv/lib/python3.13/site-packages/numpy/_typing/_dtype_like.py": 1598511035344858524, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_to_typst.py": 14619529283550788275, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_astype.py": 7497268667246913350, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/crud.py": 805684028038896506, - "venv/lib/python3.13/site-packages/authlib/jose/drafts/_jwe_enc_cryptography.py": 4383854709657749855, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_period.py": 7727606662611927293, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_between_time.py": 14266333058913745751, - "venv/lib/python3.13/site-packages/sqlalchemy/schema.py": 16029542421991709659, - "venv/lib/python3.13/site-packages/pip/_vendor/tomli_w/__init__.py": 12849371269359608058, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/kind/foo.f90": 1367964042730902899, - "venv/lib/python3.13/site-packages/passlib/handlers/sun_md5_crypt.py": 1949993216707182407, - "venv/lib/python3.13/site-packages/starlette/convertors.py": 17839747154274354605, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/client.py": 18443944554871937480, - "venv/lib/python3.13/site-packages/_pytest/config/compat.py": 13175516717549204627, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_construction.py": 13953424340346625390, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9207/parameter.py": 2793853093222900337, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/flatiter.pyi": 9598576095384661517, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/parameters.py": 12219404446503940066, - "venv/lib/python3.13/site-packages/numpy/ctypeslib/__init__.py": 2401931196871484449, - "venv/lib/python3.13/site-packages/uvicorn/loops/auto.py": 13086005977087619545, - "venv/lib/python3.13/site-packages/pygments/lexers/python.py": 8995519134978505744, - "venv/lib/python3.13/site-packages/sqlalchemy/engine/cursor.py": 8074527784886981710, - "backend/src/schemas/health.py": 13764741380188041840, - "venv/lib/python3.13/site-packages/pip/_vendor/requests/utils.py": 3710235316419562274, - "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_hermite_e.py": 8912795372542950449, - "venv/lib/python3.13/site-packages/httpcore/_async/socks_proxy.py": 9026788710898138090, - "venv/lib/python3.13/site-packages/jeepney/io/tests/utils.py": 10346859893683522113, - "venv/lib/python3.13/site-packages/pygments/lexers/minecraft.py": 10133579583270214110, - "frontend/src/routes/reports/+page.svelte": 7370192460972346131, - "frontend/build/_app/immutable/nodes/18.BazzBSLx.js": 14618705072013016073, - "venv/lib/python3.13/site-packages/sqlalchemy/util/tool_support.py": 4926732415520779988, - "venv/lib/python3.13/site-packages/starlette/middleware/authentication.py": 15211131264936212938, - "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/WHEEL": 16097436423493754389, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/metrics_py.py": 13809503317864539103, - "venv/lib/python3.13/site-packages/numpy/_core/_ufunc_config.py": 7365943844063702766, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arccos.csv": 3026156288992132911, - "venv/lib/python3.13/site-packages/pandas/tests/frame/test_cumulative.py": 15644124412739892167, - "venv/lib/python3.13/site-packages/pygments/plugin.py": 18006138132596504101, - "venv/lib/python3.13/site-packages/python_multipart/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/_pytest/tracemalloc.py": 5530234062530858720, - "venv/lib/python3.13/site-packages/click-8.3.1.dist-info/INSTALLER": 17282701611721059870, - "backend/src/services/clean_release/demo_data_service.py": 8795028177684641724, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_compound.f90": 15012692484070385863, - "venv/lib/python3.13/site-packages/pygments/lexers/_scilab_builtins.py": 17453812809700086888, - "venv/lib/python3.13/site-packages/rapidfuzz/process.py": 3870006735299537016, - "venv/lib/python3.13/site-packages/numpy/random/tests/data/philox-testset-2.csv": 7063857529719738394, - "venv/lib/python3.13/site-packages/urllib3-2.6.2.dist-info/WHEEL": 7454950858448014158, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/status.py": 2214590120238144582, - "venv/lib/python3.13/site-packages/keyring/backends/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pydantic/v1/dataclasses.py": 7833468513057242440, - "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/cython/checks.pyx": 13187505236986855177, - "venv/lib/python3.13/site-packages/pandas/core/computation/parsing.py": 3084943521520476999, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/fromnumeric.py": 3792079757208879362, - "venv/lib/python3.13/site-packages/pandas/tests/libs/test_hashtable.py": 7762405492052106717, - "venv/lib/python3.13/site-packages/sqlalchemy/engine/_py_util.py": 13997184496924925110, - "venv/lib/python3.13/site-packages/sqlalchemy/util/_has_cy.py": 11979732417254560424, - "backend/src/api/routes/translate/_preview_routes.py": 744850480449179988, - "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/RECORD": 17545477863793260029, - "backend/src/services/clean_release/stages/manifest_consistency.py": 1270636316397468243, - "venv/lib/python3.13/site-packages/jsonschema/_legacy_keywords.py": 16481666133229715822, - "venv/lib/python3.13/site-packages/numpy/lib/tests/data/python3.npy": 4957143805477405905, - "venv/lib/python3.13/site-packages/pydantic/_internal/_schema_gather.py": 3634138701088855517, - "venv/lib/python3.13/site-packages/pandas/_libs/parsers.cpython-313-x86_64-linux-gnu.so": 14134106903573638108, - "venv/lib/python3.13/site-packages/git/__init__.py": 15867730798565725003, - "frontend/build/_app/immutable/chunks/DySFV_q2.js": 9541708291004606021, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_missing.py": 2976310411820303374, - "frontend/src/lib/components/dataset-review/LaunchConfirmationPanel.svelte": 5965510319309867257, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/recfunctions.py": 18330899924171767482, - "venv/lib/python3.13/site-packages/pandas/errors/__init__.py": 13444371880185740908, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/session.py": 5126234270435358377, - "venv/lib/python3.13/site-packages/pandas/core/groupby/grouper.py": 18110568057754450953, - "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth1/__init__.py": 14481526616887213120, - "venv/lib/python3.13/site-packages/pydantic/_internal/_import_utils.py": 4029157986210295967, - "venv/lib/python3.13/site-packages/psycopg2/_json.py": 9729420372294281405, - "frontend/src/routes/settings/settings-utils.js": 9490767217322820262, - "venv/lib/python3.13/site-packages/numpy/ma/__init__.py": 214772578978182427, - "venv/lib/python3.13/site-packages/numpy/_core/_add_newdocs.pyi": 9282436354926617898, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/__init__.py": 15130871412783076140, - "backend/src/api/routes/translate/_run_routes.py": 8915481471453671422, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_get_level_values.py": 12490886203425393290, - "venv/lib/python3.13/site-packages/pandas/tests/strings/test_cat.py": 15988884721768567895, - "venv/lib/python3.13/site-packages/numpy/f2py/capi_maps.pyi": 10638891136586198429, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/collections.py": 16114931075157411913, - "venv/lib/python3.13/site-packages/anyio/_core/_tasks.py": 14104828341875599130, - "venv/lib/python3.13/site-packages/fastapi/utils.py": 15402403831700548944, - "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pip/_internal/commands/__init__.py": 3795218871212151351, - "venv/lib/python3.13/site-packages/httpcore/_async/http2.py": 16350817785499681224, - "frontend/build/_app/immutable/chunks/1IJdlE0w.js": 14600235715446716616, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/test_constructors.py": 9478848417896027917, - "venv/lib/python3.13/site-packages/jeepney/io/threading.py": 525625939662612746, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/pretty.py": 2448541115957861214, - "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz": 17626265752554406355, - "venv/lib/python3.13/site-packages/ecdsa/ecdh.py": 12596317261561755793, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_map.py": 1115471561925426082, - "venv/lib/python3.13/site-packages/numpy/_core/numeric.py": 12261531924304979741, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_print.py": 598821365691498702, - "venv/lib/python3.13/site-packages/attrs/filters.py": 6844006230924162452, - "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_api.py": 16743710460729009914, - "venv/lib/python3.13/site-packages/pandas/_libs/lib.cpython-313-x86_64-linux-gnu.so": 6452315003728497116, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_html.py": 7732330576029516854, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_markdown.py": 9964642152916165317, - "venv/lib/python3.13/site-packages/sqlalchemy/util/deprecations.py": 7020540470348910770, - "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/endpoints.py": 18334891787808122725, - "venv/lib/python3.13/site-packages/_pytest/python.py": 1829073958095716309, - "venv/lib/python3.13/site-packages/pandas/core/ops/array_ops.py": 10061020479033421596, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm32_gcc.h": 3561524604274567339, - "venv/lib/python3.13/site-packages/pip/_vendor/truststore/__init__.py": 1948986914452928735, - "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/WHEEL": 5838667082726674838, - "venv/lib/python3.13/site-packages/pyasn1/compat/integer.py": 7365270971777550573, - "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth1/authorization_server.py": 6858244712625056421, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/poly1305.pyi": 14119032813912827271, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/f90continuation.f90": 17056591497459381871, - "venv/lib/python3.13/site-packages/git/refs/remote.py": 4391983355222612205, - "frontend/src/components/Footer.svelte": 17748559656923032, - "frontend/build/_app/immutable/chunks/ZFFoSDus.js": 12701360151670566914, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/publicmod.f90": 2174121054736811903, - "venv/lib/python3.13/site-packages/jose/backends/_asn1.py": 14123487576864105793, - "venv/lib/python3.13/site-packages/packaging/__init__.py": 5479277484104486860, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/tzconversion.cpython-313-x86_64-linux-gnu.so": 15960606468596245469, - "frontend/src/lib/ui/LanguageSwitcher.svelte": 3899734183369041614, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/timeout.py": 1807228452024740476, - "venv/lib/python3.13/site-packages/pandas/tests/tslibs/__init__.py": 15130871412783076140, - "backend/src/services/dataset_review/__init__.py": 15781509495698823404, - "venv/lib/python3.13/site-packages/fastapi/security/open_id_connect_url.py": 3502444317759870079, - "venv/lib/python3.13/site-packages/pydantic/v1/__init__.py": 1642038155370734658, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/array_constructors.pyi": 164538008396001632, - "backend/src/plugins/migration.py": 16567640288127443175, - "venv/lib/python3.13/site-packages/starlette/middleware/errors.py": 1337979724602864440, - "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_cisco.py": 1786475632318043669, - "venv/lib/python3.13/site-packages/pandas/core/computation/api.py": 17919983681396223380, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_astype.py": 16700461036658228009, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_reflection.py": 10520778598547003532, - "backend/tests/conftest.py": 14115149798000023183, - "venv/lib/python3.13/site-packages/attr/_config.py": 1864824728504480204, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/models.py": 9513172366009392193, - "venv/lib/python3.13/site-packages/pip/_vendor/distlib/version.py": 6401479036177132374, - "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/RECORD": 3288669175908898843, - "venv/lib/python3.13/site-packages/pydantic/generics.py": 15019381413806459410, - "venv/lib/python3.13/site-packages/websockets/asyncio/client.py": 5694225754072131767, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/__init__.py": 3969805865048730851, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/base.py": 16891437410462671317, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/oracledb.py": 7158791242292470472, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/formatters/_mapping.py": 13335227913146542481, - "venv/lib/python3.13/site-packages/numpy/lib/_version.pyi": 10804755840730584157, - "venv/lib/python3.13/site-packages/jsonschema/_types.py": 9250091433305395923, - "venv/lib/python3.13/site-packages/PIL/DcxImagePlugin.py": 11767274218348117481, - "frontend/src/routes/admin/settings/+page.svelte": 6706258642200752989, - "frontend/build/_app/immutable/nodes/19.B67FSCEK.js": 10417078689207235455, - "venv/lib/python3.13/site-packages/cffi/verifier.py": 8473599757770867754, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/mapped_collection.py": 11377280960650304531, - "venv/lib/python3.13/site-packages/PIL/ImageChops.py": 16368812693381154921, - "frontend/src/lib/stores/taskDrawer.js": 6659505033581293370, - "frontend/build/_app/immutable/chunks/Cp3Pv6sc.js": 7350545894220053516, - "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/licenses/LICENSE": 7959949171752474553, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/writeonly.py": 14213960431308620600, - "backend/src/core/task_manager/task_logger.py": 12820629458199400734, - "venv/lib/python3.13/site-packages/gitdb/test/__init__.py": 18393574323937353933, - "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_inference.py": 16402427186697071465, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_keys.py": 10813898277355150779, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timezones.cpython-313-x86_64-linux-gnu.so": 1137453907225619959, - "venv/lib/python3.13/site-packages/pygments/lexers/text.py": 10572727755736597715, - "venv/lib/python3.13/site-packages/numpy/lib/_arrayterator_impl.pyi": 2744889206277418389, - "venv/lib/python3.13/site-packages/pandas/tests/resample/test_base.py": 15292769510056833117, - "venv/lib/python3.13/site-packages/multipart/multipart.py": 26386459953377432, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_export_format.py": 17862222951776199694, - "venv/lib/python3.13/site-packages/numpy/f2py/diagnose.py": 503331864022631297, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_numeric.py": 5627177940393829333, - "venv/lib/python3.13/site-packages/passlib/win32.py": 5311393450489898748, - "venv/lib/python3.13/site-packages/pandas/tests/io/xml/conftest.py": 17514079438846557943, - "venv/lib/python3.13/site-packages/PIL/WmfImagePlugin.py": 15685062825106444247, - "backend/src/api/routes/assistant/_dataset_review.py": 14508672919199309579, - "venv/lib/python3.13/site-packages/sqlalchemy/engine/create.py": 16693261531832306870, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/socks.py": 17581293673028078134, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/nattype.pyi": 1830368009811266890, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/aioodbc.py": 12704729841432715246, - "venv/lib/python3.13/site-packages/pip/_vendor/certifi/__init__.py": 2833016678144975576, - "venv/lib/python3.13/site-packages/anyio/lowlevel.py": 11919467357746648592, - "venv/lib/python3.13/site-packages/pip/_vendor/distro/__main__.py": 2688850704829116818, - "venv/lib/python3.13/site-packages/pandas/_testing/compat.py": 10172779814048259850, - "venv/lib/python3.13/site-packages/pyasn1/type/namedval.py": 8273171503516887681, - "venv/lib/python3.13/site-packages/urllib3/_collections.py": 3440910792774742262, - "frontend/build/_app/immutable/chunks/2dOUpm6k.js": 11811637653151731489, - "backend/test_app.db": 2486636812009447051, - "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/WHEEL": 13347410390513723930, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/fixtures/mypy.py": 823265492261272631, - "venv/lib/python3.13/site-packages/pandas/core/dtypes/cast.py": 342228968652072052, - "backend/src/api/routes/git/_deps.py": 12613530531412985767, - "venv/lib/python3.13/site-packages/pip/_internal/vcs/versioncontrol.py": 13742159245132241245, - "venv/lib/python3.13/site-packages/pip/_vendor/msgpack/exceptions.py": 11303331612406662162, - "venv/lib/python3.13/site-packages/pandas/tests/series/test_missing.py": 3991199131191840903, - "backend/tests/services/clean_release/test_compliance_execution_service.py": 5924200441771414883, - "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/WHEEL": 16784970174376303810, - "venv/lib/python3.13/site-packages/pygments/lexers/_cocoa_builtins.py": 15468347167912293394, - "venv/lib/python3.13/site-packages/ecdsa/ellipticcurve.py": 15624510849346629163, - "venv/lib/python3.13/site-packages/pygments/lexers/algebra.py": 9651893228421050246, - "frontend/src/components/TaskHistory.svelte": 7819646903874958430, - "venv/lib/python3.13/site-packages/starlette/middleware/httpsredirect.py": 16837082808103815044, - "frontend/build/_app/immutable/chunks/CeAdK8Hz.js": 230807975890735821, - "venv/lib/python3.13/site-packages/pandas/compat/numpy/function.py": 18405870240333383757, - "venv/lib/python3.13/site-packages/pyasn1/type/constraint.py": 16776615503418773283, - "venv/lib/python3.13/site-packages/fastapi/middleware/gzip.py": 436886407566263171, - "venv/lib/python3.13/site-packages/pandas/tests/dtypes/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/greenlet/PyGreenletUnswitchable.cpp": 3160733517193315684, - "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_take.py": 1216902953519121176, - "backend/src/api/routes/git/_environment_routes.py": 1034235394475003092, - "venv/lib/python3.13/site-packages/pyasn1/codec/der/encoder.py": 4790267438222037867, - "backend/src/core/task_manager/persistence.py": 7896628499516364250, - "frontend/src/lib/components/reports/ReportDetailPanel.svelte": 16014663571033060148, - "backend/src/services/clean_release/__tests__/test_source_isolation.py": 17714198919084455758, - "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/requirements.py": 13215932786801020434, - "venv/lib/python3.13/site-packages/apscheduler/jobstores/memory.py": 9947113720821563254, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_cpu.h": 13799366908726531089, - "venv/lib/python3.13/site-packages/requests/status_codes.py": 17005213506461710202, - "venv/lib/python3.13/site-packages/pandas/tests/reductions/test_reductions.py": 11624188672428941494, - "venv/lib/python3.13/site-packages/authlib/oidc/core/claims.py": 2035724920423374302, - "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_cat_accessor.py": 4304062895283374927, - "frontend/build/_app/immutable/nodes/4.B0v4GDoW.js": 9805334845064330359, - "venv/lib/python3.13/site-packages/anyio/abc/_sockets.py": 15042495744291042062, - "venv/lib/python3.13/site-packages/pip/_internal/commands/cache.py": 1892313355296776523, - "venv/lib/python3.13/site-packages/yaml/_yaml.cpython-313-x86_64-linux-gnu.so": 16990140871649227895, - "venv/lib/python3.13/site-packages/authlib/integrations/flask_client/__init__.py": 9997757256282720103, - "venv/lib/python3.13/site-packages/apscheduler/triggers/combining.py": 1264860868414723829, - "venv/lib/python3.13/site-packages/packaging/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/char/__init__.py": 4428218097234308768, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/regexopt.py": 16073437303824961930, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_clip.py": 8087139801274517318, - "venv/lib/python3.13/site-packages/pydantic/_internal/_known_annotated_metadata.py": 9308620143218174987, - "venv/lib/python3.13/site-packages/numpy/_core/arrayprint.pyi": 84606125837677197, - "venv/lib/python3.13/site-packages/pip/_vendor/requests/_internal_utils.py": 4091305333167213279, - "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_get.py": 6509102681661636928, - "venv/lib/python3.13/site-packages/psycopg2/_range.py": 7184417109068014771, - "venv/lib/python3.13/site-packages/pandas/core/config_init.py": 16537122488227845090, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/provision.py": 17812733620485633975, - "venv/lib/python3.13/site-packages/fastapi/_compat/shared.py": 5249003014594464718, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/events.py": 10224214051422678828, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_repr.py": 13147587049887075335, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_is_full.py": 9577318758326279694, - "venv/lib/python3.13/site-packages/yaml/dumper.py": 11376022992370902766, - "backend/tests/test_translate_corrections.py": 1228642484417924184, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_parameter.py": 15173522343126004527, - "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/conversion.cpython-313-x86_64-linux-gnu.so": 9014806524727977333, - "venv/lib/python3.13/site-packages/apscheduler/schedulers/base.py": 17992335652981439676, - "venv/lib/python3.13/site-packages/numpy/f2py/capi_maps.py": 2490579175967301457, - "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/request.py": 17642741955458391050, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/index_tricks.pyi": 11463747060334597941, - "venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/WHEEL": 5179340427739743287, - "venv/lib/python3.13/site-packages/_pytest/_code/source.py": 9488112979192923739, - "venv/lib/python3.13/site-packages/websockets/legacy/__init__.py": 12332512329533591682, - "venv/lib/python3.13/site-packages/_pytest/setuponly.py": 10959102379908419762, - "venv/lib/python3.13/site-packages/jaraco/classes/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/bcrypt/__init__.py": 11415155211917181362, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_3kcompat.h": 5377305123299457337, - "frontend/src/routes/dashboards/[id]/components/DashboardGitManager.svelte": 4990524146294551357, - "frontend/src/routes/settings/notifications/+page.svelte": 14504217413720856827, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/test_nat.py": 7400568652984772972, - "venv/lib/python3.13/site-packages/pandas/tests/extension/json/test_json.py": 12422315190455428620, - "venv/lib/python3.13/site-packages/pygments/lexers/urbi.py": 1611762607688882372, - "venv/lib/python3.13/site-packages/authlib/integrations/django_client/apps.py": 14151733532064278336, - "frontend/src/routes/tools/storage/+page.svelte": 2651964385884112547, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/einsumfunc.pyi": 8902765738896588686, - "venv/lib/python3.13/site-packages/websockets/headers.py": 13587146967490088657, - "venv/lib/python3.13/site-packages/authlib/oauth1/errors.py": 1154126353335030046, - "venv/lib/python3.13/site-packages/numpy/f2py/_backends/__init__.pyi": 16164841755339571545, - "docker/backend.Dockerfile": 10320070102635663967, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/pkcs12.py": 5946672289916692272, - "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/WHEEL": 16097436423493754389, - "venv/lib/python3.13/site-packages/numpy/testing/_private/extbuild.pyi": 18253950285509265097, - "venv/lib/python3.13/site-packages/certifi/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/psycopg2/errorcodes.py": 6711830404954314463, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/polynomial_polybase.pyi": 3404315099794022355, - "venv/lib/python3.13/site-packages/apscheduler/executors/gevent.py": 17122637996105344344, - "venv/lib/python3.13/site-packages/numpy/lib/_type_check_impl.pyi": 2667658052734929089, - "venv/lib/python3.13/site-packages/numpy/random/mtrand.cpython-313-x86_64-linux-gnu.so": 16146459667121787202, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_abstract_interface.py": 17625870734108222276, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_select_dtypes.py": 3530442956913622572, - "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/var_.py": 12699521091170347311, - "venv/lib/python3.13/site-packages/numpy/_core/_exceptions.pyi": 3661113433078225952, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/__init__.py": 6532094538918910232, - "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/conftest.py": 13388202260795998613, - "venv/lib/python3.13/site-packages/attr/_funcs.py": 5302917072419624193, - "venv/lib/python3.13/site-packages/websockets/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/cryptography/exceptions.py": 5173540025160237758, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/array_like.py": 2778905818573625118, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/key_set.py": 8485970749081951741, - "venv/lib/python3.13/site-packages/pandas/tests/window/moments/test_moments_consistency_rolling.py": 11118160360072677569, - "venv/lib/python3.13/site-packages/pip/_vendor/packaging/licenses/__init__.py": 2635182244050911910, - "venv/lib/python3.13/site-packages/referencing/tests/test_core.py": 8280983300775878144, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_to_string.py": 11422235699126032386, - "venv/lib/python3.13/site-packages/multipart/__init__.py": 6496114190873890851, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_hist_method.py": 2109257663592928, - "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/METADATA": 3643456577199395707, - "venv/lib/python3.13/site-packages/jsonschema_specifications/_core.py": 14812112544772987164, - "venv/lib/python3.13/site-packages/idna/intranges.py": 12536174834761591006, - "venv/lib/python3.13/site-packages/referencing/retrieval.py": 11921179805977833120, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_integer/foo77.f": 12000068001851270396, - "venv/lib/python3.13/site-packages/pandas/conftest.py": 747626550806435763, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_file_buffer_url.py": 15377043158761455858, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/filters/__init__.py": 835924536855006596, - "venv/lib/python3.13/site-packages/urllib3/util/wait.py": 14629837381061032546, - "venv/lib/python3.13/site-packages/pygments/lexers/_sql_builtins.py": 5906655440517434734, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/WHEEL": 2357997949040430835, - "venv/lib/python3.13/site-packages/pygments/lexers/other.py": 6893672181003034910, - "venv/lib/python3.13/site-packages/websockets/legacy/client.py": 4032878587330592478, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/char.pyi": 13143560686049627445, - "venv/lib/python3.13/site-packages/pandas/tests/frame/constructors/test_from_records.py": 12217508428903265797, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_sparc_sun_gcc.h": 2915128971664712180, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/twodim_base.pyi": 10156504423258357540, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_multiarray.py": 5928288171180750841, - "venv/lib/python3.13/site-packages/pandas/tests/extension/array_with_attr/array.py": 13040461386712513615, - "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_sparse_accessor.py": 6774374030220202353, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/array_pad.pyi": 14755435694146003896, - "venv/lib/python3.13/site-packages/pandas/tests/extension/json/__init__.py": 7877061921210840955, - "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/INSTALLER": 17282701611721059870, - "frontend/src/lib/ui/Input.svelte": 8632025378593263475, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/LCSseq.pyi": 16372699564794732463, - "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/zip-safe": 15240312484046875203, - "frontend/src/routes/tools/mapper/+page.svelte": 11954517841045690204, - "frontend/build/_app/immutable/nodes/0.SLFvtO6J.js": 14720565923096646553, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_insert.py": 6970975909565157982, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/annotation.py": 15855576199737688124, "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_sort_values.py": 834951665649981397, - "venv/lib/python3.13/site-packages/jaraco/classes/properties.py": 6976928770004942858, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/pkcs7.py": 9623344347519683527, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/routines/subrout.f": 18215492757907465667, - "venv/lib/python3.13/site-packages/anyio/streams/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pygments/lexers/freefem.py": 9851243865301700231, - "backend/tests/core/test_git_service_gitea_pr.py": 6098719224379185148, - "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/version.py": 14723293207188512766, - "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/PIL/Image.py": 13615925856053031482, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_umath_complex.py": 11732242536199439023, - "venv/lib/python3.13/site-packages/pyasn1/codec/der/__init__.py": 15728752901274520502, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_results.py": 18145930285449734975, - "backend/src/models/task.py": 10701108436197477339, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_longdouble.py": 9337218715436213122, - "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/METADATA": 317417773265681256, - "venv/lib/python3.13/site-packages/jeepney/tests/test_fds.py": 6257376331171761928, - "venv/lib/python3.13/site-packages/numpy/lib/_version.py": 15294708923334674060, - "venv/lib/python3.13/site-packages/pandas/core/indexes/accessors.py": 14394872772838047912, - "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/RECORD": 17985800801793506250, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/strptime.cpython-313-x86_64-linux-gnu.so": 12654188486128938170, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_truncate.py": 6478126371906156409, - "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/WHEEL": 9788895026336324100, - "venv/lib/python3.13/site-packages/numpy.libs/libquadmath-96973f99-934c22de.so.0.0.0": 5098713761946118139, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_categorical.py": 18254320571347851153, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_align.py": 6050248183327934780, - "venv/lib/python3.13/site-packages/pillow.libs/libwebp-d8b9687f.so.7.2.0": 116215608212382352, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_loc.py": 17839380711970027363, - "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/meson.build": 8784756284679859367, - "venv/lib/python3.13/site-packages/pip/_internal/vcs/git.py": 17060377178521307324, - "venv/lib/python3.13/site-packages/pandas/io/feather_format.py": 13242733585787888812, - "venv/lib/python3.13/site-packages/pandas/io/formats/style_render.py": 13586834368514801953, - "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_pbkdf2.py": 4977067068389993374, - "venv/lib/python3.13/site-packages/pandas/tests/window/test_pairwise.py": 2673370322448160842, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-log2.csv": 13979868713429167140, - "venv/lib/python3.13/site-packages/pyasn1/debug.py": 6305633719847955310, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/bar.py": 12859947592168238832, - "venv/lib/python3.13/site-packages/pydantic_core/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/__init__.py": 697601512486720554, - "venv/lib/python3.13/site-packages/git/refs/log.py": 5175801243332619268, - "venv/lib/python3.13/site-packages/pygments/lexers/slash.py": 8320676560518108343, - "venv/lib/python3.13/site-packages/pygments/styles/pastie.py": 15784474766258831882, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalarinherit.py": 15240535501243623986, - "venv/lib/python3.13/site-packages/pygments/lexers/graph.py": 10445044822847205061, - "venv/lib/python3.13/site-packages/click/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/licenses/LICENSE": 3509878235770224233, - "frontend/vite.config.js": 6182424215365912367, - "backend/src/plugins/translate/metrics.py": 11569471420441638918, - "venv/lib/python3.13/site-packages/numpy/polynomial/hermite_e.pyi": 13068936038543812082, - "backend/src/services/clean_release/facade.py": 11231787492455424065, - "venv/lib/python3.13/site-packages/websockets/sync/messages.py": 15699091325918681038, - "venv/lib/python3.13/site-packages/numpy/random/tests/data/sfc64_np126.pkl.gz": 1630203486813146863, - "venv/lib/python3.13/site-packages/numpy/lib/recfunctions.py": 3001896031623204147, - "frontend/src/lib/components/assistant/__tests__/assistant_clarification.integration.test.js": 12258270009984504212, - "venv/lib/python3.13/site-packages/ecdsa/_rwlock.py": 7971972922423146201, - "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/modules.pyi": 14176187662591164602, - "venv/lib/python3.13/site-packages/more_itertools/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_vendor/requests/sessions.py": 5400174351499383072, - "venv/lib/python3.13/site-packages/pandas/tests/config/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_is_unique.py": 3989602816674881215, - "venv/lib/python3.13/site-packages/pandas/core/arrays/datetimes.py": 10585034798097337148, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_set_index.py": 10971093361190283675, - "venv/lib/python3.13/site-packages/git/index/util.py": 5022401275553420722, - "frontend/src/lib/components/layout/TopNavbar.svelte": 14489256050586877364, - "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libselinux-0922c95c.so.1": 16516617710645376769, - "venv/lib/python3.13/site-packages/pip/_internal/utils/virtualenv.py": 14416705841810221305, - "venv/lib/python3.13/site-packages/pydantic/json_schema.py": 15678278224696353978, - "venv/lib/python3.13/site-packages/pandas/tests/api/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/RECORD": 9502524172853437600, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/jws_algs.py": 11920621906391796226, - "frontend/src/routes/settings/__tests__/settings_page.integration.test.js": 13008989176397099996, - "venv/lib/python3.13/site-packages/pandas/core/indexes/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/uvicorn/lifespan/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_parsing.py": 2228959015420278458, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_setops.py": 10550603120090683350, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_csv.py": 571991535656576735, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/datetimes/test_cumulative.py": 6346947559103505068, - "venv/lib/python3.13/site-packages/numpy/_configtool.py": 2946953194004101078, - "venv/lib/python3.13/site-packages/pip/_internal/exceptions.py": 2252826732781519645, - "venv/lib/python3.13/site-packages/pyasn1/codec/cer/decoder.py": 17559787396729804535, - "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/cache.py": 3177663126928467950, - "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/aws.py": 1364297790170663941, - "venv/lib/python3.13/site-packages/pillow.libs/libbrotlicommon-c55a5f7a.so.1.2.0": 2635192149914499986, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/arrayscalars.h": 16142050006935459679, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_quantile.py": 11273403743157110261, - "venv/lib/python3.13/site-packages/pip/_internal/commands/freeze.py": 8644678595442275485, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/engine.py": 2652248727360250985, - "frontend/src/routes/+page.ts": 11160596731849880920, - "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/REQUESTED": 15130871412783076140, - "frontend/src/routes/migration/+page.svelte": 7821836225621176583, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_raises.py": 9678418010293693275, - "backend/src/api/routes/assistant/__init__.py": 14959302162073618175, - "venv/lib/python3.13/site-packages/pyasn1/type/namedtype.py": 1859990775875190116, - "backend/src/models/connection.py": 7467905739729526898, - "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/RECORD": 8956798822782402202, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7592/__init__.py": 1398617034174236358, - "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_xs.py": 11073752361562791165, - "venv/lib/python3.13/site-packages/pygments/lexers/teal.py": 10004159499175716139, - "backend/src/services/clean_release/__tests__/test_preparation_service.py": 4958420988131940633, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/lib_polynomial.pyi": 9134949577567498894, - "venv/lib/python3.13/site-packages/pydantic/v1/fields.py": 3948219773415054006, - "venv/lib/python3.13/site-packages/authlib/integrations/starlette_client/__init__.py": 9083396324667433335, - "venv/lib/python3.13/site-packages/pandas/tests/extension/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/io/formats/templates/latex.tpl": 8820045022551446255, - "venv/lib/python3.13/site-packages/requests/auth.py": 912521029864094489, - "venv/lib/python3.13/site-packages/pluggy/__init__.py": 8269188363563356631, - "venv/bin/websockets": 12099863324306500376, - "frontend/src/components/llm/DocPreview.svelte": 9286231407313632900, - "venv/lib/python3.13/site-packages/annotated_doc/main.py": 3384049281532298500, - "venv/lib/python3.13/site-packages/pillow.libs/libharfbuzz-0692f733.so.0.61230.0": 23110287346167671, - "venv/lib/python3.13/site-packages/fastapi/_compat/__init__.py": 12380131786677943349, - "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_shift.py": 9952689832827833247, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_unique.py": 6234921572794573905, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_multi_thread.py": 5660352470978621226, - "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/METADATA": 6502714564886871819, - "venv/lib/python3.13/site-packages/pandas/tests/window/test_cython_aggregations.py": 10818895573637904764, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_add_prefix_suffix.py": 8367793476246001244, - "venv/lib/python3.13/site-packages/psycopg2/pool.py": 8855184580138330938, - "frontend/src/lib/stores/assistantChat.js": 13807808925025688939, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/authorization_code.py": 4958605540994687737, - "venv/lib/python3.13/site-packages/authlib/integrations/sqla_oauth2/client_mixin.py": 17980753662107479779, - "venv/lib/python3.13/site-packages/numpy/typing/tests/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/random/_sfc64.pyi": 3536657185495782642, - "venv/lib/python3.13/site-packages/numpy/matrixlib/defmatrix.py": 4940170059946018356, - "venv/lib/python3.13/site-packages/numpy/typing/tests/test_isfile.py": 14544060093268573418, - "venv/lib/python3.13/site-packages/numpy/random/tests/data/pcg64dxsm-testset-2.csv": 16611724551361692999, - "venv/lib/python3.13/site-packages/numpy/dtypes.pyi": 6713822658171717369, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/conftest.py": 17897502508251413988, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_to_csv.py": 10737444103906389448, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/fft.pyi": 14454280827038327842, - "venv/lib/python3.13/site-packages/fastapi/temp_pydantic_v1_params.py": 9436036880518047720, - "venv/lib/python3.13/site-packages/_pytest/_io/terminalwriter.py": 16852767249156780980, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/string_/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/sqlalchemy/log.py": 10101221585967121334, - "venv/lib/python3.13/site-packages/uvicorn/__main__.py": 6086938803696646644, - "venv/lib/python3.13/site-packages/pygments/lexers/codeql.py": 4254046699692048717, - "frontend/src/lib/utils/debounce.js": 16884470786640632815, - "venv/lib/python3.13/site-packages/sqlalchemy/types.py": 15819795572817819102, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh25286_bc.pyf": 10893958728966010450, - "venv/lib/python3.13/site-packages/PIL/SpiderImagePlugin.py": 12234762087257163606, - "docker/all-in-one.Dockerfile": 10896793266219904099, - "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/licenses/LICENSE": 4274653168153720331, - "venv/lib/python3.13/site-packages/pandas/core/array_algos/__init__.py": 11850945878149145990, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_isocalendar.py": 5704842983090753914, - "backend/test_auth.db": 18214842050920965999, - "venv/lib/python3.13/site-packages/pandas/core/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_internal/commands/hash.py": 11824898770873127699, - "venv/lib/python3.13/site-packages/numpy/core/_dtype.py": 2806449741844148191, - "backend/src/services/clean_release/stages/__init__.py": 11216464651705158032, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_numeric.py": 9383693732009547935, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_datetimes.py": 8863748366184419339, - "venv/lib/python3.13/site-packages/pip/_internal/vcs/bazaar.py": 5630511062945201327, - "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_style.py": 10405592363651914796, - "venv/lib/python3.13/site-packages/passlib/handlers/phpass.py": 16489430001449160264, - "venv/lib/python3.13/site-packages/httpx/_main.py": 1812303705973265093, - "venv/lib/python3.13/site-packages/pygments/lexers/spice.py": 1376126320935115350, - "venv/lib/python3.13/site-packages/greenlet/tests/test_stack_saved.py": 7767924647054186572, - "venv/lib/python3.13/site-packages/pandas/core/arrays/_utils.py": 11574890848475750509, - "venv/lib/python3.13/site-packages/pydantic/_internal/_forward_ref.py": 10623110912945011703, - "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_list_accessor.py": 8613662386779664039, - "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/METADATA": 13695483537390128881, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/mutable.py": 9323088483998280629, - "venv/lib/python3.13/site-packages/numpy/_typing/_ufunc.pyi": 6286629088867436848, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_cross.py": 17742712348672218852, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/test_formats.py": 18080627205081311773, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/base.py": 5294446834530589760, - "venv/lib/python3.13/site-packages/ecdsa/_version.py": 17707102226558781833, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_utils.py": 15197339054699289627, - "venv/lib/python3.13/site-packages/ecdsa/__init__.py": 6237633580090653788, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/token.py": 11655733747403312358, - "backend/src/core/__tests__/test_superset_preview_pipeline.py": 5338719285630543394, - "venv/lib/python3.13/site-packages/_pytest/assertion/util.py": 16957445183087315124, - "venv/lib/python3.13/site-packages/pygments/styles/perldoc.py": 4857683935715743356, - "venv/lib/python3.13/site-packages/PIL/PngImagePlugin.py": 5076219228736706283, - "venv/lib/python3.13/site-packages/pandas/tests/generic/__init__.py": 15130871412783076140, - "backend/src/core/task_manager/cleanup.py": 8316318318890394605, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_timestamp.py": 10308799534491190078, - "venv/lib/python3.13/site-packages/pygments/lexers/smithy.py": 10789533877863290582, - "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/licenses/LICENSE": 8364608327598414179, - "venv/lib/python3.13/site-packages/pandas/tests/series/test_arrow_interface.py": 9757086292358759236, - "frontend/src/lib/components/layout/__tests__/test_taskDrawer.svelte.js": 15288009749873977442, - "venv/lib/python3.13/site-packages/passlib/crypto/__init__.py": 16409196868630049365, - "venv/lib/python3.13/site-packages/uvicorn/server.py": 15714008348292243019, - "backend/src/api/routes/git/_repo_lifecycle_routes.py": 6605622512801609889, - "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/METADATA": 15987199384245264478, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_empty.py": 13006241382741353569, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ufuncs.pyi": 1808147181379894521, - "backend/src/services/clean_release/repositories/manifest_repository.py": 12395698948312301073, - "backend/src/plugins/translate/plugin.py": 6629867705339506493, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm64_masm.obj": 11967637259540485652, - "venv/lib/python3.13/site-packages/ecdsa/numbertheory.py": 13538480862642502330, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/LCSseq.py": 13853220736499979380, - "venv/lib/python3.13/site-packages/PIL/_imagingmath.cpython-313-x86_64-linux-gnu.so": 77725273398858074, - "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/resultproxy.cpython-313-x86_64-linux-gnu.so": 6011605826065363427, - "venv/lib/python3.13/site-packages/pydantic_core/core_schema.py": 8106298745123589494, - "venv/lib/python3.13/site-packages/numpy/lib/_array_utils_impl.py": 14446508217220482719, - "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libpcre-9513aab5.so.1.2.0": 12298861477332583668, - "venv/lib/python3.13/site-packages/authlib/oidc/discovery/well_known.py": 8259335680633926377, - "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_backend.py": 1472021608501071055, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_easter.py": 3397863170068576196, - "venv/lib/python3.13/site-packages/numpy/core/defchararray.py": 11371045148957547088, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/__init__.py": 10357835306532281617, - "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/LICENSE": 6989336036499641077, - "backend/src/models/auth.py.bak": 7050478675360007060, - "backend/src/services/reports/__tests__/test_report_normalizer.py": 5030199452684805352, - "frontend/src/lib/components/reports/__tests__/reports_page.integration.test.js": 16463062768004950066, - "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/RECORD": 9974324769263969827, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/getlimits.pyi": 93747984191461691, - "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/wrapper.py": 14599195010683170123, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/utils.h": 3920393832993063886, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/object/test_indexing.py": 1947969642791009285, - "venv/lib/python3.13/site-packages/_pytest/pathlib.py": 9719734558816066453, - "venv/lib/python3.13/site-packages/numpy/ma/extras.pyi": 15292036493781556342, - "venv/lib/python3.13/site-packages/greenlet/tests/test_extension_interface.py": 11693583111513457974, - "venv/lib/python3.13/site-packages/pip/_internal/vcs/__init__.py": 1197579313959289096, - "venv/lib/python3.13/site-packages/numpy/lib/_stride_tricks_impl.py": 5260748170237305627, - "venv/lib/python3.13/site-packages/passlib/handlers/argon2.py": 835074952952017434, - "venv/lib/python3.13/site-packages/_pytest/pytester_assertions.py": 1899505062406979663, - "venv/lib/python3.13/site-packages/pandas/core/indexes/interval.py": 17965911911189276907, - "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/WHEEL": 1598805043198466373, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_value_counts.py": 13270420637302622174, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_cov_corr.py": 8117511855230249212, - "venv/lib/python3.13/site-packages/pygments/lexers/mojo.py": 8616283481592061285, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/provision.py": 2676876852726658063, - "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_mask.py": 9654897363729130542, - "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/__init__.py": 7526309124863950484, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_select.py": 17823338162428379468, - "backend/src/api/routes/git/_repo_routes.py": 7367823490321383813, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/provision.py": 7362363963464621570, - "venv/lib/python3.13/site-packages/numpy/lib/npyio.pyi": 3212440968296555560, - "venv/lib/python3.13/site-packages/PIL/_imagingft.cpython-313-x86_64-linux-gnu.so": 11054435406031360190, - "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/RECORD": 963865046004908868, - "venv/lib/python3.13/site-packages/pandas/tests/interchange/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/version.py": 1497063540123613501, - "venv/lib/python3.13/site-packages/pandas/_libs/window/aggregations.cpython-313-x86_64-linux-gnu.so": 16327106317503267067, - "venv/lib/python3.13/site-packages/pandas/tests/test_aggregation.py": 16863055892192070549, - "venv/lib/python3.13/site-packages/psycopg2/extensions.py": 14197445323992851566, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/Hamming.pyi": 4432290176776357346, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_semicolon_split.py": 8153770165829451525, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_lexsort.py": 10394832796613968484, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/shape.pyi": 2188930129299348535, - "venv/lib/python3.13/site-packages/pygments/lexers/d.py": 18120801227801223376, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/twofactor/__init__.py": 18069619555394133945, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/mixed/foo.f": 5690596225005490325, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_getlimits.py": 118041882543413669, - "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/METADATA": 7727489762869155085, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/control.py": 2034518223411945438, - "venv/lib/python3.13/site-packages/numpy/_pyinstaller/tests/__init__.py": 13331622784664204066, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-cos.csv": 12896264205153363031, - "venv/lib/python3.13/site-packages/pandas/tests/extension/base/reshaping.py": 18085648077811502689, - "venv/lib/python3.13/site-packages/smmap/test/test_buf.py": 6910367739329016619, - "venv/lib/python3.13/site-packages/pydantic/deprecated/config.py": 12280996227531856230, - "venv/lib/python3.13/site-packages/pandas/tests/frame/test_constructors.py": 13890224577680389718, - "venv/lib/python3.13/site-packages/pandas/tests/series/test_api.py": 13319208721442328400, - "venv/lib/python3.13/site-packages/pygments/lexers/pawn.py": 18127303119414402594, - "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/api.py": 13134394673408254097, - "venv/lib/python3.13/site-packages/apscheduler/jobstores/rethinkdb.py": 16413299263077970925, - "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libcrypto-2e26a48f.so.3": 3658133521245392852, - "venv/lib/python3.13/site-packages/pandas/core/tools/numeric.py": 8510988912136285022, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/formatter.py": 16499277113779414101, - "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/queue.py": 7820997545569991670, - "venv/lib/python3.13/site-packages/_pytest/_py/path.py": 8464061867075119556, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ndarray_conversion.py": 6205112277291935767, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/json.py": 4660603129768960095, - "frontend/build/_app/immutable/chunks/pZ1kmITO.js": 7579087758312850992, - "venv/lib/python3.13/site-packages/bcrypt/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/_pytest/_py/error.py": 2257336434271433543, - "venv/lib/python3.13/site-packages/bcrypt/_bcrypt.abi3.so": 8691731321358529264, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_umath_accuracy.py": 3904008607472505376, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/lexer.py": 14400766876373764268, - "venv/lib/python3.13/site-packages/pip/_vendor/idna/compat.py": 9758194415584776667, - "venv/lib/python3.13/site-packages/fastapi/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/ec_key.py": 5961540064444749833, - "venv/lib/python3.13/site-packages/pip/_internal/cli/main.py": 9304034369762028739, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/concatkdf.py": 6712732248328458871, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/timedeltas/test_reductions.py": 14432782234851468060, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/aiosqlite.py": 9888795404090331319, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/base.py": 14734745827490220667, - "venv/lib/python3.13/site-packages/pytest/__init__.py": 6137272437722350673, - "backend/src/plugins/backup.py": 9697280948668596192, - "backend/src/plugins/translate/superset_executor.py": 13699494825970352543, - "venv/lib/python3.13/site-packages/jsonschema/tests/test_types.py": 651959450717569029, - "build.sh": 37085706669440656, - "venv/lib/python3.13/site-packages/pip/_internal/pyproject.py": 6155748929233245415, - "venv/lib/python3.13/site-packages/numpy/lib/npyio.py": 6782361985454523908, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/json.py": 15085143436056608404, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_tz_localize.py": 13699016868476153393, - "venv/lib/python3.13/site-packages/pandas/core/groupby/base.py": 16888506204910366302, - "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/METADATA": 3448868793744358515, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_datetime.py": 7862725028865965163, - "venv/lib/python3.13/site-packages/PIL/_tkinter_finder.py": 14045496501810535432, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_transpose.py": 17983160984979323393, - "venv/lib/python3.13/site-packages/httpcore/_async/http11.py": 7565741048880549265, - "venv/lib/python3.13/site-packages/uvicorn/supervisors/__init__.py": 15971002342788501945, - "venv/lib/python3.13/site-packages/pygments/lexers/bqn.py": 11823648528816858738, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_constructors.py": 9815164146739254076, - "backend/src/core/config_models.py": 4264626520931642357, - "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/METADATA": 4868544280955034757, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/fixtures/sql.py": 13315906751371033170, - "venv/lib/python3.13/site-packages/PIL/GdImageFile.py": 16875784236394545058, - "backend/src/plugins/storage/plugin.py": 13669428465597027289, - "venv/lib/python3.13/site-packages/attr/_version_info.pyi": 7141309436445210354, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/negative_bounds/issue_20853.f90": 3911644649277659333, - "venv/lib/python3.13/site-packages/pandas/tests/window/conftest.py": 10673264126684571493, - "venv/lib/python3.13/site-packages/anyio/abc/_testing.py": 16484863782452886547, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_windows_renderer.py": 1076842273781909680, - "venv/lib/python3.13/site-packages/pip/_vendor/idna/uts46data.py": 1867240043777383728, - "venv/lib/python3.13/site-packages/starlette/middleware/exceptions.py": 10408538054406276433, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_duplicates.py": 9830936017197354309, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/Jaro.py": 183817263146423033, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_2_complexcompat.h": 5001035774408914877, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_index_as_string.py": 13421551616136437100, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/dh.py": 5728866271812501558, - "venv/lib/python3.13/site-packages/websockets/legacy/http.py": 16266924390281399720, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test__datasource.py": 1747755531265478106, - "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/abstract.py": 14216912708889351810, - "venv/lib/python3.13/site-packages/pandas/core/tools/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_get_numeric_data.py": 11747933921770969706, - "venv/lib/python3.13/site-packages/pandas/io/html.py": 2727247063231114153, - "venv/lib/python3.13/site-packages/greenlet/PyGreenlet.hpp": 6366432579621298231, - "venv/lib/python3.13/site-packages/pycparser/ply/ygen.py": 5520340773074632724, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/asn1.pyi": 16048852379621461316, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_get_numeric_data.py": 5896318696417090902, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_frame_equal.py": 12459816298158655274, - "venv/lib/python3.13/site-packages/more_itertools/__init__.pyi": 16479506520351014608, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ndarray_assignability.pyi": 1718610984396277997, - "venv/lib/python3.13/site-packages/pandas/tests/base/test_unique.py": 3148372351781648868, - "venv/lib/python3.13/site-packages/pandas/_testing/_warnings.py": 5640964566228306285, - "venv/lib/python3.13/site-packages/pygments/formatters/groff.py": 6480830447984073574, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/modules.py": 9023244176010175562, - "venv/lib/python3.13/site-packages/pygments/lexers/r.py": 14263133575134645005, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/__init__.py": 9820770319106921495, - "venv/lib/python3.13/site-packages/pygments/lexers/thingsdb.py": 6073447481627395832, - "frontend/src/components/llm/ValidationReport.svelte": 11810571826279890996, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_repr.py": 11737029058271003097, - "venv/lib/python3.13/site-packages/pydantic/v1/parse.py": 5875950480538559709, - "venv/lib/python3.13/site-packages/jeepney/io/trio.py": 11859775321483330469, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/operators.py": 2468046993343796128, - "backend/src/services/__init__.py": 15123879863527585264, - "venv/lib/python3.13/site-packages/pygments/lexers/special.py": 4972294202790455038, - "venv/lib/python3.13/site-packages/_pytest/stash.py": 14430252294763173610, - "backend/logs/app.log.2": 6692440785424103264, - "venv/lib/python3.13/site-packages/numpy/random/tests/data/pcg64-testset-2.csv": 5423145402839576695, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/assumed_shape/foo_mod.f90": 5765181406654284736, - "backend/src/services/clean_release/repositories/approval_repository.py": 15069637305272665109, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_overrides.py": 92685611709898742, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_tooltip.py": 853808724844451770, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_spinners.py": 15873416546130487469, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/expression.py": 1248029135284283479, - "venv/lib/python3.13/site-packages/pip/_vendor/requests/certs.py": 13366788049827102313, - "venv/lib/python3.13/site-packages/pydantic/typing.py": 6661252174518316760, - "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/METADATA": 6596896092754256988, - "venv/lib/python3.13/site-packages/PIL/PcdImagePlugin.py": 922809545463280224, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/assertsql.py": 4633484475514351889, - "venv/lib/python3.13/site-packages/ecdsa/test_ellipticcurve.py": 11125783981574901613, - "venv/lib/python3.13/site-packages/numpy/_core/strings.pyi": 1981676808027146409, - "backend/src/plugins/storage/__init__.py.bak": 7062955918227442388, - "frontend/src/lib/stores/__tests__/mocks/stores.js": 14098417748659067309, - "frontend/src/lib/components/layout/__tests__/sidebarNavigation.test.js": 9823973527644599938, - "backend/src/core/auth/security.py": 8289703096420999159, - "venv/lib/python3.13/site-packages/pandas/tests/frame/test_arrow_interface.py": 5231449831607036031, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_numerictypes.py": 8836108334624807647, - "backend/tests/scripts/test_clean_release_tui.py": 14700450036639944764, - "venv/lib/python3.13/site-packages/sqlalchemy/engine/row.py": 9763935103055608874, - "backend/src/core/database.py.bak": 14909628735913201532, - "venv/lib/python3.13/site-packages/greenlet/tests/_test_extension_cpp.cpp": 4590574206187223887, - "venv/lib/python3.13/site-packages/rsa/core.py": 13203947234024924497, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ndarray_misc.pyi": 7544619194032232861, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_tz_localize.py": 18409231586451494605, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_crosstab.py": 6631711416347033281, - "venv/lib/python3.13/site-packages/pandas/tests/tools/test_to_timedelta.py": 364160935264757405, - "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/LICENSE": 11167201188673981085, - "venv/lib/python3.13/site-packages/numpy/f2py/__main__.py": 12567751646090102167, - "frontend/src/lib/components/translate/TermCorrectionPopup.svelte": 563259816136630056, - "venv/lib/python3.13/site-packages/pydantic/_internal/_utils.py": 10936299012115637790, - "venv/lib/python3.13/site-packages/numpy/polynomial/tests/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_interval.py": 2613503970235591726, - "venv/lib/python3.13/site-packages/uvicorn/loops/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/serializer.py": 8708767945343850816, - "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/client_auth.py": 3301527187487914220, - "venv/lib/python3.13/site-packages/numpy/f2py/auxfuncs.py": 2234931733687557433, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/default_styles.py": 4469204219504675080, - "venv/lib/python3.13/site-packages/numpy/lib/_histograms_impl.pyi": 6534825471013879522, - "venv/lib/python3.13/site-packages/pip/_vendor/requests/hooks.py": 9888227370911151341, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/interval/test_interval_new.py": 3893421355544517336, - "venv/lib/python3.13/site-packages/pandas/io/formats/templates/html.tpl": 12550218314797699304, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/fixtures/base.py": 10205051944814316388, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/util.py": 4890614159013873000, - "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/METADATA": 10241403930811743893, - "venv/lib/python3.13/site-packages/dateutil/relativedelta.py": 5903095963079475484, - "venv/lib/python3.13/site-packages/pydantic/experimental/arguments_schema.py": 8644805798814234457, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/functions.py": 16567226076808693246, - "venv/lib/python3.13/site-packages/passlib/handlers/scrypt.py": 10089372287597257402, - "venv/lib/python3.13/site-packages/numpy/random/_examples/numba/extending_distributions.py": 209769687436320665, - "venv/lib/python3.13/site-packages/pandas/core/computation/align.py": 13027916530558901817, - "frontend/src/lib/components/layout/__tests__/test_breadcrumbs.svelte.js": 1250794495161202602, - "venv/lib/python3.13/site-packages/requests/__version__.py": 6677532709758546816, - "frontend/build/_app/immutable/chunks/A8Q9-d-F.js": 1942778798008045249, - "venv/lib/python3.13/site-packages/anyio/_backends/_trio.py": 4764555436057754985, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh25286.f90": 1249061697041863692, - "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/licenses/LICENSE": 17020744174398828059, - "venv/lib/python3.13/site-packages/numpy/f2py/f2py2e.py": 738588649412338185, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_operators.py": 12686786829906210592, - "venv/lib/python3.13/site-packages/pluggy/_warnings.py": 2664977718908223842, - "venv/lib/python3.13/site-packages/pip/_vendor/packaging/specifiers.py": 12284901056355482991, - "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/adapter.py": 5908944827805063108, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/test_arithmetic.py": 16045758521544316139, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_doc.py": 7865575374100528149, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/scoping.py": 18223258186431020473, - "venv/lib/python3.13/site-packages/pyasn1/codec/native/encoder.py": 120921270972591880, - "venv/lib/python3.13/site-packages/starlette/formparsers.py": 9019779181100355515, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_function.py": 7048185308307653546, - "venv/lib/python3.13/site-packages/numpy/lib/format.pyi": 11752225430594536662, - "venv/lib/python3.13/site-packages/numpy/random/_examples/cython/extending.pyx": 756189645898997788, - "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/processors.pyx": 7085380878820747579, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/constants.pyi": 4415188581374004936, - "venv/lib/python3.13/site-packages/numpy/tests/test_ctypeslib.py": 9592016432737074765, - "venv/lib/python3.13/site-packages/attr/setters.pyi": 6670509359139243236, - "venv/lib/python3.13/site-packages/click-8.3.1.dist-info/METADATA": 3188324716322823755, - "venv/lib/python3.13/site-packages/pandas/core/_numba/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_multiarray.py": 3592197154340095431, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_is_monotonic.py": 12769599198035357753, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_contains.py": 5273759677032634868, - "venv/lib/python3.13/site-packages/charset_normalizer/constant.py": 3070316197495651997, - "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/RECORD": 8201759541483070364, - "venv/lib/python3.13/site-packages/PIL/ImageTk.py": 17063969714816564357, - "venv/lib/python3.13/site-packages/jsonschema/validators.py": 3832874295500213309, - "venv/lib/python3.13/site-packages/greenlet/_greenlet.cpython-313-x86_64-linux-gnu.so": 6036818030377883416, - "venv/lib/python3.13/site-packages/referencing/__init__.py": 10093824711214801917, - "venv/lib/python3.13/site-packages/pygments/lexers/apdlexer.py": 14222752852221009085, - "venv/lib/python3.13/site-packages/fastapi/middleware/cors.py": 7452860773712601508, - "venv/lib/python3.13/site-packages/pygments/lexers/cddl.py": 1303059539145221713, - "venv/lib/python3.13/site-packages/pillow.libs/libpng16-4a38ea05.so.16.53.0": 13136089038268964667, - "frontend/src/lib/components/dataset-review/__tests__/us2_semantic_workspace.ux.test.js": 3550956860258259058, - "venv/lib/python3.13/site-packages/pandas/_libs/parsers.pyi": 18402185996588014111, - "venv/lib/python3.13/site-packages/numpy/random/tests/test_direct.py": 12680113511641199070, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_cell_widths.py": 5724379364993806351, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_rename.py": 16148017223289654683, - "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/RECORD": 14375680579341422646, - "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/licenses/LICENSE": 5757922580822401219, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/logging.py": 2426447364230673649, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/bitwise_ops.pyi": 751490187478960891, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/warnings_and_errors.pyi": 3151453262733619734, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ctypeslib.pyi": 8623725566434725526, - "backend/src/api/routes/__tests__/test_clean_release_api.py": 11565478953155085157, - "backend/src/services/dataset_review/semantic_resolver.py": 8447496149691924829, - "venv/lib/python3.13/site-packages/pip/_internal/metadata/base.py": 13444129650880426353, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_analytics.py": 8155550493311083506, - "venv/lib/python3.13/site-packages/dotenv/__main__.py": 16883579879172186355, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/terminal_theme.py": 13727399800263579809, - "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_npy_units.py": 8966226962799105383, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_x86_msvc.h": 2465089365642299646, - "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/RECORD": 3617343778671172258, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/cmac.py": 12011944740750051829, - "venv/lib/python3.13/site-packages/fastapi/security/oauth2.py": 1925394177931547776, - "venv/lib/python3.13/site-packages/pydantic/mypy.py": 10034028441785588819, - "venv/lib/python3.13/site-packages/passlib/crypto/scrypt/_gen_files.py": 11149423183253618378, - "venv/lib/python3.13/site-packages/passlib/tests/test_win32.py": 13932956220195912963, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_explode.py": 18263694040596159591, - "venv/lib/python3.13/site-packages/charset_normalizer/md__mypyc.cpython-313-x86_64-linux-gnu.so": 12629680116730190225, - "venv/lib/python3.13/site-packages/pandas/util/_print_versions.py": 15326663505771588740, - "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_getitem.py": 18202683049446557047, - "venv/lib/python3.13/site-packages/pygments/lexers/bdd.py": 5389493859905397060, - "frontend/src/components/backups/BackupManager.svelte": 15722995371746548624, - "backend/src/services/reports/normalizer.py": 11408466232944555336, - "venv/lib/python3.13/site-packages/more_itertools/recipes.pyi": 16788810745659802820, - "venv/lib/python3.13/site-packages/urllib3/util/response.py": 6106698559175827207, - "venv/lib/python3.13/site-packages/greenlet/tests/fail_slp_switch.py": 16490710972475154509, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_rewrite_warning.py": 4895919872954538758, - "venv/lib/python3.13/site-packages/numpy/version.pyi": 5075382895829889457, - "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/RECORD": 6518517239543344179, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_x64_masm.obj": 2884737706935637437, - "venv/lib/python3.13/site-packages/pygments/lexers/arturo.py": 4565524340706235725, - "venv/lib/python3.13/site-packages/pygments/lexers/html.py": 17288963642862550116, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/data_multiplier.f": 13432803601367981068, - "venv/lib/python3.13/site-packages/pandas/core/arrays/floating.py": 1215586266958421991, - "venv/lib/python3.13/site-packages/pygments/lexers/dax.py": 10868881057512002309, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_array.f90": 9711940829820746513, - "venv/lib/python3.13/site-packages/greenlet/tests/test_generator_nested.py": 12822240347707346718, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/datonly.f90": 10495925225338237742, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pygments/lexers/chapel.py": 7619603166448145621, - "venv/lib/python3.13/site-packages/dotenv/ipython.py": 15904966766060247908, - "backend/src/services/dataset_review/orchestrator_pkg/_helpers.py": 11613130235340753050, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_astype.py": 4975959187621745360, - "venv/lib/python3.13/site-packages/pygments/lexers/inferno.py": 9056274496469409594, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/conftest.py": 8406022190801970256, - "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_datetimelike.py": 15246580603900811749, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/pyodbc.py": 8175468565413744516, - "frontend/build/_app/immutable/chunks/ClIjFp8f.js": 4856629551122561739, - "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/WHEEL": 2357997949040430835, - "backend/src/core/utils/async_network.py": 2763204398131017281, - "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_numeric.py": 9417128508433693658, - "venv/lib/python3.13/site-packages/PIL/_imagingmath.pyi": 18222325750818585549, - "venv/lib/python3.13/site-packages/pip/_internal/operations/build/metadata_legacy.py": 9226692984248279094, - "venv/lib/python3.13/site-packages/pip/_internal/req/req_dependency_group.py": 10505346210114745037, - "venv/lib/python3.13/site-packages/rapidfuzz/process.pyi": 6959881293311340830, - "venv/lib/python3.13/site-packages/apscheduler/executors/base.py": 1980520974511822101, - "venv/lib/python3.13/site-packages/numpy/ma/testutils.py": 9355402483340137461, - "venv/lib/python3.13/site-packages/pandas/api/typing/__init__.py": 6438268275857060114, - "venv/lib/python3.13/site-packages/websockets/asyncio/router.py": 15039562376314233669, - "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/attr/_cmp.pyi": 14443711863388606665, - "venv/lib/python3.13/site-packages/pydantic/v1/env_settings.py": 6194387033830177219, - "venv/lib/python3.13/site-packages/fastapi/openapi/docs.py": 16735218221639179927, + "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/METADATA": 4975169119201255384, "venv/lib/python3.13/site-packages/jsonschema/benchmarks/subcomponents.py": 10365594934527289233, - "venv/lib/python3.13/site-packages/pandas/_version.py": 3480474785419232091, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_sorted.py": 1899608688401238388, - "venv/lib/python3.13/site-packages/authlib/common/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/rsa/transform.py": 12261738253972114335, - "venv/lib/python3.13/site-packages/numpy/random/_generator.pyi": 17167649524261942483, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_multiindex.py": 13723677252432338937, - "venv/lib/python3.13/site-packages/pygments/styles/arduino.py": 4578385147314541233, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_reindex.py": 12459492712890114705, - "venv/lib/python3.13/site-packages/PIL/ImageFont.py": 15621336334706847865, - "venv/lib/python3.13/site-packages/pyasn1/type/base.py": 6801504886392649787, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/cmac.pyi": 16042272072158438261, - "venv/lib/python3.13/site-packages/pydantic/v1/tools.py": 1995883197897112278, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_assign.py": 2647902466315482406, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_value_counts.py": 5534713464063604301, - "frontend/src/routes/dashboards/health/+page.svelte": 5234355531444674267, - "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_mask.py": 5451866071307236899, - "venv/lib/python3.13/site-packages/pygments/styles/vs.py": 4188729978573652106, - "frontend/build/_app/immutable/nodes/33.JpEaV7re.js": 16783069657925281131, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/sphinxext.py": 2403717774564798878, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/vectorized.cpython-313-x86_64-linux-gnu.so": 5441755022198996487, - "venv/lib/python3.13/site-packages/numpy/_utils/_convertions.pyi": 362674842164060822, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/information_schema.py": 8551227132710897346, - "venv/lib/python3.13/site-packages/pygments/styles/staroffice.py": 11694998942433220413, - "frontend/src/lib/toasts.js": 199299975383904134, - "frontend/src/lib/components/dataset-review/SemanticLayerReview.svelte": 2844634204872241861, - "frontend/build/_app/immutable/chunks/Fxxb239K.js": 5574865482398189674, - "backend/src/models/profile.py": 18027673609437659833, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_pickle.py": 4216445955812104014, - "venv/lib/python3.13/site-packages/PIL/MspImagePlugin.py": 3034490726971829439, - "backend/src/services/reports/__init__.py": 11818812865847046400, - "venv/lib/python3.13/site-packages/authlib/jose/rfc8037/okp_key.py": 10312614562914096039, - "venv/lib/python3.13/site-packages/numpy/lib/_arraysetops_impl.pyi": 3111521453255595221, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/histograms.pyi": 2281259341486424755, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh27697.f90": 4990763135487995517, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_ufunc.py": 3326502989311831856, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/recarray_from_file.fits": 15116318600514274152, - "venv/lib/python3.13/site-packages/requests/packages.py": 7733041271118298220, - "venv/lib/python3.13/site-packages/passlib/handlers/scram.py": 12281469744083867450, - "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/METADATA": 15888766579203341778, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_tz_localize.py": 14495969595744172955, - "venv/lib/python3.13/site-packages/cffi/backend_ctypes.py": 2042566833861899211, - "venv/lib/python3.13/site-packages/pip/_internal/utils/misc.py": 17461379236189029253, - "venv/lib/python3.13/site-packages/annotated_doc/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/httpx/_utils.py": 4836536051177895209, - "venv/lib/python3.13/site-packages/numpy/testing/print_coercion_tables.pyi": 3814281717779245045, - "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/style.py": 15214295655795348821, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_isin.py": 11330491145602008796, - "venv/lib/python3.13/site-packages/sqlalchemy/util/typing.py": 17638587764345605306, - "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/licenses/LICENSE": 5669644120528099197, - "venv/lib/python3.13/site-packages/pip/_vendor/requests/adapters.py": 2224938661429637508, - "venv/lib/python3.13/site-packages/uvicorn/supervisors/statreload.py": 5018382301336802445, - "venv/lib/python3.13/site-packages/pygments/lexers/_stata_builtins.py": 18053452765493556047, - "venv/lib/python3.13/site-packages/pygments/lexers/_php_builtins.py": 2344562378679281201, - "venv/lib/python3.13/site-packages/pandas/core/array_algos/transforms.py": 3773159138960141434, - "venv/lib/python3.13/site-packages/pygments/lexers/ride.py": 14096748896451437594, - "venv/lib/python3.13/site-packages/PIL/GimpPaletteFile.py": 2040459799887417392, - "backend/src/core/task_manager/manager.py": 5748204558787054193, - "backend/src/api/routes/assistant/_schemas.py": 6735060826070731731, - "venv/lib/python3.13/site-packages/pydantic/type_adapter.py": 10162988530225478692, - "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/licenses/LICENSE": 12688029424398428498, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7009/__init__.py": 1923528231486706442, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/strings.pyi": 402863478592154500, - "venv/lib/python3.13/site-packages/PIL/TiffTags.py": 8688883943071546469, - "venv/lib/python3.13/site-packages/git/config.py": 1724894144987553201, - "venv/lib/python3.13/site-packages/numpy/exceptions.pyi": 13942486291715303235, - "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/anyio/abc/_tasks.py": 16839170934610571514, - "venv/lib/python3.13/site-packages/attr/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_internal/commands/install.py": 17631777189475433503, - "venv/lib/python3.13/site-packages/fastapi/dependencies/models.py": 8626894872248212015, - "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/hist.py": 10928173425078493095, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_formats.py": 2601044064677727807, - "venv/lib/python3.13/site-packages/pydantic/schema.py": 83238111330132033, - "venv/lib/python3.13/site-packages/PIL/GribStubImagePlugin.py": 14954946414134984896, - "venv/lib/python3.13/site-packages/pandas/tests/apply/test_series_transform.py": 18159263102656491974, - "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/licenses/LICENSE": 5563356551734678258, - "venv/lib/python3.13/site-packages/greenlet/tests/test_tracing.py": 10227316489696807112, - "venv/lib/python3.13/site-packages/pip/_internal/commands/uninstall.py": 11003472265011262515, - "venv/lib/python3.13/site-packages/pandas/api/indexers/__init__.py": 17431573013142626187, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_add_prefix_suffix.py": 4815518357936092237, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py": 8530403239168529668, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/ed448.py": 12264234876933578367, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/offsets.cpython-313-x86_64-linux-gnu.so": 6726636942028566415, - "venv/lib/python3.13/site-packages/attr/__init__.pyi": 13203080513025719049, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_get_dummies.py": 16112674981222844375, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/__init__.py": 15130871412783076140, - "frontend/src/routes/git/+page.svelte": 14169430923974356254, - "venv/lib/python3.13/site-packages/pygments/lexers/tal.py": 447505725492547461, - "backend/src/api/routes/__tests__/test_clean_release_v2_release_api.py": 14275839608126658275, - "venv/lib/python3.13/site-packages/psycopg2/__init__.py": 15798412693009721199, - "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/licenses/LICENSE": 10253862887434903467, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/warnings_and_errors.py": 11172336980866895356, - "venv/lib/python3.13/site-packages/pandas/core/arrays/_ranges.py": 2572903460327860111, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/usecols/test_parse_dates.py": 5344929031479212951, - "venv/lib/python3.13/site-packages/pydantic/_internal/_schema_generation_shared.py": 23345689300073549, - "venv/lib/python3.13/site-packages/starlette/background.py": 10232175205397808417, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_describe.py": 14493300276133670380, - "venv/lib/python3.13/site-packages/pandas/io/iceberg.py": 13137128885014736233, - "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_freq_attr.py": 1720704043778272895, - "venv/lib/python3.13/site-packages/pyasn1/__init__.py": 8089201217593738032, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/jsonschema_specifications/__init__.py": 5732822354953774657, - "venv/lib/python3.13/site-packages/pip/_internal/utils/logging.py": 9639351759822608724, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge.py": 11366935134260232329, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_drop_duplicates.py": 5874427993953991216, - "venv/lib/python3.13/site-packages/jsonschema/tests/fuzz_validate.py": 2328585939822059352, - "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/WHEEL": 13232065379159720345, - "venv/lib/python3.13/site-packages/authlib/integrations/sqla_oauth2/__init__.py": 12911374670789466961, - "venv/lib/python3.13/site-packages/authlib/integrations/flask_client/apps.py": 10758062668702044519, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7516/__init__.py": 11121941644106061453, - "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/RECORD": 9803861100978586236, - "venv/lib/python3.13/site-packages/websockets/legacy/protocol.py": 762692033188392424, - "venv/lib/python3.13/site-packages/httpx/_status_codes.py": 1758440600462491839, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/shape_base.pyi": 5046405609030418900, - "venv/lib/python3.13/site-packages/rapidfuzz/fuzz_py.py": 6428078990080243608, - "venv/lib/python3.13/site-packages/numpy/random/tests/data/mt19937-testset-2.csv": 14641856424618845798, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/size/foo.f90": 18067977329435720684, + "venv/lib/python3.13/site-packages/numpy/_core/_type_aliases.pyi": 15848834171197104301, "venv/lib/python3.13/site-packages/pandas/util/_tester.py": 1033951890304257539, - "venv/lib/python3.13/site-packages/pandas/tests/window/test_base_indexer.py": 3129123098288498633, - "venv/lib/python3.13/site-packages/pandas/tests/io/test_compression.py": 3167245427092658522, - "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_macos.py": 7028037591427052891, - "venv/lib/python3.13/site-packages/urllib3/contrib/pyopenssl.py": 11839715589709210412, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_polynomial.py": 3049262771098624825, - "venv/lib/python3.13/site-packages/pygments/lexers/ada.py": 17032408976634308999, - "backend/src/services/llm_provider.py": 3024842945367976592, - "venv/lib/python3.13/site-packages/pydantic_settings/exceptions.py": 18300876747412267999, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_x64_masm.asm": 15349921092257597740, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_resolution.py": 9651416588266430520, - "venv/lib/python3.13/site-packages/pandas/io/pytables.py": 17482934215513855928, - "venv/lib/python3.13/site-packages/passlib/tests/test_crypto_des.py": 7198931807116651263, - "venv/lib/python3.13/site-packages/idna/compat.py": 9758194415584776667, - "venv/lib/python3.13/site-packages/pygments/lexers/_css_builtins.py": 17478340487186531268, - "venv/lib/python3.13/site-packages/numpy/lib/_type_check_impl.py": 15989335816452913951, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_partial_slicing.py": 15567512240469921599, - "venv/lib/python3.13/site-packages/_pytest/doctest.py": 6126919596776592278, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/random.pyi": 9425735458050148191, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/conftest.py": 16571782049241458769, - "venv/lib/python3.13/site-packages/jose/exceptions.py": 8562012933958941039, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_non_unique.py": 15286893322149413712, - "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/WHEEL": 7454950858448014158, - "venv/lib/python3.13/site-packages/jeepney/bindgen.py": 7094585345946943534, - "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/METADATA": 13776251749114562660, - "venv/lib/python3.13/site-packages/pip/_internal/network/utils.py": 13421242949994555055, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-tanh.csv": 6674536825156196036, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/data_common.f": 5913807803369559749, - "venv/lib/python3.13/site-packages/numpy/lib/_shape_base_impl.py": 16539612003028676816, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_frame.py": 2169381747938271444, - "venv/lib/python3.13/site-packages/pydantic/v1/version.py": 2758971830527526972, - "venv/lib/python3.13/site-packages/httpx/_exceptions.py": 18399489130669465891, - "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/serialize.py": 11139432164346742421, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ndarray_shape_manipulation.pyi": 3533739482029983817, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/Jaro_py.py": 11991492232381887787, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_isoc.py": 4923640657296076239, - "venv/lib/python3.13/site-packages/pandas/io/formats/console.py": 10370334487585281127, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/engines.py": 10876954465293959720, - "venv/lib/python3.13/site-packages/numpy/_core/memmap.py": 4093510602708416858, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/reflection.py": 1799734694597531652, - "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/immutabledict.cpython-313-x86_64-linux-gnu.so": 12776951671822017500, - "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/RECORD": 9678861487447993169, - "venv/lib/python3.13/site-packages/cryptography/x509/general_name.py": 4481582226129488535, - "venv/lib/python3.13/site-packages/PIL/JpegPresets.py": 12342262642420923471, - "venv/lib/python3.13/site-packages/numpy/lib/array_utils.pyi": 14646405559193539455, - "venv/lib/python3.13/site-packages/pandas/_libs/join.cpython-313-x86_64-linux-gnu.so": 2947947484481830203, - "venv/lib/python3.13/site-packages/cffi/_imp_emulation.py": 17246725564704952212, - "venv/lib/python3.13/site-packages/pygments/lexers/typoscript.py": 6706632522710582762, - "frontend/src/lib/components/assistant/__tests__/assistant_first_message.integration.test.js": 16494645867501045726, - "frontend/src/lib/components/translate/CorrectionCell.svelte": 4880217280855576250, - "frontend/build/_app/immutable/assets/0.DpIDeCZ3.css": 7055983390808293488, - "backend/src/api/routes/dataset_review_pkg/_dependencies.py": 15939232213193276681, - "venv/lib/python3.13/site-packages/pip/_vendor/tomli_w/py.typed": 9796674040111366709, - "venv/lib/python3.13/site-packages/numpy/random/tests/data/mt19937-testset-1.csv": 16349400027062875699, - "venv/lib/python3.13/site-packages/iniconfig/_version.py": 8497474654470220170, - "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/licenses/LICENSE": 16147999986886816451, - "venv/lib/python3.13/site-packages/fastapi/middleware/__init__.py": 5289703478893407762, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/gh26920/two_mods_with_one_public_routine.f90": 7957683453180939605, - "venv/lib/python3.13/site-packages/pandas/tests/window/moments/test_moments_consistency_expanding.py": 12504275097476819918, - "venv/lib/python3.13/site-packages/authlib/integrations/base_client/framework_integration.py": 3935346152156572025, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/openssl/binding.py": 17078280153372356796, - "venv/lib/python3.13/site-packages/greenlet/TThreadStateDestroy.cpp": 13749797532421836328, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/_pytest/hookspec.py": 387790426108810884, - "venv/lib/python3.13/site-packages/pandas/core/groupby/ops.py": 2036968385544457016, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_pop.py": 5700439923973346681, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/cache_key.py": 11118819065204404106, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_qcut.py": 8972418112914954758, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/types.py": 16795741817129898714, - "venv/lib/python3.13/site-packages/pandas/tests/extension/base/setitem.py": 9552868454186447925, - "venv/lib/python3.13/site-packages/more_itertools/more.py": 1631135582441184133, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py": 16386268386376675175, - "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pandas/tests/construction/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_loadtxt.py": 17562784940619942447, - "venv/lib/python3.13/site-packages/httpcore/_backends/anyio.py": 6167729964577005634, - "venv/lib/python3.13/site-packages/pandas/core/groupby/generic.py": 4857114071347950833, - "venv/lib/python3.13/site-packages/passlib/tests/test_context_deprecated.py": 7876919198015151018, - "frontend/src/lib/ui/Select.svelte": 11354509509920497811, - "frontend/build/_app/immutable/nodes/28.BeU7bdHC.js": 11715772981654521705, - "backend/src/api/routes/clean_release_v2.py": 2858037566596334612, - "backend/tests/test_translate_executor_filter.py": 11717560360659156703, - "frontend/build/_app/immutable/nodes/1.Bqvpw8Vl.js": 16310728508939338800, - "venv/lib/python3.13/site-packages/jsonschema/benchmarks/validator_creation.py": 2745563768861102999, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-log10.csv": 13441294827017400897, - "venv/lib/python3.13/site-packages/passlib/tests/test_crypto_builtin_md4.py": 16840174243259839994, - "venv/lib/python3.13/site-packages/pydantic/alias_generators.py": 5991580234179623842, - "backend/src/core/superset_client/_dashboards_crud.py": 4664728216214173491, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_deprecations.py": 6015734648984591027, - "backend/src/models/dataset_review_pkg/_semantic_models.py": 15376906129805121935, - "backend/src/plugins/llm_analysis/models.py": 11561165853127709481, - "venv/lib/python3.13/site-packages/numpy/linalg/tests/test_linalg.py": 2939739913218718132, - "venv/lib/python3.13/site-packages/pandas/tests/series/test_iteration.py": 15247340610412364508, - "venv/lib/python3.13/site-packages/pygments/cmdline.py": 15628499088643246809, - "frontend/build/_app/immutable/chunks/BDmwnQQF.js": 1134144008713893143, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/multiarray.py": 3224049574922696945, - "venv/lib/python3.13/site-packages/pandas/tests/interchange/test_impl.py": 12056958946481531279, - "venv/lib/python3.13/site-packages/git/objects/tree.py": 10239027037919781330, - "backend/src/schemas/dataset_review.py": 15720223123457526104, - "venv/lib/python3.13/site-packages/pip/_internal/operations/build/metadata.py": 2021612995853910808, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/prompt.py": 9561640601516933380, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_copy.py": 11335108864615756235, - "venv/lib/python3.13/site-packages/httpcore/_api.py": 16499985295426060327, - "venv/lib/python3.13/site-packages/pygments/formatters/irc.py": 2133711525226123259, - "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_indexing.py": 81180636019259296, - "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/WHEEL": 15858869568085970864, - "venv/lib/python3.13/site-packages/attr/setters.py": 12467854389745942025, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_regression.py": 4611768764484593979, - "venv/lib/python3.13/site-packages/pandas/core/frame.py": 2630807744775247533, - "venv/lib/python3.13/site-packages/pandas/tests/extension/decimal/__init__.py": 4761936067832638585, - "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_concat.py": 10207975532842927134, - "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/METADATA": 2604612822968175379, - "venv/lib/python3.13/site-packages/_pytest/unraisableexception.py": 4597178803320514675, - "backend/src/models/__tests__/test_report_models.py": 14916807060334836854, - "venv/lib/python3.13/site-packages/keyring/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/scanner.py": 5640381644804445932, - "venv/lib/python3.13/site-packages/passlib/handlers/oracle.py": 12959175637015399815, - "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_argon2.py": 11345706437113628133, - "venv/lib/python3.13/site-packages/packaging/pylock.py": 15346942039643310253, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7636/__init__.py": 913610541217778747, - "venv/lib/python3.13/site-packages/passlib/tests/sample1c.cfg": 13088198405762342506, - "venv/lib/python3.13/site-packages/pygments/lexers/dns.py": 17149871769553794654, - "venv/lib/python3.13/site-packages/pip/_internal/models/search_scope.py": 9282393652860589543, - "venv/lib/python3.13/site-packages/fastapi/openapi/constants.py": 1111838716953068285, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/hkdf.py": 8539232219382152238, - "venv/lib/python3.13/site-packages/pip/_internal/utils/_jaraco_text.py": 9046755357011730699, - "venv/lib/python3.13/site-packages/pip/_internal/cli/__init__.py": 11914508471759255927, - "venv/lib/python3.13/site-packages/PIL/Hdf5StubImagePlugin.py": 15654153796225833950, - "venv/lib/python3.13/site-packages/_pytest/terminal.py": 885450969703476729, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/__init__.py": 13584649922093198724, - "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/signals.py": 13677199634497673845, - "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py": 17873236864291624476, - "venv/lib/python3.13/site-packages/pydantic/_internal/_mock_val_ser.py": 12265320534388472158, - "backend/src/core/utils/network.py": 2917454689057905472, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_dataframe.py": 14945138617962156057, - "venv/lib/python3.13/site-packages/h11/_events.py": 13800479928851716538, - "venv/lib/python3.13/site-packages/numpy/_utils/_inspect.py": 7029935879540617057, - "venv/lib/python3.13/site-packages/PIL/_util.py": 17116054813914373606, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_offsets.py": 4499538899492148499, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_header.py": 3564391095263545879, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/type_check.pyi": 9177256991985898824, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_datetimes.py": 7889573945417063183, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/JaroWinkler_py.py": 16189204441438239231, - "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_printing.py": 8859757563354666575, - "venv/lib/python3.13/site-packages/pandas/io/sas/sas7bdat.py": 17851617851457266799, - "venv/lib/python3.13/site-packages/websockets/sync/client.py": 10892557975919033983, - "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/licenses/COPYING": 14459782230785388765, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/arrayterator.py": 3076316311545674897, - "venv/lib/python3.13/site-packages/pip/_vendor/distlib/resources.py": 11533706401259147051, - "venv/lib/python3.13/site-packages/numpy/strings/__init__.pyi": 6213864891045042045, - "backend/src/services/clean_release/repositories/__init__.py": 9926779835387630811, - "venv/lib/python3.13/site-packages/smmap/test/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/test_aggregate.py": 15038915958422670700, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/jwk.py": 6458001384702613165, - "venv/lib/python3.13/site-packages/pip/_internal/cli/base_command.py": 10660882478126415399, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/matrix.pyi": 15667024840812783911, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_construction.py": 6564829381134214401, - "venv/lib/python3.13/site-packages/fastapi/dependencies/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/METADATA": 14543822270526146783, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/expression.py": 15511250785671695359, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_shape_base.py": 8837845103338426570, - "venv/lib/python3.13/site-packages/authlib/jose/rfc8037/__init__.py": 8705044848308260480, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/instrumentation.py": 13198832283145198959, - "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/__init__.py": 12793458753561114666, - "venv/lib/python3.13/site-packages/numpy/core/arrayprint.py": 9652368112174245943, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_year.py": 17441853503700184299, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/arithmetic.py": 3209727509456212551, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_where.py": 16584772339591698754, - "venv/lib/python3.13/site-packages/numpy/_utils/__init__.py": 7731065084036767848, - "venv/lib/python3.13/site-packages/git/objects/submodule/__init__.py": 12958523219496107878, - "frontend/src/pages/Dashboard.svelte": 3653104499351855122, - "frontend/src/lib/api/assistant.js": 15470667170083225911, - "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_defmatrix.py": 2982572083770917411, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8693/__init__.py": 11065844267208884531, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_analytics.py": 4510712334676848202, - "venv/lib/python3.13/site-packages/pip/_internal/cli/parser.py": 1064209424435927674, - "venv/lib/python3.13/site-packages/authlib/integrations/starlette_client/apps.py": 4219758952914498116, - "venv/lib/python3.13/site-packages/idna/codec.py": 4260241549062101779, - "venv/lib/python3.13/site-packages/fastapi/security/api_key.py": 6965937678104291169, - "venv/lib/python3.13/site-packages/pandas/core/util/hashing.py": 13106575357604888913, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_real/foo77.f": 16156304612888138777, - "venv/lib/python3.13/site-packages/pandas/tests/frame/test_query_eval.py": 17613800806748649144, - "venv/lib/python3.13/site-packages/rsa/__init__.py": 14623742580410014505, - "venv/lib/python3.13/site-packages/greenlet/greenlet.h": 16216120538647882082, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_asof.py": 17616601748321325187, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_pickle.py": 16196792378104396231, - "venv/lib/python3.13/site-packages/fastapi/logger.py": 11590581556317053213, - "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/METADATA": 12295263493152296681, - "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/limited_api2.pyx": 15936470837420356071, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_indexing.py": 3841182456456779012, - "venv/lib/python3.13/site-packages/pandas/tests/extension/base/base.py": 14908084548919567658, - "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_parse_iso8601.py": 9100947620267156161, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_multiprocessing.py": 5522490547285108448, - "venv/lib/python3.13/site-packages/pyasn1/codec/streaming.py": 13202773554072937140, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_hour.py": 13754646634123368797, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_subclass.py": 10949229764696473939, - "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/immutabledict.pyx": 11739218099400096619, - "venv/lib/python3.13/site-packages/PIL/_avif.cpython-313-x86_64-linux-gnu.so": 5243449968857258659, - "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/RECORD": 12598309574903741388, - "venv/lib/python3.13/site-packages/attr/_typing_compat.pyi": 2823472697859409877, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_take.py": 14969455660160053080, - "venv/lib/python3.13/site-packages/pandas/_version_meson.py": 4875297137037630519, - "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/resolution.py": 5132658725516243311, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_ints.py": 5616705208267050659, - "venv/lib/python3.13/site-packages/pandas/_config/display.py": 433650013567734821, - "venv/lib/python3.13/site-packages/pip/_internal/commands/list.py": 13035925292530461722, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_common.py": 9097104320321411408, - "venv/lib/python3.13/site-packages/pydantic/json.py": 4109352930301629308, - "venv/lib/python3.13/site-packages/pygments/lexers/zig.py": 470431199354307668, - "venv/lib/python3.13/site-packages/_pytest/logging.py": 10972553724755511468, - "venv/lib/python3.13/site-packages/pydantic/deprecated/copy_internals.py": 1245428320513062166, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_stringdtype.py": 8381476847196129074, - "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/sum_.py": 7062070517544958546, - "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/RECORD": 7363618870628306370, - "venv/lib/python3.13/site-packages/pip/__main__.py": 574438877257676911, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/errors.py": 14634768861119075506, - "venv/lib/python3.13/site-packages/pandas/core/reshape/concat.py": 2218848863149192467, - "venv/lib/python3.13/site-packages/pip/_internal/operations/check.py": 16650663913976953800, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_argparse.py": 11111699418217357084, - "venv/lib/python3.13/site-packages/numpy/core/_dtype.pyi": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/transform/test_numba.py": 8250377774229977284, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_conversion_utils.py": 1567199588622767277, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_na_values.py": 13527837495439739279, - "venv/lib/python3.13/site-packages/pygments/lexers/sas.py": 6128008194712914874, - "frontend/src/components/git/GitManager.svelte": 10046788495793334635, - "venv/lib/python3.13/site-packages/pandas/tests/generic/test_finalize.py": 12539815426478689538, - "venv/lib/python3.13/site-packages/pandas/tests/io/test_common.py": 10797243274520625867, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/profiling.py": 16030397164203895281, - "venv/lib/python3.13/site-packages/anyio/abc/_streams.py": 8089057973257658396, - "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/applicator": 6870991911243684132, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/use_modules.f90": 3913612933340746297, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_monotonic.py": 14648437502004398715, - "venv/lib/python3.13/site-packages/pandas/tests/frame/test_reductions.py": 3227705565578016389, - "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/RECORD": 16558021503346615951, - "venv/lib/python3.13/site-packages/smmap/__init__.py": 4557520096828426601, - "venv/lib/python3.13/site-packages/iniconfig/exceptions.py": 16501270224069836264, - "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/httpcore/_backends/mock.py": 6849131425727092784, - "venv/lib/python3.13/site-packages/dateutil/_version.py": 8279235793001245767, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py": 6067836157632573182, - "venv/lib/python3.13/site-packages/keyring/testing/backend.py": 14295829193445781542, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/flatiter.py": 3066469329738423021, - "venv/lib/python3.13/site-packages/pandas/tests/api/test_types.py": 8889829773923216769, - "venv/lib/python3.13/site-packages/pandas/_libs/reshape.cpython-313-x86_64-linux-gnu.so": 10639750501333255943, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/rsa_key.py": 7092106298733667895, - "venv/lib/python3.13/site-packages/requests/structures.py": 2668010839316715865, - "venv/lib/python3.13/site-packages/passlib/crypto/scrypt/_builtin.py": 74545289993348593, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/extension/base/dim2.py": 5767600151459095125, - "venv/lib/python3.13/site-packages/pandas/tests/strings/conftest.py": 12065119814157197510, - "venv/lib/python3.13/site-packages/dateutil/parser/__init__.py": 11377431154251655738, - "venv/lib/python3.13/site-packages/pip/_vendor/tomli_w/_writer.py": 15053365792216907149, - "venv/lib/python3.13/site-packages/pandas/tests/io/test_gcs.py": 7733247456252965901, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/ccalendar.cpython-313-x86_64-linux-gnu.so": 11019871270094058038, - "venv/lib/python3.13/site-packages/pip/_internal/utils/compat.py": 1841193561752758336, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/foo_deps.f90": 14350239197565389508, - "venv/lib/python3.13/site-packages/uvicorn/lifespan/off.py": 16254524872582859561, - "venv/lib/python3.13/site-packages/fastapi/_compat/main.py": 13016492818231995760, - "venv/lib/python3.13/site-packages/numpy/tests/test_configtool.py": 8208415015478205502, - "backend/tests/services/clean_release/test_demo_mode_isolation.py": 1970652424726919519, - "venv/lib/python3.13/site-packages/ecdsa/test_rw_lock.py": 1572802971060634697, - "venv/lib/python3.13/site-packages/greenlet/tests/fail_initialstub_already_started.py": 5562030563802006923, - "venv/lib/python3.13/site-packages/websockets/speedups.c": 11800200877763464246, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_einsum.py": 17286384318722237180, - "venv/lib/python3.13/site-packages/PIL/FitsImagePlugin.py": 618556384932056120, - "venv/lib/python3.13/site-packages/pip/_vendor/msgpack/ext.py": 15699809032725838985, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_astype.py": 11386658862732393123, - "venv/lib/python3.13/site-packages/pydantic_core/_pydantic_core.cpython-313-x86_64-linux-gnu.so": 13917011878259810696, - "venv/lib/python3.13/site-packages/sqlalchemy/exc.py": 6372950288664776625, - "venv/lib/python3.13/site-packages/pygments/lexers/floscript.py": 944042220740663491, - "venv/lib/python3.13/site-packages/PIL/FontFile.py": 112053841436523305, - "frontend/src/lib/auth/store.ts": 14669655798912377598, - "venv/lib/python3.13/site-packages/numpy/_core/defchararray.pyi": 2277933368373498515, - "venv/lib/python3.13/site-packages/pandas/_libs/__init__.py": 17117112389651696580, - "venv/lib/python3.13/site-packages/numpy/random/_mt19937.cpython-313-x86_64-linux-gnu.so": 85866616759631810, - "venv/lib/python3.13/site-packages/pip/_internal/cli/main_parser.py": 7942770969280622910, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/cli/hi77.f": 10617763407280454334, - "venv/lib/python3.13/site-packages/pandas/_libs/arrays.pyi": 12629806207276576877, - "venv/lib/python3.13/site-packages/pandas/core/groupby/numba_.py": 15997665748332235683, - "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/authlib/integrations/sqla_oauth2/functions.py": 14107377669163193871, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/ccalendar.pyi": 15789956857032062129, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_floats.py": 3064615530495290792, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_dtypes.py": 6831042272921908068, - "venv/lib/python3.13/site-packages/urllib3/poolmanager.py": 15431313180245757657, - "venv/bin/activate": 14735074000123383125, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/poolmanager.py": 5071697837617938064, - "frontend/src/routes/+error.svelte": 16649211425103750277, - "frontend/build/_app/immutable/nodes/36.BfewuKxM.js": 16060258850338526744, - "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_numeric.py": 17391095502314929042, - "backend/src/core/migration/risk_assessor.py": 1061977005072298440, - "venv/lib/python3.13/site-packages/numpy/lib/_array_utils_impl.pyi": 11535882608355652318, - "venv/lib/python3.13/site-packages/pandas/compat/__init__.py": 6077099417711209303, - "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py": 5324490103277723813, - "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/RECORD": 4487477737768669516, - "frontend/build/_app/immutable/nodes/20.BNq1dr4D.js": 14340650458933574612, - "backend/tests/core/test_mapping_service.py": 6888870177029085220, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/conftest.py": 2643915042664055969, - "venv/lib/python3.13/site-packages/click/core.py": 16793133181718891193, - "venv/lib/python3.13/site-packages/pydantic/v1/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/plotting/__init__.py": 13230487326686617492, - "venv/lib/python3.13/site-packages/pygments/lexers/numbair.py": 17382646010399794697, - "venv/lib/python3.13/site-packages/fastapi/templating.py": 10760135144345238340, - "venv/lib/python3.13/site-packages/pygments/lexers/meson.py": 14659991367778746658, - "backend/src/api/routes/translate/_dictionary_routes.py": 13818233841800263162, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arcsin.csv": 1665171675551692225, - "venv/lib/python3.13/site-packages/pandas/tests/generic/test_series.py": 2980850649986213051, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_errstate.py": 10788459171326750780, - "venv/lib/python3.13/site-packages/starlette/authentication.py": 10905269573809129547, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/_cryptography_key.py": 388489172928969873, - "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/converter.py": 9041278869295701566, - "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_struct_accessor.py": 6567451952835390075, - "venv/lib/python3.13/site-packages/_pytest/junitxml.py": 5871715626272366062, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_encoding.py": 6622474614967398246, - "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_json_table_schema_ext_dtype.py": 13021437050542691118, - "venv/lib/python3.13/site-packages/sqlalchemy/event/api.py": 987321343916500337, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_ndarray_backed.py": 10097812802469682233, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_overlaps.py": 2328652590379935311, - "venv/lib/python3.13/site-packages/pygments/lexers/scdoc.py": 8481749542463754279, - "venv/lib/python3.13/site-packages/pygments/styles/tango.py": 12389250878249075539, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/_typing.py": 17589387690638097975, - "venv/lib/python3.13/site-packages/pygments/lexers/smv.py": 8253688483040957894, - "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_distutils.py": 1948707545068786, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_scalar_compat.py": 1306236983392218709, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/dtypes/test_dtypes_basic.py": 10917162988625838981, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/discovery.py": 12479996594187326798, - "venv/lib/python3.13/site-packages/pandas/core/interchange/buffer.py": 12961802206383700922, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/DamerauLevenshtein_py.py": 1933257612725836484, - "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/METADATA": 14180973198574731599, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/__init__.py": 14571251344510763303, - "venv/lib/python3.13/site-packages/numpy/f2py/setup.cfg": 17974180080760231128, - "venv/lib/python3.13/site-packages/cryptography/hazmat/backends/__init__.py": 18019562641348687547, - "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/misc.py": 6571241778569465264, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_skiprows.py": 8764515842253490735, - "venv/lib/python3.13/site-packages/keyring/util/platform_.py": 16978095707950463638, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/structs.py": 4479429145468072604, - "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/rsa.py": 5392922995791487437, - "venv/lib/python3.13/site-packages/pandas/tests/frame/test_logical_ops.py": 16166386974005224415, - "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_timezones.py": 1962830142478494009, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/mariadbconnector.py": 14865906347579451546, - "frontend/src/lib/api/__tests__/reports_api.test.js": 11820587361929895100, - "venv/lib/python3.13/site-packages/typing_inspection/typing_objects.py": 16856718240972376883, - "venv/lib/python3.13/site-packages/jeepney/io/asyncio.py": 13239992245695516007, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_nditer.py": 8341339612899904236, - "venv/lib/python3.13/site-packages/pandas/core/strings/accessor.py": 14021462534679430426, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh24008.f": 3872245077994936272, - "venv/lib/python3.13/site-packages/urllib3/util/proxy.py": 17667887856427739069, - "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/itsdangerous/serializer.py": 14271229091461164933, - "venv/lib/python3.13/site-packages/pip/_vendor/requests/models.py": 17870758731501836303, - "venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/pluggy/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pillow.libs/libavif-01e67780.so.16.3.0": 13947441788826399574, - "venv/lib/python3.13/site-packages/httpx/_urls.py": 4219389176352582046, - "venv/lib/python3.13/site-packages/websockets/cli.py": 14049106025886056110, - "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/cython/setup.py": 17086801293303202021, - "venv/lib/python3.13/site-packages/pandas/core/arrays/boolean.py": 8821671562937866269, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/period/test_asfreq.py": 6162659555626011770, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/properties.py": 5799883762127872919, - "venv/lib/python3.13/site-packages/pygments/lexers/_mapping.py": 12987629396101138833, - "venv/lib/python3.13/site-packages/numpy/_core/_multiarray_tests.cpython-313-x86_64-linux-gnu.so": 442168371609469538, - "venv/lib/python3.13/site-packages/PIL/_imagingcms.pyi": 12476347428820346383, - "frontend/src/routes/datasets/review/__tests__/dataset_review_entry.ux.test.js": 5439236328736424365, - "venv/lib/python3.13/site-packages/keyring/backends/Windows.py": 4103830951042463184, - "venv/lib/python3.13/site-packages/anyio/abc/_subprocesses.py": 4297459042599291531, - "venv/lib/python3.13/site-packages/passlib/tests/tox_support.py": 9200774792427691602, - "venv/lib/python3.13/site-packages/fastapi/openapi/utils.py": 9058442333718187759, - "frontend/build/index.html": 6110200597222080248, - "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_openpyxl.py": 9542840527483618681, - "venv/lib/python3.13/site-packages/packaging/metadata.py": 9168255069163141470, - "venv/lib/python3.13/site-packages/pandas/core/dtypes/common.py": 10996276696597806957, - "frontend/src/components/storage/FileList.svelte": 11661146151896000393, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_rank.py": 5817408252050193538, - "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/cffi/error.py": 8147505969912539538, - "frontend/build/_app/immutable/chunks/D5BsboTl.js": 12208458907620838691, - "backend/src/plugins/translate/__tests__/test_token_budget.py": 9060506557524997011, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/filter.py": 16846063190466267618, - "backend/src/api/routes/__tests__/test_dashboards.py": 14899529124453053148, - "venv/lib/python3.13/site-packages/apscheduler/util.py": 11440701924954413440, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh25286.pyf": 14358606965464506398, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_dtype.py": 12210524152630532747, - "venv/lib/python3.13/site-packages/pandas/core/array_algos/putmask.py": 10934101690788549526, - "venv/lib/python3.13/site-packages/pip/_vendor/pygments/plugin.py": 18006138132596504101, - "venv/lib/python3.13/site-packages/pydantic/validate_call_decorator.py": 11130572937843915026, - "venv/lib/python3.13/site-packages/pandas/_libs/pandas_datetime.cpython-313-x86_64-linux-gnu.so": 15874094681262240628, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_replace.py": 8165088653532047247, - "venv/lib/python3.13/site-packages/passlib/handlers/roundup.py": 3844280972451753019, - "venv/lib/python3.13/site-packages/pandas/tests/frame/test_subclass.py": 16342917051908786497, - "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arctanh.csv": 8620268345075425735, - "venv/lib/python3.13/site-packages/pandas/io/excel/_odswriter.py": 17220892094904423676, - "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/__init__.py": 1437580234680265326, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_argsort.py": 7320661835159648143, - "venv/lib/python3.13/site-packages/anyio/_core/_signals.py": 1204322949639513552, - "venv/lib/python3.13/site-packages/pydantic/_internal/_discriminated_union.py": 1818179910730401509, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_constructors.py": 11786151805350138436, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/identity.py": 326059526167697655, - "venv/lib/python3.13/site-packages/secretstorage/dhcrypto.py": 8860116996905452758, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_dot.py": 16876560325283070437, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/json.py": 14738429697319670035, - "venv/lib/python3.13/site-packages/pygments/lexers/ezhil.py": 10294520768762308887, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/errors.py": 10750605030539582738, - "venv/lib/python3.13/site-packages/numpy/polynomial/polynomial.py": 7658234162211356265, - "frontend/build/_app/immutable/nodes/30.BHAvSo-A.js": 13327487733725668780, - "frontend/build/_app/immutable/chunks/D0X9GEx9.js": 7204815795777103850, - "venv/lib/python3.13/site-packages/numpy/_core/fromnumeric.py": 9409852116555866847, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_arrayterator.py": 1646530870049791291, - "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/macos.py": 17442393555211213147, - "venv/lib/python3.13/site-packages/apscheduler/schedulers/tornado.py": 6491136785917169991, - "venv/lib/python3.13/site-packages/pandas/tests/series/test_validate.py": 2133732492454460539, - "venv/lib/python3.13/site-packages/pandas/tests/io/json/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/PIL/IcnsImagePlugin.py": 1870235606309784691, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/common.py": 11384497819737275399, - "venv/lib/python3.13/site-packages/charset_normalizer/version.py": 9948878594498587774, - "venv/lib/python3.13/site-packages/dateutil/zoneinfo/__init__.py": 10261654903106416888, - "venv/lib/python3.13/site-packages/tzlocal/win32.py": 1949985224569608978, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_factorize.py": 861897342553280506, - "venv/lib/python3.13/site-packages/click/utils.py": 13475604420010022458, - "venv/lib/python3.13/site-packages/_pytest/pastebin.py": 13946273207624603063, - "backend/src/plugins/translate/_utils.py": 4311334421388625700, - "venv/lib/python3.13/site-packages/_pytest/setupplan.py": 7496801885995567141, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_drop_duplicates.py": 2397396876872403048, - "venv/lib/python3.13/site-packages/pydantic/_internal/_model_construction.py": 694471028676746110, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/accesstype.f90": 877982462186396830, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ufuncs.py": 12732599294816239111, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_categorical_equal.py": 7942323667866280872, - "venv/lib/python3.13/site-packages/pip/_vendor/distro/__init__.py": 11414161642984633362, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/visitors.py": 5190923415390076080, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/__init__.py": 16434403703599680307, - "venv/lib/python3.13/site-packages/jsonschema/tests/test_utils.py": 8668650648802195016, - "venv/lib/python3.13/site-packages/click/_textwrap.py": 14586282603215052310, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/common.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/PIL/PSDraw.py": 1927169421822446045, - "venv/lib/python3.13/site-packages/numpy/polynomial/_polybase.py": 893743087939984792, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/color.py": 15062855556511243610, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_fileno.py": 15541504502174047167, - "venv/lib/python3.13/site-packages/pandas/io/__init__.py": 9767690163638898709, - "venv/bin/pyrsa-encrypt": 5858278204727417482, - "backend/src/core/__tests__/test_superset_profile_lookup.py": 15590077829286810714, - "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/METADATA": 3390257212824996989, - "venv/lib/python3.13/site-packages/fastapi/types.py": 3867821246650502267, - "backend/src/api/routes/translate/_job_routes.py": 6716903871937439968, - "venv/lib/python3.13/site-packages/referencing/_attrs.py": 14434891919747863272, - "scripts/gen_semantics.py": 11397714264377363083, - "venv/lib/python3.13/site-packages/pandas/tests/test_flags.py": 411845322592830527, - "venv/lib/python3.13/site-packages/numpy/_core/_struct_ufunc_tests.cpython-313-x86_64-linux-gnu.so": 13269324887178340397, - "backend/src/api/routes/translate/_correction_routes.py": 17010744610493077227, - "venv/lib/python3.13/site-packages/numpy/typing/mypy_plugin.py": 1306129775649200113, - "venv/lib/python3.13/site-packages/httpx/_transports/__init__.py": 5931944625631942279, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7521/client.py": 17305914656270781911, - "venv/lib/python3.13/site-packages/pip/_internal/commands/lock.py": 14782882714168174465, - "venv/lib/python3.13/site-packages/pip/_vendor/packaging/metadata.py": 7204343250279221076, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/_elements_constructors.py": 9279447066034364952, - "venv/lib/python3.13/site-packages/urllib3/py.typed": 12220177918227495093, - "venv/lib/python3.13/site-packages/httpx/_multipart.py": 2181282475656908730, - "venv/lib/python3.13/site-packages/attr/_compat.py": 4016698632899969390, - "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/RECORD": 12575893084587070195, - "venv/lib/python3.13/site-packages/pip/_internal/resolution/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/apscheduler/schedulers/background.py": 2105814165112049750, - "venv/lib/python3.13/site-packages/jeepney/io/tests/test_trio.py": 7459901627473962540, - "venv/lib/python3.13/site-packages/greenlet/tests/test_throw.py": 4119265751381210399, - "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/licenses/COPYING": 15270149301471737292, - "venv/lib/python3.13/site-packages/pydantic/deprecated/tools.py": 16466182352694741629, - "venv/lib/python3.13/site-packages/pip/_internal/index/collector.py": 7454652626329467900, - "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/numpy/lib/_npyio_impl.pyi": 6576645822227068922, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame_groupby.py": 12709199432838648700, - "venv/lib/python3.13/site-packages/numpy/polynomial/__init__.pyi": 8708830448398500675, - "venv/lib/python3.13/site-packages/numpy/lib/array_utils.py": 18135114588643176359, - "venv/lib/python3.13/site-packages/passlib/handlers/digests.py": 18158237109145814857, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_set_axis.py": 4097534573847151853, - "venv/lib/python3.13/site-packages/pandas/tests/window/test_groupby.py": 15721254196883995634, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_fillna.py": 7349777469648334282, - "venv/lib/python3.13/site-packages/pandas/tests/generic/test_to_xarray.py": 15341013524814290960, - "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_file_handling.py": 732772718210067599, - "venv/lib/python3.13/site-packages/urllib3/connectionpool.py": 7493427857878469165, - "venv/lib/python3.13/site-packages/PIL/ImageWin.py": 13635870584232081323, - "venv/lib/python3.13/site-packages/pygments/filters/__init__.py": 2992007913496948339, - "venv/lib/python3.13/site-packages/pygments/lexers/ldap.py": 17455983150181177257, - "frontend/src/lib/stores/__tests__/mocks/navigation.js": 10782992736745205981, - "frontend/src/lib/components/translate/__tests__/test_bulk_replace_modal.svelte.js": 6802604718120565742, - "backend/src/scripts/init_auth_db.py": 7729644769215024318, - "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/json.py": 6429651405841289922, - "venv/lib/python3.13/site-packages/apscheduler/executors/asyncio.py": 2230610508870117058, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/shape.pyi": 17197248408326188931, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_validate_kwargs.py": 10173906126211473463, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_indexers.py": 6773751569163287047, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/np_datetime.pyi": 2884703536776830012, - "venv/lib/python3.13/site-packages/pandas/tests/extension/test_categorical.py": 1329115818264527103, - "venv/lib/python3.13/site-packages/pandas/core/computation/check.py": 16048939716341154196, - "venv/lib/python3.13/site-packages/sqlalchemy/connectors/asyncio.py": 4200928269459447593, - "venv/lib/python3.13/site-packages/yaml/parser.py": 18021832376874455801, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/ed25519.py": 2285778903282667561, - "venv/lib/python3.13/site-packages/numpy/ma/mrecords.py": 687170905107114309, - "venv/lib/python3.13/site-packages/pandas/core/indexes/period.py": 1181348384346239378, - "venv/lib/python3.13/site-packages/idna-3.11.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/urllib3/util/connection.py": 15511685694589961094, - "venv/lib/python3.13/site-packages/pygments/lexers/__init__.py": 4627540245914849670, - "venv/lib/python3.13/site-packages/packaging/utils.py": 3469957615920103670, - "frontend/src/types/backup.ts": 1741234034896689348, - "frontend/src/lib/stores/__tests__/sidebar.test.js": 5168138864675110669, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_validate_inclusive.py": 1389676378885557519, - "venv/lib/python3.13/site-packages/pip/_internal/main.py": 13711402795965346761, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_palettes.py": 13495896173068490516, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_functions.py": 16376319335326812580, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_overlaps.py": 8287716909793575347, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_indexing.py": 546024765756472196, - "venv/lib/python3.13/site-packages/pygments/formatters/latex.py": 7514533384468139434, - "venv/lib/python3.13/site-packages/keyring/compat/py312.py": 17581691618899404491, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/elements.py": 11185011314498348980, - "venv/lib/python3.13/site-packages/certifi/cacert.pem": 14727832973577663826, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_histograms.py": 47631283818191049, - "frontend/src/lib/components/translate/ScheduleConfig.svelte": 7232384043845640258, - "frontend/src/lib/components/translate/TranslationRunGlobalIndicator.svelte": 2809909710891941374, - "frontend/src/components/tasks/TaskResultPanel.svelte": 193489346212840974, - "venv/lib/python3.13/site-packages/jsonschema/benchmarks/nested_schemas.py": 4114645644496880787, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_regression.py": 6742646011852052645, - "venv/lib/python3.13/site-packages/pandas/core/groupby/groupby.py": 5536922766239875007, - "venv/lib/python3.13/site-packages/pandas/tests/frame/test_block_internals.py": 17935662848672401507, - "venv/lib/python3.13/site-packages/pandas/tests/io/xml/test_to_xml.py": 8477770807916990981, - "venv/lib/python3.13/site-packages/sqlalchemy/util/concurrency.py": 1325673503812009695, - "venv/lib/python3.13/site-packages/dateutil/tz/__init__.py": 9617254832690762236, - "backend/src/api/routes/reports.py": 13330739376983048757, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/Postfix.pyi": 2700568594438441246, - "backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py": 9290595122369575824, - "backend/src/plugins/translate/events.py": 14264965160929343917, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_abc.py": 10164280045317807365, - "venv/lib/python3.13/site-packages/pandas/core/arrays/string_arrow.py": 16997970607998635570, - "backend/tests/test_smoke_app.py": 7819901244710945164, - "venv/lib/python3.13/site-packages/ecdsa/test_numbertheory.py": 2117130219401053225, - "venv/lib/python3.13/site-packages/passlib/tests/test_ext_django.py": 3210697476292094384, - "venv/lib/python3.13/site-packages/pandas/core/ops/mask_ops.py": 16152832446926420035, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_real.py": 5283415082530228716, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_indexing.py": 17106010337164216722, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_character/foo77.f": 4046503346951676582, - "venv/lib/python3.13/site-packages/pandas/tests/extension/date/__init__.py": 16789767433439616593, - "venv/lib/python3.13/site-packages/pandas/io/parsers/arrow_parser_wrapper.py": 11745253171984606573, - "venv/lib/python3.13/site-packages/jeepney/tests/test_bus_messages.py": 4323093138307306385, - "frontend/src/lib/stores/health.js": 3437957055218721782, - "backend/src/plugins/mapper.py": 1970475023222782681, - "venv/lib/python3.13/site-packages/_pytest/deprecated.py": 5452408732344157294, - "venv/lib/python3.13/site-packages/numpy/lib/__init__.py": 12211229657513986410, - "venv/lib/python3.13/site-packages/yaml/resolver.py": 6669674521776449098, - "venv/lib/python3.13/site-packages/jeepney/bus.py": 5163075760432139100, - "venv/lib/python3.13/site-packages/apscheduler/__init__.py": 8652514118183227412, - "venv/lib/python3.13/site-packages/numpy/_utils/__init__.pyi": 13530522898409268883, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/common_with_division.f": 13517753924061311074, - "venv/lib/python3.13/site-packages/apscheduler/triggers/cron/fields.py": 8923326131649837922, - "venv/lib/python3.13/site-packages/passlib/__init__.py": 6987142392711441525, - "venv/lib/python3.13/site-packages/pandas/tests/internals/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/dictionary.py": 9599439750713575741, - "venv/lib/python3.13/site-packages/pygments/lexers/hare.py": 8693002231020751711, - "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_regression.py": 16266600037241221681, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_astype.py": 4178231007649608531, - "venv/lib/python3.13/site-packages/numpy/_pyinstaller/hook-numpy.pyi": 14233146512272397376, - "venv/lib/python3.13/site-packages/secretstorage/collection.py": 17903258621904912493, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/nditer.pyi": 2351219156711800159, - "venv/lib/python3.13/site-packages/pandas/io/parsers/python_parser.py": 7297059565749331767, - "venv/lib/python3.13/site-packages/cryptography/x509/certificate_transparency.py": 11337143186866439208, - "venv/lib/python3.13/site-packages/passlib/tests/backports.py": 17098448557554464521, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/query.py": 3867868366067025348, - "frontend/src/lib/components/layout/Sidebar.svelte": 15884718235284801177, - "venv/lib/python3.13/site-packages/pygments/lexers/foxpro.py": 14032656072384708293, - "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_liboffsets.py": 14705822637347212540, - "venv/lib/python3.13/site-packages/anyio/_core/_streams.py": 6436461519284884601, - "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/licenses/LICENSE": 11199044866758471950, - "venv/lib/python3.13/site-packages/bcrypt/__about__.py": 11196369962175692786, - "frontend/src/lib/components/translate/BulkCorrectionSidebar.svelte": 17772864954770752590, - "frontend/build/_app/immutable/nodes/26.Bv0TZ1Py.js": 12032769457852764082, - "venv/lib/python3.13/site-packages/authlib/oauth2/__init__.py": 13682931764896414722, - "backend/src/api/routes/plugins.py": 2062850550409490465, - "frontend/src/routes/storage/backups/+page.svelte": 3437582895363203695, - "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/METADATA": 9041650844081036822, - "venv/lib/python3.13/site-packages/cryptography/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/_libs/tslib.pyi": 16170606956605100142, - "venv/lib/python3.13/site-packages/_pytest/debugging.py": 16135285365306979060, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/infer.py": 12541904372617915365, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/declarative/extensions.py": 217122171232375592, - "backend/src/models/__tests__/test_models.py": 15975002719327784362, - "venv/lib/python3.13/site-packages/numpy/_core/_dtype_ctypes.py": 5564496700647900501, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timedeltas.cpython-313-x86_64-linux-gnu.so": 17089839649971421164, - "venv/lib/python3.13/site-packages/pandas/tests/resample/test_datetime_index.py": 15448494560143263150, - "venv/lib/python3.13/site-packages/pygments/lexers/elm.py": 14683437310498104916, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_any_index.py": 10800968419286329268, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_ops.py": 16346030307660048773, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/polynomial_series.pyi": 7112486730197067087, - "venv/lib/python3.13/site-packages/_pytest/stepwise.py": 3527630676691417317, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_scalar.py": 2434773821902319678, - "venv/lib/python3.13/site-packages/pycparser/ply/lex.py": 3393278208465358140, - "venv/lib/python3.13/site-packages/numpy/random/lib/libnpyrandom.a": 1802449692091040396, - "venv/lib/python3.13/site-packages/pandas/tests/interchange/test_utils.py": 2329717399120006435, - "venv/lib/python3.13/site-packages/starlette/testclient.py": 16088848330558215194, - "venv/lib/python3.13/site-packages/PIL/__init__.py": 10393984345353752724, - "venv/lib/python3.13/site-packages/pygments/lexers/erlang.py": 11757064262773184741, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/aead.py": 8740476942925346444, - "venv/lib/python3.13/site-packages/pydantic/_internal/_dataclasses.py": 15256193972947054890, - "venv/lib/python3.13/site-packages/pip/_internal/operations/install/__init__.py": 10456333337205488584, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/text.py": 6096215585499446070, - "venv/lib/python3.13/site-packages/PIL/ImageText.py": 15322496455608242001, - "venv/lib/python3.13/site-packages/numpy/tests/test_reloading.py": 17532116685329953400, - "backend/src/services/dataset_review/orchestrator.py": 8780497744077644822, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_logical/foo90.f90": 12508663906609241323, "venv/lib/python3.13/site-packages/starlette/requests.py": 4582424111350387010, - "venv/lib/python3.13/site-packages/pydantic/experimental/missing_sentinel.py": 1637241331832367709, - "venv/lib/python3.13/site-packages/numpy/lib/scimath.py": 7616377937400918724, - "venv/lib/python3.13/site-packages/websockets/legacy/auth.py": 16685128086396181286, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/response.py": 15004896908941411698, - "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_object.py": 9215781825358309147, - "venv/lib/python3.13/site-packages/pygments/styles/igor.py": 2291640843781128270, - "venv/lib/python3.13/site-packages/pandas/core/arrays/string_.py": 14865733321317939478, - "frontend/src/routes/profile/+page.svelte": 17979719303737794427, - "venv/lib/python3.13/site-packages/pip/_internal/utils/egg_link.py": 18211947508793805393, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ufunc_config.pyi": 2005481648919369399, - "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/licenses/numpy/_core/src/common/pythoncapi-compat/COPYING": 3474104874623144155, - "venv/lib/python3.13/site-packages/pygments/styles/solarized.py": 11231143047572616298, - "venv/lib/python3.13/site-packages/authlib/jose/rfc7516/models.py": 5656065513234782067, - "venv/lib/python3.13/site-packages/PIL/_webp.pyi": 18222325750818585549, - "venv/lib/python3.13/site-packages/pygments/lexers/_mysql_builtins.py": 16087227298679432006, - "venv/lib/python3.13/site-packages/pandas/tseries/__init__.py": 2648641118117738895, - "logs/app.log.1": 15453131390328548426, - "venv/lib/python3.13/site-packages/tzlocal/unix.py": 995019116408448073, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/decl_base.py": 8678387511873412922, - "venv/lib/python3.13/site-packages/greenlet/greenlet_exceptions.hpp": 8819301638282185623, - "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pandas/tests/io/sas/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_round.py": 9358309072340573675, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_ordered.py": 13827016781743929164, - "venv/lib/python3.13/site-packages/pip/_internal/distributions/sdist.py": 9490366272695301385, - "venv/lib/python3.13/site-packages/pip/_vendor/certifi/core.py": 2300277198409164253, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/random.py": 12722750410117529986, - "venv/lib/python3.13/site-packages/numpy/_core/_dtype.py": 7796703383405149774, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_dict.py": 808180749933361743, - "venv/lib/python3.13/site-packages/httpcore/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/pygments/lexers/verifpal.py": 9190813166686923928, - "venv/lib/python3.13/site-packages/websockets/streams.py": 15786581670248099415, - "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/test_observance.py": 18178414966262524534, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_twodim_base.py": 17623133613018058380, - "venv/lib/python3.13/site-packages/httpcore/_async/connection_pool.py": 932468678264370661, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/foo.f": 6349567809926050379, - "venv/lib/python3.13/site-packages/pygments/styles/trac.py": 13968346768164381833, - "venv/lib/python3.13/site-packages/pygments/lexers/whiley.py": 218468511185731869, - "frontend/src/lib/stores/environmentContext.js": 1762535408632658714, - "venv/lib/python3.13/site-packages/git/objects/submodule/util.py": 8621897576747443758, - "venv/lib/python3.13/site-packages/dateutil/easter.py": 14631233890122048084, - "frontend/src/routes/datasets/review/[id]/__tests__/dataset_review_workspace.ux.test.js": 4105775024258653726, - "backend/src/plugins/translate/dictionary.py": 4920392475082272360, - "backend/tests/services/clean_release/test_report_audit_immutability.py": 11385235469772417017, - "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/RECORD": 4857922668040624663, - "venv/lib/python3.13/site-packages/packaging/_musllinux.py": 2568338440457080365, - "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_bool.py": 433342705586552936, - "venv/lib/python3.13/site-packages/websockets/extensions/__init__.py": 13067201313921664210, - "backend/src/plugins/llm_analysis/__tests__/test_client_headers.py": 8746149613497088008, - "venv/lib/python3.13/site-packages/pip/_internal/index/package_finder.py": 12631116673181479779, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/twofactor/totp.py": 11888568940387752607, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/vector.py": 9941185556118343263, - "venv/lib/python3.13/site-packages/pandas/tests/window/test_api.py": 6439927798101672423, - "venv/lib/python3.13/site-packages/fastapi/_compat/v1.py": 9776181748061371513, - "run.sh": 4808871544409245302, - "venv/lib/python3.13/site-packages/pygments/lexers/smalltalk.py": 6113431347120223592, - "venv/lib/python3.13/site-packages/numpy/__init__.py": 2331213407497901634, - "venv/lib/python3.13/site-packages/pandas/tests/generic/test_frame.py": 9378623452601244234, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_dtypes.py": 4985057130807802395, - "backend/tests/test_dashboards_api.py": 2278794209397518464, - "venv/lib/python3.13/site-packages/authlib/jose/util.py": 14843923624043422219, - "venv/lib/python3.13/site-packages/websockets/asyncio/compatibility.py": 9716993942839407921, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_base.py": 16710163879060522196, - "venv/lib/python3.13/site-packages/PIL/_binary.py": 14039167720582222043, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_complex.py": 4290059580478881700, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_regression.py": 16293647824734937323, - "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/wrapper.py": 4633931060151989960, - "venv/lib/python3.13/site-packages/numpy/fft/_pocketfft.py": 6142062990691556076, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/comparisons.pyi": 4158883009780474220, - "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_strptime.py": 14328510310436552635, - "venv/lib/python3.13/site-packages/pandas/io/formats/excel.py": 797619981868084011, - "venv/lib/python3.13/site-packages/pygments/styles/emacs.py": 4540417536507245024, - "venv/lib/python3.13/site-packages/PIL/ImageOps.py": 3884310863548175682, - "venv/lib/python3.13/site-packages/pygments/lexers/dalvik.py": 5549983892200382076, - "venv/lib/python3.13/site-packages/apscheduler/jobstores/redis.py": 11313520438600819390, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/modules.pyi": 131293606732000587, - "venv/lib/python3.13/site-packages/apscheduler/executors/pool.py": 10344126569001032241, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/Levenshtein_py.py": 11350239659973489646, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7662/token_validator.py": 13917237710752731397, - "venv/lib/python3.13/site-packages/pip/_internal/cli/cmdoptions.py": 12107733000019393631, - "venv/lib/python3.13/site-packages/cryptography/x509/ocsp.py": 17973800752927680404, - "venv/lib/python3.13/site-packages/pandas/tests/extension/array_with_attr/__init__.py": 15991623390785635773, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_combine_concat.py": 3201068805128232483, - "venv/lib/python3.13/site-packages/greenlet/PyModule.cpp": 3464405102256525511, - "venv/lib/python3.13/site-packages/numpy/core/multiarray.py": 18368443598659711836, - "venv/lib/python3.13/site-packages/sqlalchemy/inspection.py": 8563914460959280101, - "venv/lib/python3.13/site-packages/pygments/lexers/shell.py": 3842338968014057744, - "frontend/src/components/PasswordPrompt.svelte": 14457083234480062595, - "frontend/src/components/TaskList.svelte": 13727273029173605651, - "frontend/src/components/EnvSelector.svelte": 3937920133889630193, - "venv/lib/python3.13/site-packages/starlette/routing.py": 16063812008141874150, - "backend/src/services/__tests__/test_llm_prompt_templates.py": 17912427710321938757, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/_asymmetric.py": 6903778603779934572, - "backend/tests/services/clean_release/test_approval_service.py": 8359796700245201345, - "venv/lib/python3.13/site-packages/apscheduler/triggers/date.py": 9545774812177853725, - "venv/lib/python3.13/site-packages/greenlet/tests/fail_switch_three_greenlets2.py": 11100501798741918610, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_constructors.py": 16197656939536784142, - "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/RECORD": 3283324710045856319, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ma.pyi": 6467636381637286867, - "venv/lib/python3.13/site-packages/pandas/tests/extension/uuid/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/live.py": 8586058300967410643, - "venv/lib/python3.13/site-packages/pillow.libs/liblzma-61b1002e.so.5.8.2": 11405063484938458842, - "venv/lib/python3.13/site-packages/pydantic/version.py": 3699343596421001359, - "venv/lib/python3.13/site-packages/numpy/core/fromnumeric.py": 2136433423902202138, - "venv/lib/python3.13/site-packages/numpy/_core/_methods.py": 16805668769357938792, - "venv/lib/python3.13/site-packages/fastapi/__init__.py": 11054203163075417954, - "venv/lib/python3.13/site-packages/packaging/_elffile.py": 9546225990833172494, - "venv/lib/python3.13/site-packages/anyio/_core/_contextmanagers.py": 1258491775823080427, - "frontend/src/components/DynamicForm.svelte": 12658559315809907844, + "venv/lib/python3.13/site-packages/sqlalchemy/connectors/aioodbc.py": 2018840826888846321, + "venv/lib/python3.13/site-packages/pygments/styles/xcode.py": 14124729477757765388, + "backend/src/services/notifications/providers.py": 5844970860921555598, "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_common.py": 2265736743367879051, - "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_odswriter.py": 5134385709728943904, - "frontend/src/lib/components/dataset-review/CompiledSQLPreview.svelte": 14788599185006992431, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/__init__.py": 15130871412783076140, - "backend/src/plugins/translate/orchestrator.py": 6507658261488157100, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_category.py": 3944898528119364040, + "venv/lib/python3.13/site-packages/pandas/tests/series/test_arithmetic.py": 17427754419626622853, + "backend/src/plugins/translate/sql_generator.py": 900251269659959067, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust.abi3.so": 2537152913308578487, + "venv/lib/python3.13/site-packages/numpy/random/_examples/numba/extending_distributions.py": 209769687436320665, + "venv/lib/python3.13/site-packages/pydantic/plugin/__init__.py": 16803973597469216174, + "venv/lib/python3.13/site-packages/passlib/ext/__init__.py": 15240312484046875203, + "venv/lib/python3.13/site-packages/passlib/crypto/_md4.py": 379335134151814809, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/__init__.py": 697601512486720554, + "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_concat.py": 10207975532842927134, + "venv/lib/python3.13/site-packages/_pytest/fixtures.py": 1442767529726551116, + "venv/lib/python3.13/site-packages/pip/_internal/commands/list.py": 13035925292530461722, + "venv/lib/python3.13/site-packages/cryptography/hazmat/backends/__init__.py": 18019562641348687547, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/descriptor_props.py": 7044852927393650707, + "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libkrb5-fcafa220.so.3.3": 5620628698712971642, + "frontend/src/components/backups/BackupList.svelte": 14706629542956875064, + "venv/lib/python3.13/site-packages/pandas/tests/frame/test_nonunique_indexes.py": 15468078561381939405, + "frontend/build/_app/immutable/chunks/Bn0PWGM8.js": 3309051336151057391, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/errors.py": 2147619440137604907, + "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/__init__.py": 2246704695838251846, + "venv/lib/python3.13/site-packages/numpy/_core/_simd.cpython-313-x86_64-linux-gnu.so": 12609666221355091416, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/halffloat.h": 16913381775994652343, + "venv/lib/python3.13/site-packages/pygments/styles/monokai.py": 12381683616720952636, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/x509.pyi": 17458894097215345719, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_constructors.py": 6440526981746306640, + "venv/lib/python3.13/site-packages/pandas/core/flags.py": 4690844374637430013, + "venv/lib/python3.13/site-packages/pygments/styles/rainbow_dash.py": 12236746494379891602, + "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/licenses/LICENSE": 14610443802372107702, + "venv/lib/python3.13/site-packages/urllib3/contrib/pyopenssl.py": 11839715589709210412, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc_aix.h": 13316272821279308986, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/test_arrow_compat.py": 17818294260710640443, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/Prefix.pyi": 2700568594438441246, + "venv/lib/python3.13/site-packages/pandas/tests/series/test_iteration.py": 15247340610412364508, + "venv/lib/python3.13/site-packages/pygments/lexers/d.py": 18120801227801223376, + "venv/lib/python3.13/site-packages/anyio/abc/_resources.py": 8330687082933028623, + "frontend/src/lib/components/dataset-review/__tests__/validation_findings_panel.ux.test.js": 8994492423600483794, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_take.py": 3281943380342853080, + "backend/src/scripts/create_admin.py": 11258281301071059367, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/parameters.py": 12219404446503940066, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_datetime.py": 7456744745424297814, + "venv/lib/python3.13/site-packages/pip/_vendor/msgpack/fallback.py": 4260636031748548345, + "venv/lib/python3.13/site-packages/authlib/oidc/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pygments/lexers/_tsql_builtins.py": 829193091321611630, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_dtypes.py": 4985057130807802395, "venv/lib/python3.13/site-packages/jose/backends/cryptography_backend.py": 2875270748627611635, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/plugin.py": 16042078006552521613, - "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_structures.py": 16375837477294135345, - "venv/lib/python3.13/site-packages/cffi/vengine_gen.py": 6582900613549620556, - "venv/lib/python3.13/site-packages/greenlet/TGreenletGlobals.cpp": 17400526028982558937, - "venv/lib/python3.13/site-packages/_pytest/mark/__init__.py": 9343015549300275714, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh25211.pyf": 10179237442840865225, - "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_astype.py": 4023134352880775277, - "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/RECORD": 13494296690334916257, - "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/implicit.py": 5400555157488808948, - "venv/lib/python3.13/site-packages/pydantic/functional_validators.py": 5835339743072048940, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test__iotools.py": 6260912730310453037, - "venv/lib/python3.13/site-packages/numpy/fft/_pocketfft.pyi": 1521384724035973688, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/persistence.py": 17908437937265384125, - "venv/lib/python3.13/site-packages/urllib3/filepost.py": 3814725067598042920, - "venv/lib/python3.13/site-packages/urllib3/__init__.py": 1854778274753799815, - "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/RECORD": 18294169019244826301, - "frontend/src/lib/stores/translationRun.js": 4974041543031230789, - "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/py.typed": 15130871412783076140, - "backend/src/services/dataset_review/event_logger.py": 8083530196989488371, - "venv/lib/python3.13/site-packages/pygments/lexers/textedit.py": 14872291021083255414, - "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/wsproto_impl.py": 3072714633272661847, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_update.py": 12293424926920594944, - "venv/lib/python3.13/site-packages/PIL/PcxImagePlugin.py": 1691405132377495336, - "venv/lib/python3.13/site-packages/anyio/streams/stapled.py": 9733127303038397237, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/dtypes.cpython-313-x86_64-linux-gnu.so": 657138415665704488, - "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_construct_ndarray.py": 6863874753941288585, - "venv/lib/python3.13/site-packages/greenlet/tests/_test_extension.c": 9318655518998644962, - "venv/lib/python3.13/site-packages/numpy/__init__.pyi": 15820654525292895396, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_array_coercion.py": 3551994404797560483, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_constructors.py": 12118296571694122743, - "venv/lib/python3.13/site-packages/pandas/core/util/numba_.py": 3535857372998653863, - "venv/lib/python3.13/site-packages/PIL/_imaging.cpython-313-x86_64-linux-gnu.so": 1425926264271197601, - "venv/lib/python3.13/site-packages/jsonschema_specifications/tests/test_jsonschema_specifications.py": 12693210357718751894, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/naming.py": 14503932124671438340, - "frontend/src/routes/dashboards/[id]/components/DashboardHeader.svelte": 5572977872383619871, - "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_chaining_and_caching.py": 11784574265874608859, - "venv/lib/python3.13/site-packages/numpy/_globals.py": 8736093011628027941, - "venv/lib/python3.13/site-packages/pandas/compat/pyarrow.py": 13693379998785127538, - "venv/lib/python3.13/site-packages/uvicorn/middleware/asgi2.py": 5355343704425405009, - "backend/src/core/utils/fileio.py": 5783081738676692209, - "backend/tests/scripts/test_clean_release_cli.py": 13978106497618764226, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/mod.py": 2054876501774773382, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_reindex.py": 16348619731902304844, - "venv/lib/python3.13/site-packages/pandas/io/formats/css.py": 11288129826285529457, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/array_api_info.pyi": 7887489694871300469, - "venv/lib/python3.13/site-packages/numpy/lib/_twodim_base_impl.pyi": 15509415708991012734, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/six.py": 1161259802604920635, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/fromnumeric.pyi": 8671744104085911610, - "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/METADATA": 7214286447912789067, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/x25519.py": 18229054440703471493, - "venv/lib/python3.13/site-packages/sqlalchemy/engine/mock.py": 14010776046610111182, - "venv/lib/python3.13/site-packages/pydantic/validators.py": 8292819706488319845, - "venv/lib/python3.13/site-packages/pip/_internal/utils/hashes.py": 17310331665429541812, - "docker/backend.entrypoint.sh": 16079402358996730188, - "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/METADATA": 15876173086384975957, - "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/__init__.py": 5027355874704300832, - "venv/lib/python3.13/site-packages/pygments/lexers/data.py": 9365024327689738663, - "venv/lib/python3.13/site-packages/numpy/polynomial/hermite.py": 6617116180936986481, - "venv/lib/python3.13/site-packages/pygments/lexers/gdscript.py": 12775803139854052838, - "venv/lib/python3.13/site-packages/pydantic_settings/sources/__init__.py": 7062045842767697645, - "venv/lib/python3.13/site-packages/sqlalchemy/engine/processors.py": 4817637175145012571, - "backend/src/api/routes/__tests__/test_datasets.py": 14530822388357135497, + "venv/lib/python3.13/site-packages/pygments/lexers/_asy_builtins.py": 1665617945818958781, + "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/packaging/specifiers.py": 2800449842990194437, + "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/rsa.py": 5392922995791487437, + "venv/lib/python3.13/site-packages/numpy/random/tests/data/pcg64-testset-1.csv": 16078879475693341404, + "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/WHEEL": 16223367184831500348, + "venv/lib/python3.13/site-packages/pandas/core/indexes/api.py": 13750417165301467381, + "venv/lib/python3.13/site-packages/jaraco/classes/properties.py": 6976928770004942858, + "venv/lib/python3.13/site-packages/attr/_compat.py": 4016698632899969390, + "venv/lib/python3.13/site-packages/passlib/tests/test_utils_handlers.py": 556092537518149789, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/methods/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_factorize.py": 861897342553280506, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_groupby_dropna.py": 3620959914439334511, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_rename.py": 4890779493250245903, + "venv/lib/python3.13/site-packages/requests/__init__.py": 2604491098990438229, + "venv/lib/python3.13/site-packages/PIL/PixarImagePlugin.py": 12061717157676819554, + "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/numpy/fft/__init__.pyi": 10354990065626209946, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/measure.py": 18327922742808984428, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_raises.py": 9678418010293693275, + "backend/src/api/routes/translate/_dictionary_routes.py": 5480137091791704976, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_period.py": 7727606662611927293, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_cell_widths.py": 5724379364993806351, + "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/boxplot.py": 7090586111222952862, + "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth1/authorization_server.py": 724388765673082720, + "venv/lib/python3.13/site-packages/pip/_internal/vcs/__init__.py": 1197579313959289096, + "venv/lib/python3.13/site-packages/pandas/tests/resample/test_timedelta.py": 17052461094717926538, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_pct_change.py": 10313980265441433173, "venv/lib/python3.13/site-packages/sqlalchemy/testing/fixtures/__init__.py": 6654484356035994666, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/shape.py": 13410030168622484801, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh22648.pyf": 15094859289098837494, - "venv/lib/python3.13/site-packages/pandas/tests/test_col.py": 14781555956509956371, - "venv/lib/python3.13/site-packages/numpy/ma/tests/test_old_ma.py": 18116460138221458026, - "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_readers.py": 2136472634307645842, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_cte.py": 9274103293201050794, - "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/__init__.py": 16416360448593978041, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/ciphers.pyi": 18143251582901996072, - "venv/lib/python3.13/site-packages/numpy/_core/cversions.py": 9724467539503410469, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_to_timestamp.py": 17572983799929378095, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/__init__.py": 237070345717942041, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/__init__.py": 8807410829260170597, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/timedeltas/test_constructors.py": 17219764538851313252, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/pg_catalog.py": 15726448028057859831, - "venv/lib/python3.13/site-packages/uvicorn/protocols/utils.py": 6147480543268737542, - "venv/lib/python3.13/site-packages/pytest_asyncio/py.typed": 15130871412783076140, - "venv/bin/normalizer": 10972303485259566838, - "venv/lib/python3.13/site-packages/pandas/util/_validators.py": 10201915528715968165, - "backend/src/models/auth.py": 14495240302739907540, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc_macosx.h": 3653129798702716366, - "backend/alembic/versions/8dd0a93af539_drop_deprecated_source_language_column_.py": 3574830605384611294, - "venv/lib/python3.13/site-packages/multipart/exceptions.py": 8580522204565816132, - "venv/lib/python3.13/site-packages/pip/_vendor/distlib/manifest.py": 16998683210177680416, - "venv/lib/python3.13/site-packages/numpy/_core/_asarray.pyi": 3940937389249665490, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/types.py": 12298292195929126306, - "venv/lib/python3.13/site-packages/authlib/integrations/base_client/__init__.py": 1856412417337875350, - "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/content": 16257335642847993866, - "venv/lib/python3.13/site-packages/pandas/core/sample.py": 11913688303879867963, - "venv/lib/python3.13/site-packages/pandas/core/col.py": 4221271461723119525, - "venv/lib/python3.13/site-packages/pygments/lexers/_csound_builtins.py": 14530739818491398298, - "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/METADATA": 14126682758562488244, - "venv/lib/python3.13/site-packages/ecdsa/test_ecdsa.py": 17595025859105321562, - "venv/lib/python3.13/site-packages/pillow.libs/libzstd-761a17b6.so.1.5.7": 17875236748140157032, - "venv/lib/python3.13/site-packages/pip/_internal/utils/_log.py": 13011536737418204268, - "venv/lib/python3.13/site-packages/numpy/_core/lib/npy-pkg-config/npymath.ini": 1071371630695963467, - "venv/lib/python3.13/site-packages/pandas/io/formats/templates/latex_table.tpl": 8706980975714184465, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py": 10843527833285941674, - "venv/lib/python3.13/site-packages/numpy/tests/test__all__.py": 10689265249302359388, - "venv/lib/python3.13/site-packages/greenlet/greenlet_thread_support.hpp": 7773996382104849037, - "venv/lib/python3.13/site-packages/cffi/__init__.py": 13427266446746498548, - "venv/lib/python3.13/site-packages/passlib/apache.py": 2357244937629445006, - "venv/lib/python3.13/site-packages/pandas/tests/extension/base/printing.py": 8681519649669408795, - "venv/lib/python3.13/site-packages/pandas/api/interchange/__init__.py": 181911269762882069, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_reshape.py": 10576230966727810832, - "venv/lib/python3.13/site-packages/sqlalchemy/orm/state_changes.py": 11425629729736599320, - "venv/lib/python3.13/site-packages/passlib/tests/test_crypto_digest.py": 7988469818593853943, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/mysqldb.py": 2138006249556140141, - "venv/lib/python3.13/site-packages/numpy/lib/tests/test_format.py": 5231304674283854194, - "venv/lib/python3.13/site-packages/pygments/lexers/oberon.py": 15220143799603451830, - "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/signature.py": 3614545297259098566, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_period.py": 10309599277099605395, - "backend/src/api/routes/git/_merge_routes.py": 2019590524299108754, - "backend/src/services/reports/__tests__/test_type_profiles.py": 17262223295445285285, - "venv/lib/python3.13/site-packages/numpy/typing/tests/test_runtime.py": 12534621594420844770, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/arithmetic.pyi": 10265823318697442495, - "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/nattype.cpython-313-x86_64-linux-gnu.so": 2311012065007769341, - "backend/src/services/auth_service.py": 17642785219801916280, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/provision.py": 8707620698060818654, - "venv/lib/python3.13/site-packages/numpy/polynomial/hermite.pyi": 3573629536236108391, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_arithmetic.py": 17449383588949771785, - "backend/src/schemas/auth.py": 339608158310320944, - "venv/lib/python3.13/site-packages/pandas/tests/libs/test_lib.py": 6721066015604956469, - "venv/lib/python3.13/site-packages/anyio/streams/file.py": 15232345967545920863, - "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_polyutils.py": 675639791972685455, - "venv/lib/python3.13/site-packages/greenlet/tests/leakcheck.py": 10179165748538820557, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/value_attrspec/gh21665.f90": 11945588837236968550, - "venv/lib/python3.13/site-packages/passlib/context.py": 10362592407593745107, - "venv/lib/python3.13/site-packages/websockets/sync/router.py": 10335595955948355382, - "venv/lib/python3.13/site-packages/pandas/tests/window/test_ewm.py": 13789842684407148830, - "venv/lib/python3.13/site-packages/pip/_internal/cli/spinners.py": 7664056305019151182, - "venv/lib/python3.13/site-packages/sqlalchemy/testing/exclusions.py": 15852672500377116297, - "venv/lib/python3.13/site-packages/PIL/MpoImagePlugin.py": 644327650732339301, - "venv/lib/python3.13/site-packages/pygments/lexers/math.py": 1647133236144311250, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_replace.py": 8784361132920473760, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_cut.py": 7800833253841657380, - "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/__init__.py": 11283047029180207588, - "venv/lib/python3.13/site-packages/_pytest/monkeypatch.py": 2635774457434545573, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_to_numpy.py": 14845850776625255794, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_compare.py": 171535659467902751, - "venv/lib/python3.13/site-packages/sqlalchemy/sql/ddl.py": 5006132143435653867, - "frontend/src/lib/components/translate/TranslationMetricsDashboard.svelte": 7320072998752693628, - "backend/src/services/git/_base.py": 17717982195967253756, - "venv/lib/python3.13/site-packages/numpy/fft/_helper.pyi": 9546918341939102632, - "venv/lib/python3.13/site-packages/anyio/streams/text.py": 12507591237176920223, - "venv/lib/python3.13/site-packages/packaging/tags.py": 1999137344425005827, - "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/licenses/LICENSE": 13322127602069971876, - "venv/lib/python3.13/site-packages/fastapi/__main__.py": 10755252341326986079, - "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/dsa.py": 8079219938116542284, - "venv/lib/python3.13/site-packages/pandas/core/methods/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/core/dtypes/concat.py": 14737724508458849795, - "venv/lib/python3.13/site-packages/pandas/io/sas/sas_xport.py": 16525568795475918874, - "venv/lib/python3.13/site-packages/_cffi_backend.cpython-313-x86_64-linux-gnu.so": 829323374625147265, - "venv/lib/python3.13/site-packages/pygments/lexers/roboconf.py": 1335271183806115470, - "venv/lib/python3.13/site-packages/pygments/lexers/webidl.py": 8097260111959278117, - "venv/lib/python3.13/site-packages/pydantic/_internal/_generics.py": 16438159042939059717, - "venv/lib/python3.13/site-packages/PIL/ImageDraw.py": 12919304671639673744, - "venv/lib/python3.13/site-packages/pandas/core/arraylike.py": 11439602957100017713, - "venv/lib/python3.13/site-packages/pytest_asyncio/plugin.py": 13414541723622354359, - "venv/lib/python3.13/site-packages/rpds/rpds.cpython-313-x86_64-linux-gnu.so": 561326734302492859, - "backend/src/services/__tests__/test_resource_service.py": 14435810729789665272, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/test_timedelta.py": 12822713918114715561, - "venv/lib/python3.13/site-packages/PIL/JpegImagePlugin.py": 10621639599916796689, - "venv/lib/python3.13/site-packages/greenlet/platform/switch_riscv_unix.h": 8607317131295864391, - "venv/lib/python3.13/site-packages/h11/_connection.py": 6971907312737339559, - "venv/lib/python3.13/site-packages/gitdb/__init__.py": 15381521749253695923, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_combine.py": 16193618152415684421, - "venv/lib/python3.13/site-packages/jaraco/classes/py.typed": 15130871412783076140, - "frontend/src/routes/translate/[id]/+page.svelte": 4980328348725787681, - "venv/lib/python3.13/site-packages/numpy/tests/test_lazyloading.py": 17465787495701737655, - "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/METADATA": 1684451390569121499, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/test_constructors.py": 1697610790604400105, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_numba.py": 18148155441554555618, - "backend/src/core/utils/superset_context_extractor/_parsing.py": 17093712504833649098, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_windows_renderer.py": 1076842273781909680, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_astype.py": 11995587502880659624, + "venv/lib/python3.13/site-packages/pandas/core/reshape/concat.py": 2218848863149192467, + "venv/lib/python3.13/site-packages/pygments/lexers/_mql_builtins.py": 2376212048709413586, + "venv/lib/python3.13/site-packages/pandas/core/internals/api.py": 14632030170441237968, + "venv/lib/python3.13/site-packages/pip/_vendor/packaging/py.typed": 15130871412783076140, "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_meson.pyi": 2101854548535776875, - "venv/lib/python3.13/site-packages/jsonschema/protocols.py": 847332300543820834, - "venv/lib/python3.13/site-packages/_yaml/__init__.py": 3395829783751571350, - "frontend/src/routes/+layout.svelte": 2748734957389681795, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_unary.py": 7128845965976836334, - "venv/lib/python3.13/site-packages/sqlalchemy/engine/default.py": 7906029092844029127, - "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/RECORD": 11111103193315065053, - "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/pkcs7.pyi": 2777456956260371820, - "venv/lib/python3.13/site-packages/pydantic/datetime_parse.py": 196119761382305574, - "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/__multiarray_api.h": 16138871162713175599, - "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/candidates.py": 5951912505933673835, - "venv/lib/python3.13/site-packages/numpy/_core/_simd.pyi": 13553578040186939249, - "venv/lib/python3.13/site-packages/pillow.libs/libxcb-64009ff3.so.1.1.0": 7322566017497612912, - "venv/lib/python3.13/site-packages/jeepney/tests/test_low_level.py": 3579024079580951234, - "venv/lib/python3.13/site-packages/rapidfuzz/utils.pyi": 7400725037332728015, - "venv/lib/python3.13/site-packages/_pytest/warnings.py": 8633394774569709013, - "venv/lib/python3.13/site-packages/pandas/tseries/holiday.py": 1134358927599488799, - "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_tzconversion.py": 7205566353454584259, - "venv/lib/python3.13/site-packages/pygments/lexers/webassembly.py": 17811970490091406867, - "venv/lib/python3.13/site-packages/numpy/testing/tests/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/rapidfuzz/distance/Hamming_py.py": 16133454512601432815, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_filter.py": 2388681477981649268, - "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/array.py": 12658302948819867972, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_formats.py": 2743326139283991615, - "venv/lib/python3.13/site-packages/pandas/tests/util/test_show_versions.py": 10577134135855180356, - "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_invalid.py": 2762344062554575805, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_reindex.py": 15680924058960901067, - "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/LICENSE": 6581019367004699816, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_names.py": 10037208029090713121, - "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/pyproject.py": 12684373765476932108, - "backend/src/api/routes/health.py": 4494840518139445701, - "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_arithmetic.py": 976970179757115407, - "venv/lib/python3.13/site-packages/pip/_vendor/rich/_emoji_codes.py": 13901854719435716195, - "venv/lib/python3.13/site-packages/anyio/abc/__init__.py": 11428476337116642278, - "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_pipe.py": 8255917221095334212, - "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_arithmetic.py": 16829312896275893002, - "venv/lib/python3.13/site-packages/authlib/oauth1/client.py": 7314311571224771, - "venv/lib/python3.13/site-packages/pygments/lexers/php.py": 17636450950688953288, - "venv/lib/python3.13/site-packages/authlib/common/urls.py": 13627272625165922482, - "venv/lib/python3.13/site-packages/pytest/__main__.py": 8747175113746141224, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/nditer.pyi": 33523064068376750, - "venv/lib/python3.13/site-packages/cffi/parse_c_type.h": 9889309594462820068, - "venv/lib/python3.13/site-packages/websockets/server.py": 16599051743322571790, - "venv/lib/python3.13/site-packages/cryptography/fernet.py": 10137792148038140630, - "venv/lib/python3.13/site-packages/charset_normalizer/cli/__main__.py": 2148876100501691980, - "venv/lib/python3.13/site-packages/referencing/_core.py": 14744795336121513230, - "frontend/build/_app/immutable/assets/AssistantChatPanel.D4L5jlt0.css": 10724144138366384732, - "venv/lib/python3.13/site-packages/fastapi/websockets.py": 9910052969532075719, - "venv/lib/python3.13/site-packages/pip/_internal/metadata/_json.py": 6718137926109998531, - "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/INSTALLER": 17282701611721059870, - "venv/lib/python3.13/site-packages/numpy/_core/tests/test_mem_overlap.py": 4202716587079637350, - "venv/lib/python3.13/site-packages/pandas/tests/base/test_conversion.py": 7507083194555424923, - "venv/lib/python3.13/site-packages/git/diff.py": 6691274015605451565, - "venv/lib/python3.13/site-packages/pygments/lexers/haxe.py": 1915270891525929751, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_subclass.py": 12453252499544981915, - "venv/lib/python3.13/site-packages/pandas/tests/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/sqlalchemy/ext/compiler.py": 11662494978292401568, - "venv/lib/python3.13/site-packages/pygments/lexers/int_fiction.py": 8806961041808606055, - "venv/lib/python3.13/site-packages/fastapi/applications.py": 4975013401500183420, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/endpoint.py": 8519226897299461194, - "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/REQUESTED": 15130871412783076140, - "venv/lib/python3.13/site-packages/httpcore/_trace.py": 9576253018891841832, - "venv/lib/python3.13/site-packages/dotenv/py.typed": 9796674040111366709, - "venv/lib/python3.13/site-packages/uvicorn/py.typed": 15240312484046875203, - "venv/lib/python3.13/site-packages/pygments/lexers/objective.py": 10966124906622044512, - "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/_pytest/helpconfig.py": 3033477806668470951, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/datasource.pyi": 80441145804744162, - "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_misc.py": 16393451200513733144, - "venv/lib/python3.13/site-packages/h11/_headers.py": 7592730288271984585, - "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/utils.py": 617314300548081590, - "venv/lib/python3.13/site-packages/pandas/tests/resample/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/extension/base/ops.py": 13451323660386712332, - "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_parse_dates.py": 7597935994945336408, - "frontend/src/routes/+layout.ts": 8392799000856778740, - "venv/lib/python3.13/site-packages/sqlalchemy/connectors/pyodbc.py": 4146960201984489604, - "venv/lib/python3.13/site-packages/numpy/random/_examples/cython/meson.build": 17468163147765825687, - "frontend/src/routes/settings/+page.ts": 3719008513710037840, - "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_masked_matrix.py": 1444179242134203344, - "venv/lib/python3.13/site-packages/pip/_internal/operations/build/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_between.py": 337429135216881486, - "venv/lib/python3.13/site-packages/pandas/tests/io/excel/__init__.py": 15130871412783076140, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_rename_axis.py": 13193478481758930128, - "venv/lib/python3.13/site-packages/numpy/random/tests/data/sfc64-testset-1.csv": 5708101386018266998, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_isin.py": 14387850595546682314, + "venv/lib/python3.13/site-packages/greenlet/tests/fail_switch_three_greenlets2.py": 11100501798741918610, + "venv/lib/python3.13/site-packages/attr/setters.pyi": 6670509359139243236, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_tz_convert.py": 17957207974799052653, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/base.py": 3250660921154829815, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/collections.py": 16114931075157411913, + "venv/lib/python3.13/site-packages/pygments/lexers/tcl.py": 10343667975436015855, + "venv/lib/python3.13/site-packages/cryptography/x509/base.py": 9124948989225782039, + "venv/lib/python3.13/site-packages/numpy/polynomial/laguerre.pyi": 11310761736182213265, + "frontend/src/components/__tests__/task_log_viewer.test.js": 6512653335179659416, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_memmap.py": 8709963808115492688, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_is_monotonic.py": 12769599198035357753, + "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/oauth2_session.py": 7076806577412682835, + "venv/lib/python3.13/site-packages/pandas/io/__init__.py": 9767690163638898709, + "venv/lib/python3.13/site-packages/pydantic/v1/env_settings.py": 6194387033830177219, + "venv/lib/python3.13/site-packages/pyasn1/codec/der/__init__.py": 15728752901274520502, + "venv/lib/python3.13/site-packages/pyasn1/codec/ber/__init__.py": 15728752901274520502, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/lexers/python.py": 17886036670342116501, + "venv/lib/python3.13/site-packages/numpy/rec/__init__.py": 7467092880535460658, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_categorical.py": 9923236395692943732, + "venv/lib/python3.13/site-packages/sqlalchemy/engine/row.py": 9763935103055608874, + "frontend/build/_app/immutable/nodes/2.BTzX8n4L.js": 10193965644456469096, + "frontend/src/components/git/CommitModal.svelte": 2248630732087966961, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_freq_attr.py": 7685756734926749093, + "venv/lib/python3.13/site-packages/anyio/streams/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tseries/api.py": 14785127136180503704, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_duplicated.py": 6659959750254523427, + "venv/lib/python3.13/site-packages/pandas/_libs/byteswap.pyi": 6723628093359375823, + "venv/lib/python3.13/site-packages/PIL/PaletteFile.py": 4104323659569809769, + "venv/lib/python3.13/site-packages/pandas/core/arrays/numpy_.py": 16641729409992576358, + "venv/lib/python3.13/site-packages/keyring/backends/SecretService.py": 17482492072907438453, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/__init__.py": 14571251344510763303, + "venv/lib/python3.13/site-packages/pydantic/v1/config.py": 12050640083719340958, + "venv/lib/python3.13/site-packages/numpy/_core/records.pyi": 14194354215405544730, + "venv/lib/python3.13/site-packages/pytest_asyncio/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/f2py/f2py2e.py": 738588649412338185, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_integer/foo77.f": 12000068001851270396, + "venv/lib/python3.13/site-packages/pandas/core/ops/mask_ops.py": 16152832446926420035, + "venv/bin/normalizer": 10972303485259566838, + "venv/lib/python3.13/site-packages/numpy/ma/tests/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pip/_vendor/idna/core.py": 2199607970842512780, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_ufunclike.py": 13752381070039804384, + "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/parameters.py": 247312908510013930, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py": 16768579082462294745, + "venv/lib/python3.13/site-packages/pyasn1/type/namedtype.py": 1859990775875190116, + "backend/src/plugins/storage/plugin.py": 13669428465597027289, + "venv/lib/python3.13/site-packages/_cffi_backend.cpython-313-x86_64-linux-gnu.so": 829323374625147265, + "venv/lib/python3.13/site-packages/starlette/middleware/trustedhost.py": 8302185291610019926, + "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/licenses/LICENSE": 10253862887434903467, + "frontend/src/lib/api/translate.js": 18119277537390809809, + "venv/lib/python3.13/site-packages/pip/_internal/req/constructors.py": 17485271035479378662, + "venv/lib/python3.13/site-packages/numpy/_core/_multiarray_tests.cpython-313-x86_64-linux-gnu.so": 442168371609469538, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_libgroupby.py": 9985769511561272200, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/__init__.pyi": 17469792319379909312, "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_count.py": 9186538441380080087, - "venv/lib/python3.13/site-packages/websockets/version.py": 5853118844880112885, - "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8414/__init__.py": 4781700006554860887, - "venv/lib/python3.13/site-packages/numpy/py.typed": 15130871412783076140, - "venv/lib/python3.13/site-packages/authlib/integrations/base_client/async_app.py": 4329794049222609894, - "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_timestamp.py": 12253372102602993034, - "venv/lib/python3.13/site-packages/websockets/asyncio/messages.py": 6848925149930551457, - "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_timedelta.py": 7742506012012398830, - "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/mysqlconnector.py": 17538029557373507617, - "venv/lib/python3.13/site-packages/pygments/lexers/julia.py": 13516407944275342328, - "venv/lib/python3.13/site-packages/pip/_internal/commands/index.py": 16715578868094112894, - "venv/lib/python3.13/site-packages/numpy/lib/_twodim_base_impl.py": 4154852745131464543, - "frontend/src/routes/datasets/review/[id]/+page.svelte": 2388350237937943327, - "venv/lib/python3.13/site-packages/pip/_internal/req/req_set.py": 534498057184394558, + "venv/lib/python3.13/site-packages/PIL/ImageText.py": 15322496455608242001, + "venv/lib/python3.13/site-packages/starlette/middleware/__init__.py": 9524277524025372856, + "venv/lib/python3.13/site-packages/jose/jwk.py": 2781217726458801910, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/strptime.pyi": 5973671421648618563, + "venv/lib/python3.13/site-packages/pip/_vendor/tomli/_re.py": 1296579393600719224, + "venv/lib/python3.13/site-packages/numpy/ma/tests/test_deprecations.py": 8310244516175542839, + "venv/lib/python3.13/site-packages/pandas/_libs/byteswap.cpython-313-x86_64-linux-gnu.so": 17856848989827220388, + "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/licenses/LICENSE": 14524289631770661180, + "venv/lib/python3.13/site-packages/urllib3/_collections.py": 3440910792774742262, + "frontend/src/routes/settings/settings-utils.js": 9490767217322820262, + "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/WHEEL": 16097436423493754389, + "venv/lib/python3.13/site-packages/numpy/_typing/_shape.py": 12667553664122376205, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/chararray.pyi": 17340224970247832290, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_logical.py": 6818185860296232476, + "backend/src/schemas/auth.py": 339608158310320944, + "backend/src/core/task_manager/context.py": 17543992255093146942, + "backend/src/services/reports/__tests__/test_type_profiles.py": 17262223295445285285, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arctanh.csv": 8620268345075425735, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_factorize.py": 5585211699185937865, + "venv/lib/python3.13/site-packages/pandas/_config/dates.py": 3863381688916127265, + "venv/lib/python3.13/site-packages/pip/_vendor/distlib/util.py": 3591114320020964752, + "venv/lib/python3.13/site-packages/pydantic/_internal/_validators.py": 2939255306814626438, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7591/__init__.py": 348469143777130970, + "venv/lib/python3.13/site-packages/numpy/matrixlib/__init__.py": 18402126171936308228, + "frontend/src/lib/ui/Card.svelte": 3442526978752993023, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/modules.py": 9023244176010175562, + "backend/src/api/routes/settings.py": 1899503837234642538, + "venv/lib/python3.13/site-packages/cffi/_imp_emulation.py": 17246725564704952212, + "venv/lib/python3.13/site-packages/greenlet/tests/test_weakref.py": 6780204527427742510, + "venv/lib/python3.13/site-packages/pip/_vendor/distro/__init__.py": 11414161642984633362, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_year.py": 1478857009124807836, + "backend/src/api/routes/reports.py": 13330739376983048757, + "venv/lib/python3.13/site-packages/pandas/_testing/asserters.py": 272063856832951430, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_repr.py": 7552782621374439569, + "frontend/src/components/TaskLogViewer.svelte": 14310893311791502213, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_tooltip.py": 853808724844451770, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_set_index.py": 10971093361190283675, + "venv/lib/python3.13/site-packages/greenlet/tests/_test_extension_cpp.cpython-313-x86_64-linux-gnu.so": 7659849621107414188, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9207/__init__.py": 8434616194114282088, + "venv/lib/python3.13/site-packages/passlib/tests/test_win32.py": 13932956220195912963, + "venv/lib/python3.13/site-packages/pygments/styles/colorful.py": 15708848112363953394, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/dtypes/test_dtypes_basic.py": 10917162988625838981, + "frontend/src/lib/components/dataset-review/SemanticLayerReview.svelte": 2844634204872241861, + "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/LICENSE": 14599279238716790189, + "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_promote.py": 16601872688404846307, + "venv/lib/python3.13/site-packages/pandas/io/excel/_xlrd.py": 14430937200583666658, + "venv/lib/python3.13/site-packages/websockets/typing.py": 13268801935274185287, + "venv/lib/python3.13/site-packages/pydantic/v1/tools.py": 1995883197897112278, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/automap.py": 4672057253309608464, + "frontend/build/_app/immutable/chunks/4Mt7E5DY.js": 1876154373397748488, + "backend/src/core/task_manager/__tests__/test_task_logger.py": 8175976176924379623, + "venv/lib/python3.13/site-packages/pip/_internal/models/format_control.py": 12916176880659590456, + "backend/tests/services/clean_release/test_report_audit_immutability.py": 11385235469772417017, + "venv/lib/python3.13/site-packages/pandas/io/formats/xml.py": 12235904458551067063, + "venv/lib/python3.13/site-packages/numpy/linalg/tests/test_regression.py": 5652583095949741238, + "venv/bin/fastapi": 12400009726251862770, + "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/__init__.py": 10920760520224795596, + "venv/lib/python3.13/site-packages/pip/_vendor/distro/__main__.py": 2688850704829116818, + "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/__init__.py": 11709551233929312136, + "venv/lib/python3.13/site-packages/_pytest/pytester.py": 5423287282155948827, + "venv/lib/python3.13/site-packages/pandas/io/parquet.py": 14415622950469421518, + "venv/lib/python3.13/site-packages/authlib/jose/rfc8037/okp_key.py": 10312614562914096039, + "venv/lib/python3.13/site-packages/certifi/__init__.py": 9045580998764948967, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_shift.py": 8547819448301023303, + "venv/lib/python3.13/site-packages/numpy/_core/numeric.py": 12261531924304979741, + "venv/lib/python3.13/site-packages/uvicorn/protocols/http/httptools_impl.py": 10367325397209016951, + "backend/tests/services/clean_release/test_compliance_execution_service.py": 5924200441771414883, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_logical/foo90.f90": 12508663906609241323, + "venv/lib/python3.13/site-packages/pandas/core/util/numba_.py": 3535857372998653863, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_python_parser_only.py": 12231449578582108346, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/types.py": 356973910046950951, + "venv/lib/python3.13/site-packages/pandas/tests/frame/test_constructors.py": 13890224577680389718, + "venv/lib/python3.13/site-packages/uvicorn/loops/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/core/einsumfunc.py": 3484247123731380377, + "venv/lib/python3.13/site-packages/pip/_internal/distributions/installed.py": 18153165899841229597, + "venv/lib/python3.13/site-packages/pydantic/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pip/_internal/utils/glibc.py": 12335359492756627313, + "venv/lib/python3.13/site-packages/ecdsa/test_keys.py": 17117188373419689467, + "venv/lib/python3.13/site-packages/jose/constants.py": 10880650415673457194, + "venv/lib/python3.13/site-packages/numpy/f2py/__main__.py": 12567751646090102167, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_errstate.py": 10788459171326750780, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/array.py": 13840510238256626632, + "venv/lib/python3.13/site-packages/pandas/core/algorithms.py": 487939626203097713, + "venv/lib/python3.13/site-packages/pygments/lexers/rita.py": 8105458520706587972, + "venv/lib/python3.13/site-packages/pygments/lexers/console.py": 18266795648198475028, + "venv/lib/python3.13/site-packages/httpx/_transports/default.py": 8391302827983907910, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/appengine.py": 16194997685865850655, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_x32_unix.h": 9165722966153119887, + "venv/lib/python3.13/site-packages/numpy/ma/tests/test_arrayobject.py": 9578555381494297966, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_pipe.py": 8255917221095334212, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_pivot_multilevel.py": 9830258607305392103, + "venv/lib/python3.13/site-packages/pycparser/_build_tables.py": 569728086093219621, + "venv/lib/python3.13/site-packages/uvicorn/_subprocess.py": 13965754246493254447, + "frontend/src/components/tools/MapperTool.svelte": 16528529568914906720, + "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/WHEEL": 16097436423493754389, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/conftest.py": 25473177671450048, + "frontend/build/_app/immutable/nodes/11.BfFQ1EX4.js": 7853694264472099005, + "backend/src/models/storage.py": 1218824901001897736, + "frontend/src/lib/components/translate/BulkReplaceModal.svelte": 17345501275392894037, + "venv/lib/python3.13/site-packages/httpcore/_api.py": 16499985295426060327, + "venv/lib/python3.13/site-packages/sqlalchemy/util/preloaded.py": 3719702436309355562, + "venv/lib/python3.13/site-packages/smmap/test/lib.py": 2924931247676024085, + "venv/lib/python3.13/site-packages/websockets/protocol.py": 6401227903827084901, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-log1p.csv": 16333455295913164408, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/dml.py": 6519732236745017861, + "venv/lib/python3.13/site-packages/pandas/core/tools/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pip/_internal/models/pylock.py": 16697828625021519459, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/declarative/extensions.py": 217122171232375592, + "venv/lib/python3.13/site-packages/fastapi/staticfiles.py": 4094330072433302614, + "venv/lib/python3.13/site-packages/tzlocal-5.3.1.dist-info/METADATA": 11439969143853665311, + "venv/lib/python3.13/site-packages/pandas/core/strings/__init__.py": 13025387151657797130, + "venv/lib/python3.13/site-packages/PIL/DcxImagePlugin.py": 11767274218348117481, + "venv/lib/python3.13/site-packages/bcrypt/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ufunclike.pyi": 12215374902556647369, + "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/WHEEL": 13232065379159720345, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_numeric.py": 5627177940393829333, + "venv/lib/python3.13/site-packages/pandas/tests/extension/json/test_json.py": 12422315190455428620, + "backend/src/plugins/__init__.py": 17194112070692432889, + "venv/lib/python3.13/site-packages/fastapi/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_rank.py": 5817408252050193538, + "venv/lib/python3.13/site-packages/PIL/_deprecate.py": 15076725072094847812, + "venv/lib/python3.13/site-packages/click/formatting.py": 6694583529073729642, + "venv/lib/python3.13/site-packages/pygments/lexers/meson.py": 14659991367778746658, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm64_masm.obj": 11967637259540485652, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/apply.py": 3906017176873949738, + "venv/lib/python3.13/site-packages/websockets/connection.py": 5168795926684067030, "venv/lib/python3.13/site-packages/python_multipart/decoders.py": 14252672585219598429, - "venv/lib/python3.13/site-packages/git/refs/__init__.py": 16246686106073400519, - "venv/lib/python3.13/site-packages/greenlet/TThreadState.hpp": 15599148954148720463, - "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_callback.py": 1689177048527329209, - "frontend/build/_app/immutable/nodes/24.EvmszrIx.js": 12117218792476024894, - "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/scalars.pyi": 17683675356659300769, - "venv/lib/python3.13/site-packages/numpy/core/_multiarray_umath.py": 10973016138581934035, - "venv/lib/python3.13/site-packages/jeepney-0.9.0.dist-info/METADATA": 15225661995655327539, + "venv/lib/python3.13/site-packages/pandas/tests/series/test_api.py": 13319208721442328400, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/transform/test_transform.py": 5674175311567817854, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/base.py": 7855217087916771270, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/models.py": 9513172366009392193, + "venv/lib/python3.13/site-packages/numpy/core/overrides.pyi": 1968648615494204783, + "venv/lib/python3.13/site-packages/pandas/core/frame.py": 2630807744775247533, + "backend/tests/services/clean_release/test_candidate_manifest_services.py": 16861589402854148894, + "venv/lib/python3.13/site-packages/numpy/fft/__init__.py": 9343449448737026658, + "venv/lib/python3.13/site-packages/pandas/tests/window/test_online.py": 11850497659869773510, + "venv/lib/python3.13/site-packages/pandas/core/computation/common.py": 5369352684655954608, + "venv/lib/python3.13/site-packages/pandas/core/groupby/categorical.py": 16588862198627920420, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/__init__.py": 4014740126161973332, + "venv/lib/python3.13/site-packages/pandas/_libs/parsers.cpython-313-x86_64-linux-gnu.so": 14134106903573638108, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_tz_localize.py": 14495969595744172955, + "venv/lib/python3.13/site-packages/pygments/lexers/_lasso_builtins.py": 4006621424665751347, + "backend/src/models/dataset_review_pkg/_execution_models.py": 9810012962062422666, + "venv/lib/python3.13/site-packages/PIL/_imagingmath.cpython-313-x86_64-linux-gnu.so": 77725273398858074, + "venv/lib/python3.13/site-packages/websockets/asyncio/connection.py": 17044409627448400723, + "venv/lib/python3.13/site-packages/numpy/f2py/crackfortran.pyi": 9206355685192026844, + "frontend/build/_app/immutable/nodes/16.CNhvwO2y.js": 13656477822667393544, + "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/converter.py": 9041278869295701566, + "venv/lib/python3.13/site-packages/numpy/random/_pcg64.cpython-313-x86_64-linux-gnu.so": 5759445712745875888, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/assignOnlyModule.f90": 15967199601254912096, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/information_schema.py": 8551227132710897346, + "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/RECORD": 4487477737768669516, + "venv/lib/python3.13/site-packages/_pytest/python.py": 1829073958095716309, + "venv/lib/python3.13/site-packages/pip/_internal/network/xmlrpc.py": 5064964778750366059, + "venv/lib/python3.13/site-packages/cryptography/x509/extensions.py": 10197248868682803019, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/mutable.py": 9323088483998280629, + "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/METADATA": 10810011740984652381, + "venv/lib/python3.13/site-packages/pandas/core/dtypes/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_indexing.py": 3841182456456779012, + "backend/src/schemas/translate.py": 4202862152769241553, + "venv/lib/python3.13/site-packages/passlib/tests/test_utils_pbkdf2.py": 17016810698578473773, + "venv/lib/python3.13/site-packages/pygments/lexers/archetype.py": 8995143180482517233, + "venv/lib/python3.13/site-packages/pygments/lexers/inferno.py": 9056274496469409594, + "venv/lib/python3.13/site-packages/pandas/core/roperator.py": 2587829042468916489, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/np_datetime.pyi": 2884703536776830012, + "backend/src/services/dataset_review/event_logger.py": 8083530196989488371, + "venv/lib/python3.13/site-packages/apscheduler/schedulers/asyncio.py": 11442130378027628520, + "venv/lib/python3.13/site-packages/idna-3.11.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/common.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/base_server.py": 9643197259080504542, + "venv/lib/python3.13/site-packages/pip/_vendor/tomli/__init__.py": 12906995259233516197, + "venv/lib/python3.13/site-packages/referencing/_attrs.py": 14434891919747863272, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-tanh.csv": 6674536825156196036, + "venv/lib/python3.13/site-packages/pyasn1/type/constraint.py": 16776615503418773283, + "venv/lib/python3.13/site-packages/passlib/tests/test_ext_django.py": 3210697476292094384, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/result.py": 8306497889916212025, + "venv/lib/python3.13/site-packages/yaml/dumper.py": 11376022992370902766, + "venv/lib/python3.13/site-packages/pygments/styles/manni.py": 11853576691280294949, + "venv/lib/python3.13/site-packages/pygments/lexers/qlik.py": 3881663935630350152, + "backend/src/api/routes/plugins.py": 2062850550409490465, + "venv/lib/python3.13/site-packages/h11/_readers.py": 832030916375670301, + "venv/lib/python3.13/site-packages/ecdsa/test_ellipticcurve.py": 11125783981574901613, + "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/errors.py": 4817746830102488448, + "venv/lib/python3.13/site-packages/pandas/core/computation/pytables.py": 16326122536715961388, + "venv/lib/python3.13/site-packages/pygments/lexers/smithy.py": 10789533877863290582, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_to_frame.py": 4303613319747945709, + "venv/lib/python3.13/site-packages/pydantic/functional_serializers.py": 15285359935059345032, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_isin.py": 11330491145602008796, + "venv/lib/python3.13/site-packages/pandas/tests/extension/test_numpy.py": 4073641912755651877, + "venv/lib/python3.13/site-packages/fastapi/logger.py": 11590581556317053213, + "venv/lib/python3.13/site-packages/jeepney-0.9.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/METADATA": 3786116428839780263, + "venv/lib/python3.13/site-packages/pygments/styles/arduino.py": 4578385147314541233, + "venv/lib/python3.13/site-packages/pip/_vendor/packaging/version.py": 5000350193835202949, + "venv/lib/python3.13/site-packages/numpy/doc/ufuncs.py": 11706048944901534664, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_join.py": 4213933887062089605, + "venv/lib/python3.13/site-packages/pip/_internal/network/session.py": 293771075394156394, + "frontend/build/_app/immutable/chunks/Dvp0aVhC.js": 16109929560541789895, + "venv/lib/python3.13/site-packages/jeepney/io/tests/test_asyncio.py": 2820168745710754136, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/_openssl.pyi": 4376871621615688626, + "venv/lib/python3.13/site-packages/cryptography/exceptions.py": 5173540025160237758, + "venv/lib/python3.13/site-packages/numpy/_distributor_init.py": 1101690714183863290, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/openssl/_conditional.py": 14190849361275154667, + "venv/lib/python3.13/site-packages/starlette/middleware/wsgi.py": 12506262030845301606, + "venv/lib/python3.13/site-packages/pandas/_libs/__init__.py": 17117112389651696580, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/request.py": 10492090878715126550, + "venv/lib/python3.13/site-packages/greenlet/PyModule.cpp": 3464405102256525511, + "venv/lib/python3.13/site-packages/numpy/random/__init__.pxd": 7355772669172093814, + "venv/lib/python3.13/site-packages/pandas/tests/io/test_feather.py": 13613400750755530364, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame_color.py": 3700828402084646308, + "venv/lib/python3.13/site-packages/yaml/composer.py": 13619070314468518566, + "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/structs.py": 4479429145468072604, + "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/RECORD": 963865046004908868, + "venv/lib/python3.13/site-packages/pandas/tests/extension/array_with_attr/test_array_with_attr.py": 6568496539994758985, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_formats.py": 9738552308554950419, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_results.py": 18145930285449734975, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_matmul.py": 9323220618335072725, + "venv/lib/python3.13/site-packages/sqlalchemy/connectors/pyodbc.py": 4146960201984489604, + "backend/src/api/routes/connections.py": 3871707738958709690, + "frontend/src/routes/datasets/review/[id]/__tests__/dataset_review_workspace.ux.test.js": 4105775024258653726, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi": 10784666243744187693, + "venv/lib/python3.13/site-packages/pandas/core/sorting.py": 689057022713741051, + "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/secrets.py": 17816662030600756342, + "venv/lib/python3.13/site-packages/apscheduler/executors/pool.py": 10344126569001032241, + "venv/lib/python3.13/site-packages/pip/_internal/operations/install/editable_legacy.py": 8145740626773638218, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_complex.py": 4290059580478881700, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh25286.f90": 1249061697041863692, + "venv/lib/python3.13/site-packages/pyasn1/type/univ.py": 7163437624197683039, + "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/processors.cpython-313-x86_64-linux-gnu.so": 18139875206371157315, + "venv/lib/python3.13/site-packages/pygments/styles/zenburn.py": 1031869867933871309, + "backend/src/services/clean_release/repositories/compliance_repository.py": 7402628017251283691, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/pyodbc.py": 11271266527234292020, + "venv/lib/python3.13/site-packages/git/refs/head.py": 16271128287606894569, + "venv/lib/python3.13/site-packages/pygments/lexers/phix.py": 16775285097768256238, + "frontend/src/lib/ui/PageHeader.svelte": 3800784212388586861, + "venv/lib/python3.13/site-packages/pandas/tseries/offsets.py": 13750652921710295115, + "venv/lib/python3.13/site-packages/numpy/lib/_twodim_base_impl.py": 4154852745131464543, + "backend/tests/scripts/test_clean_release_cli.py": 13978106497618764226, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_asof.py": 17616601748321325187, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/accesstype.f90": 877982462186396830, + "venv/lib/python3.13/site-packages/numpy/core/__init__.pyi": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/frame/test_validate.py": 12789481642730855139, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_constructors.py": 5627819885594450614, + "backend/tests/scripts/test_clean_release_tui.py": 14700450036639944764, + "venv/lib/python3.13/site-packages/typing_inspection/typing_objects.pyi": 18193727720492050602, + "venv/lib/python3.13/site-packages/pydantic_core/__init__.py": 10563134104783445328, + "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/requirements.py": 13215932786801020434, + "venv/lib/python3.13/site-packages/numpy/lib/_npyio_impl.pyi": 6576645822227068922, + "venv/bin/pyrsa-keygen": 8222542582170363672, + "venv/lib/python3.13/site-packages/httpx/_urlparse.py": 8270294590945652412, + "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/RECORD": 3205266407680661753, + "venv/lib/python3.13/site-packages/pandas/_libs/tslib.pyi": 16170606956605100142, + "venv/lib/python3.13/site-packages/numpy/lib/_function_base_impl.pyi": 2628035888703031029, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/numeric.py": 14451517189908259173, + "venv/lib/python3.13/site-packages/pandas/tests/extension/base/groupby.py": 12749730954888633240, + "frontend/src/routes/datasets/[id]/+page.svelte": 3377235098319163133, + "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/METADATA": 16700674024421191168, + "venv/lib/python3.13/site-packages/pluggy/_tracing.py": 7276210024011809655, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_snap.py": 4515844385819802784, + "venv/lib/python3.13/site-packages/pip/_vendor/requests/packages.py": 11689856177725665974, + "venv/lib/python3.13/site-packages/attr/py.typed": 15130871412783076140, + "backend/src/schemas/settings.py": 7182606947764184429, + "venv/lib/python3.13/site-packages/starlette/applications.py": 13591448461234020757, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_clip.py": 11111183698178681331, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_regression.py": 16293647824734937323, + "venv/lib/python3.13/site-packages/pandas/core/tools/datetimes.py": 13313374952742129866, + "venv/lib/python3.13/site-packages/pandas/tests/frame/test_logical_ops.py": 16166386974005224415, + "venv/lib/python3.13/site-packages/pandas/tests/series/test_unary.py": 8046543893978198672, + "venv/lib/python3.13/site-packages/psycopg2/_ipaddress.py": 12332672835751787869, + "backend/src/api/routes/__tests__/test_assistant_authz.py": 8404416194210647280, + "venv/lib/python3.13/site-packages/numpy/_core/getlimits.pyi": 15746478550640231553, + "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py": 14946223589457772924, + "venv/lib/python3.13/site-packages/apscheduler/triggers/interval.py": 3964550092873794670, + "venv/lib/python3.13/site-packages/keyring/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pygments/lexers/trafficscript.py": 776604244051744646, + "frontend/build/_app/env.js": 8815854342083926790, + "venv/lib/python3.13/site-packages/_pytest/monkeypatch.py": 2635774457434545573, + "frontend/src/components/tasks/TaskResultPanel.svelte": 193489346212840974, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_base.py": 16710163879060522196, + "venv/lib/python3.13/site-packages/pip/_vendor/packaging/metadata.py": 7204343250279221076, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_inf.py": 8659210689723088321, + "venv/lib/python3.13/site-packages/urllib3-2.6.2.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/methods/test_round.py": 7912161077874611432, + "venv/lib/python3.13/site-packages/jose/jwe.py": 3325660353225624025, + "venv/lib/python3.13/site-packages/ecdsa/test_eddsa.py": 1785854649532849946, + "venv/lib/python3.13/site-packages/pip/_vendor/distlib/scripts.py": 8759605303886441976, + "venv/lib/python3.13/site-packages/numpy/lib/array_utils.py": 18135114588643176359, + "venv/lib/python3.13/site-packages/websockets/legacy/__init__.py": 12332512329533591682, + "venv/lib/python3.13/site-packages/numpy/char/__init__.pyi": 12214207343146244743, + "venv/lib/python3.13/site-packages/pandas/core/interchange/dataframe.py": 16525846817331842080, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/datetimes/test_cumulative.py": 6346947559103505068, + "venv/lib/python3.13/site-packages/pygments/lexers/_vbscript_builtins.py": 9882134558469491349, + "venv/lib/python3.13/site-packages/pygments/lexers/tal.py": 447505725492547461, + "venv/lib/python3.13/site-packages/pandas/core/col.py": 4221271461723119525, + "venv/lib/python3.13/site-packages/pygments/lexers/web.py": 11104721221615804497, + "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/min_max_.py": 13457611930368041821, + "venv/lib/python3.13/site-packages/greenlet/tests/test_extension_interface.py": 11693583111513457974, + "venv/lib/python3.13/site-packages/pandas/tests/window/test_expanding.py": 9047466276603454007, + "venv/lib/python3.13/site-packages/pydantic_settings/sources/types.py": 13384984564922916167, + "venv/lib/python3.13/site-packages/jsonschema/_format.py": 8987698648383779883, + "venv/lib/python3.13/site-packages/jsonschema/tests/test_types.py": 651959450717569029, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_win32_console.py": 18092547253031555768, + "venv/lib/python3.13/site-packages/jose/backends/base.py": 12795468809472351388, + "venv/lib/python3.13/site-packages/rapidfuzz/__init__.py": 12462153783886855740, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_2_compat.h": 6512969159139431485, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_getitem.py": 11882213323878588707, + "venv/lib/python3.13/site-packages/numpy/f2py/symbolic.pyi": 14558091964387571257, + "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pip/_internal/cli/index_command.py": 15798187258841839292, + "venv/lib/python3.13/site-packages/pandas/core/dtypes/dtypes.py": 9839461501970023861, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_excel.py": 5467043641314706635, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_kind.py": 18178830861475480607, + "venv/lib/python3.13/site-packages/pandas/tests/io/test_stata.py": 3030675968330529905, + "venv/lib/python3.13/site-packages/pandas/io/json/_normalize.py": 15938855324762935595, + "backend/src/services/clean_release/artifact_catalog_loader.py": 16969668877930596278, + "venv/lib/python3.13/site-packages/gitdb/base.py": 7927279446353696534, + "venv/lib/python3.13/site-packages/httpx/_auth.py": 1283189552342958900, + "venv/lib/python3.13/site-packages/pip/_internal/cli/req_command.py": 2887890799766730546, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_symbolic.py": 8093576026032854125, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/formatters/__init__.py": 3247870839323520754, + "venv/lib/python3.13/site-packages/numpy/_core/overrides.py": 252940520997718714, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_internals.py": 10472508540875131797, + "venv/lib/python3.13/site-packages/pandas/tests/frame/test_unary.py": 2573825678342936734, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/ed448.py": 12264234876933578367, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/urllib3/contrib/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/click/testing.py": 15973659312284678327, + "venv/lib/python3.13/site-packages/ecdsa/util.py": 10543788809724099209, + "venv/lib/python3.13/site-packages/referencing/tests/test_exceptions.py": 10846225989746274213, + "backend/src/models/filter_state.py": 6470311179852241297, + "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/__init__.py": 16416360448593978041, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/token.py": 6987328478153445584, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/asyncio.py": 2517623574187179319, + "backend/src/plugins/llm_analysis/__tests__/test_screenshot_service.py": 17792688368296989200, + "venv/lib/python3.13/site-packages/pip/_internal/utils/retry.py": 15244280495983216204, + "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/METADATA": 14180973198574731599, + "backend/src/services/clean_release/policy_resolution_service.py": 5075709738950902327, + "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/RECORD": 11904769847385571600, + "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/RECORD": 10052481303799123207, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/token_validator.py": 2932866595454490527, + "venv/lib/python3.13/site-packages/keyring/testing/backend.py": 14295829193445781542, + "venv/lib/python3.13/site-packages/pygments/lexers/wren.py": 6259586056260713984, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_series_equal.py": 1223890028205011021, + "frontend/src/services/__tests__/gitService.test.js": 12845562082447336909, + "venv/lib/python3.13/site-packages/pandas/tests/frame/test_cumulative.py": 15644124412739892167, + "venv/lib/python3.13/site-packages/numpy/random/mtrand.pyi": 17144590106028661128, + "venv/lib/python3.13/site-packages/dateutil/_version.py": 8279235793001245767, + "venv/lib/python3.13/site-packages/dateutil/tz/win.py": 8427821225251397364, + "venv/lib/python3.13/site-packages/pygments/styles/vim.py": 2621036947954523349, + "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/test_arithmetic.py": 14858832264660410908, + "venv/lib/python3.13/site-packages/pygments/lexers/typst.py": 8883289726601667104, + "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/__init__.py": 5895297076117159245, + "venv/lib/python3.13/site-packages/numpy/lib/stride_tricks.py": 548928042543500365, + "venv/lib/python3.13/site-packages/numpy/random/_pickle.pyi": 16081120364372391381, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/transform/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pytest/__main__.py": 8747175113746141224, + "venv/lib/python3.13/site-packages/more_itertools/more.pyi": 4844596605492825806, + "venv/lib/python3.13/site-packages/itsdangerous/_json.py": 4872267972688724005, + "venv/lib/python3.13/site-packages/dotenv/__main__.py": 16883579879172186355, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_join.py": 2585969863606902743, + "venv/lib/python3.13/site-packages/pandas/tests/config/test_config.py": 4630144191929135452, + "frontend/build/_app/immutable/chunks/DBhKLy_4.js": 87415875228682141, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/identity.py": 326059526167697655, + "backend/src/plugins/translate/_token_budget.py": 3072188939870967700, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/mod.pyi": 10591120373577657317, + "venv/lib/python3.13/site-packages/pyasn1/type/namedval.py": 8273171503516887681, + "venv/lib/python3.13/site-packages/smmap/test/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/retry.py": 17371295199208325375, + "venv/lib/python3.13/site-packages/keyring/util/__init__.py": 9635016046220094473, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_show_versions.py": 10577134135855180356, + "venv/lib/python3.13/site-packages/starlette/middleware/gzip.py": 4321371046149637632, + "venv/lib/python3.13/site-packages/anyio/abc/_streams.py": 8089057973257658396, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_non_unique.py": 15286893322149413712, + "venv/lib/python3.13/site-packages/fastapi/_compat/v1.py": 9776181748061371513, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/lib_utils.pyi": 3708905060001289515, + "venv/lib/python3.13/site-packages/pandas/tests/test_aggregation.py": 16863055892192070549, + "venv/lib/python3.13/site-packages/pandas/tests/window/test_groupby.py": 15721254196883995634, + "venv/lib/python3.13/site-packages/jsonschema/tests/_suite.py": 6307666366417438489, + "venv/lib/python3.13/site-packages/pandas/tests/window/test_numba.py": 6409810497251251179, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/json.py": 14755215397454910426, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_half.py": 3121836756584726126, + "venv/lib/python3.13/site-packages/cryptography/hazmat/decrepit/ciphers/__init__.py": 63497920264089252, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_astype.py": 7497268667246913350, + "venv/lib/python3.13/site-packages/pandas/tests/io/xml/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/charset_normalizer/models.py": 9917300217816275821, + "venv/lib/python3.13/site-packages/jsonschema/tests/typing/test_all_concrete_validators_match_protocol.py": 14824388798676578409, + "venv/lib/python3.13/site-packages/pygments/lexers/typoscript.py": 6706632522710582762, + "backend/tests/test_log_persistence.py": 11073909507089982937, + "venv/lib/python3.13/site-packages/numpy/f2py/__version__.py": 8588600299261398598, + "venv/lib/python3.13/site-packages/pandas/io/formats/excel.py": 797619981868084011, + "venv/lib/python3.13/site-packages/pygments/lexers/ruby.py": 6898093948224302592, + "venv/lib/python3.13/site-packages/pygments/lexers/webmisc.py": 9530962803076253849, + "venv/lib/python3.13/site-packages/pandas/tests/extension/base/printing.py": 8681519649669408795, + "venv/lib/python3.13/site-packages/pygments/lexers/_lilypond_builtins.py": 1766946089314631488, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/test_formats.py": 18080627205081311773, + "backend/tests/test_translate_executor_filter.py": 11717560360659156703, + "venv/lib/python3.13/site-packages/pyasn1/codec/native/__init__.py": 15728752901274520502, + "venv/lib/python3.13/site-packages/pip/_internal/models/selection_prefs.py": 14700113736620314923, + "venv/lib/python3.13/site-packages/h11/_abnf.py": 10456996134895429201, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/request.py": 10484280068366411541, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/cli/gh_22819.pyf": 14717748358749934995, + "venv/lib/python3.13/site-packages/pip/_internal/commands/freeze.py": 8644678595442275485, + "venv/lib/python3.13/site-packages/starlette/templating.py": 9242638124487797988, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timezones.pyi": 17528421279543420867, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_tools.py": 13994164937603424236, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_deprecate_nonkeyword_arguments.py": 11676809974120007408, + "venv/lib/python3.13/site-packages/PIL/PdfParser.py": 13710342183037972042, + "venv/lib/python3.13/site-packages/yaml/emitter.py": 6036657460416912844, + "backend/src/schemas/health.py": 13764741380188041840, + "venv/lib/python3.13/site-packages/pygments/lexers/fantom.py": 1986459352773446836, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/char.f90": 12203871998988759364, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_delete.py": 5958440386632506587, + "venv/lib/python3.13/site-packages/pandas/arrays/__init__.py": 10005095663840461954, + "backend/src/services/clean_release/exceptions.py": 14631509303697939633, + "venv/lib/python3.13/site-packages/sqlalchemy/util/_has_cy.py": 11979732417254560424, + "venv/lib/python3.13/site-packages/uvicorn/middleware/asgi2.py": 5355343704425405009, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pygments/lexers/_csound_builtins.py": 14530739818491398298, + "backend/src/api/routes/git/_repo_operations_routes.py": 17252968422647919723, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/_globals.py": 8736093011628027941, + "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/extension_types.py": 1856757457657310231, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ma.py": 15912582628112164509, + "venv/lib/python3.13/site-packages/pygments/lexers/factor.py": 15788613154609197002, + "venv/lib/python3.13/site-packages/pandas/core/arrays/_ranges.py": 2572903460327860111, + "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/RECORD": 1556051687830913019, + "backend/src/services/git/_sync.py": 16596597562042405179, + "venv/lib/python3.13/site-packages/gitdb/test/lib.py": 13294941660283059872, + "backend/src/api/routes/__tests__/test_reports_openapi_conformance.py": 14282751162289385516, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh15035.f": 13126319439858352711, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_timedelta_range.py": 15081095442418142820, + "venv/lib/python3.13/site-packages/pygments/styles/sas.py": 12363791134941577382, + "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/h11/_state.py": 11398755254809751139, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/test_arithmetic.py": 16045758521544316139, + "venv/lib/python3.13/site-packages/cffi/vengine_cpy.py": 10684192171370688079, + "venv/lib/python3.13/site-packages/pip/_internal/commands/hash.py": 11824898770873127699, + "venv/lib/python3.13/site-packages/gitdb/fun.py": 55226330810782184, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_html.py": 7947998260347730581, + "venv/lib/python3.13/site-packages/numpy/lib/tests/data/win64python2.npy": 11005857803794805939, + "backend/src/scripts/clean_release_cli.py": 14467814161661747234, + "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_hermite.py": 3628609433179387988, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalarinherit.py": 15240535501243623986, + "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/METADATA": 11557342107649194148, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked_shared.py": 8453174300922339015, + "venv/lib/python3.13/site-packages/pluggy/_version.py": 7195758686717994475, + "venv/lib/python3.13/site-packages/numpy/_core/_dtype_ctypes.py": 5564496700647900501, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/bulk_persistence.py": 2307818727114646866, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_comparison.py": 11333735187162513512, + "venv/lib/python3.13/site-packages/pygments/styles/fruity.py": 7925019839136894457, + "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/var_.py": 12699521091170347311, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_dlpack.py": 7908102652282922952, + "venv/lib/python3.13/site-packages/passlib/tests/sample1b.cfg": 2872366861156549016, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/ed25519.pyi": 16312114056447366970, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_string.py": 10141066226714805009, + "venv/lib/python3.13/site-packages/git/objects/submodule/root.py": 5322248117564025370, + "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/RECORD": 4857922668040624663, + "venv/lib/python3.13/site-packages/pip/_internal/utils/logging.py": 9639351759822608724, + "venv/lib/python3.13/site-packages/pygments/lexers/soong.py": 10273453675034306814, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_setops.py": 15196593522537569500, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_printing.py": 8859757563354666575, + "venv/lib/python3.13/site-packages/PIL/ImageDraw.py": 12919304671639673744, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_join.py": 17874591841487372992, + "venv/lib/python3.13/site-packages/pygments/lexers/_sourcemod_builtins.py": 11809503654078535014, + "venv/lib/python3.13/site-packages/greenlet/TBrokenGreenlet.cpp": 10822436772777706192, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/context.py": 1041624619197012753, + "venv/lib/python3.13/site-packages/pandas/core/reshape/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_constructors.py": 9815164146739254076, + "venv/lib/python3.13/site-packages/pandas/_libs/sas.cpython-313-x86_64-linux-gnu.so": 16309838137741124637, + "venv/lib/python3.13/site-packages/pandas/io/excel/_xlsxwriter.py": 16873939324418752965, + "venv/lib/python3.13/site-packages/git/objects/commit.py": 12317865358846331802, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/fromnumeric.pyi": 8671744104085911610, + "venv/lib/python3.13/site-packages/pandas/io/formats/format.py": 3364941338174434661, + "venv/lib/python3.13/site-packages/pandas/core/window/common.py": 17956497339875932377, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_old_base.py": 191359377446257900, + "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_construct_from_scalar.py": 16520136036631155842, + "venv/lib/python3.13/site-packages/pip/_internal/configuration.py": 2563100675379605810, + "venv/lib/python3.13/site-packages/pandas/tests/io/sas/test_sas7bdat.py": 8963983384208121526, + "venv/lib/python3.13/site-packages/numpy/f2py/func2subr.pyi": 16573082220135508510, + "venv/lib/python3.13/site-packages/pygments/style.py": 17393199235575070210, + "frontend/build/_app/immutable/nodes/19.UaiNjUdw.js": 17580400751027983788, + "venv/lib/python3.13/site-packages/pygments/lexers/pddl.py": 9256112535059995841, + "venv/lib/python3.13/site-packages/pandas/core/arrays/boolean.py": 8821671562937866269, + "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_multiarray.py": 3592197154340095431, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_custom_business_day.py": 2200008998040663785, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7662/token_validator.py": 13917237710752731397, + "venv/lib/python3.13/site-packages/urllib3/http2/connection.py": 1661620860881397554, + "frontend/src/lib/stores/__tests__/setupTests.js": 13316015450930652502, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/random/libdivide.h": 5314232500579481313, + "venv/lib/python3.13/site-packages/pygments/lexers/crystal.py": 3579547906957125755, + "venv/lib/python3.13/site-packages/pandas/core/ops/missing.py": 9493665944764255854, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_tz_convert.py": 77283525137564255, + "venv/lib/python3.13/site-packages/pygments/lexers/agile.py": 5686162551416231457, + "backend/src/api/routes/admin.py": 16164005699911103765, + "venv/lib/python3.13/site-packages/pip/_internal/utils/temp_dir.py": 8657533190026387896, + "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_api.py": 7131036004750554905, + "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/base.py": 13454394827268856575, + "venv/lib/python3.13/site-packages/fastapi/websockets.py": 9910052969532075719, + "venv/lib/python3.13/site-packages/_pytest/assertion/truncate.py": 14000392306994773741, + "frontend/src/routes/translate/history/+page.svelte": 7874402226825627914, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/offsets.cpython-313-x86_64-linux-gnu.so": 6726636942028566415, + "venv/lib/python3.13/site-packages/numpy/linalg/__init__.py": 15647756307608142577, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/declarative/__init__.py": 2436195108273216959, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_frame.py": 2169381747938271444, + "venv/lib/python3.13/site-packages/rsa/prime.py": 10820898885044917095, + "venv/lib/python3.13/site-packages/jsonschema/exceptions.py": 15651767069704734674, + "venv/lib/python3.13/site-packages/pip/_internal/metadata/pkg_resources.py": 14271077832999370068, + "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/licenses/LICENSE": 13322127602069971876, + "venv/lib/python3.13/site-packages/pillow.libs/libharfbuzz-0692f733.so.0.61230.0": 23110287346167671, + "venv/lib/python3.13/site-packages/numpy/lib/_scimath_impl.py": 14696841109142419143, + "venv/lib/python3.13/site-packages/numpy/random/_mt19937.cpython-313-x86_64-linux-gnu.so": 85866616759631810, + "venv/lib/python3.13/site-packages/pip/_internal/operations/build/wheel_editable.py": 14352954849821931255, + "venv/lib/python3.13/site-packages/pydantic/root_model.py": 20625057828723317, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7516/jwe.py": 10478268710546063196, + "venv/lib/python3.13/site-packages/pip/_internal/commands/download.py": 7533669665002975823, + "frontend/build/_app/immutable/nodes/34.CPCAjONs.js": 8672599980797084253, + "venv/lib/python3.13/site-packages/fastapi/middleware/cors.py": 7452860773712601508, + "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/METADATA": 11419135077900073883, + "venv/lib/python3.13/site-packages/pandas/core/indexes/frozen.py": 1419685664276640120, + "venv/lib/python3.13/site-packages/pandas/tests/io/test_gcs.py": 7733247456252965901, + "venv/lib/python3.13/site-packages/pip/_internal/utils/_jaraco_text.py": 9046755357011730699, + "venv/lib/python3.13/site-packages/jeepney/fds.py": 16573439672758641560, + "venv/lib/python3.13/site-packages/pydantic/v1/version.py": 2758971830527526972, + "frontend/build/_app/immutable/chunks/ikwS1dR6.js": 3267599179274813039, + "venv/lib/python3.13/site-packages/pydantic/type_adapter.py": 10162988530225478692, + "venv/lib/python3.13/site-packages/pygments/styles/nord.py": 8469538903422182155, + "backend/src/core/auth/logger.py": 14199514105394646252, + "venv/lib/python3.13/site-packages/rapidfuzz/process_py.py": 17563673072076876125, + "venv/lib/python3.13/site-packages/pydantic/json_schema.py": 15678278224696353978, + "venv/lib/python3.13/site-packages/pip/_internal/operations/freeze.py": 3469845570614985559, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/_typing.py": 17589387690638097975, + "venv/lib/python3.13/site-packages/httpcore/_backends/anyio.py": 6167729964577005634, + "venv/lib/python3.13/site-packages/pygments/lexers/rust.py": 8605690716125176329, + "venv/lib/python3.13/site-packages/numpy/fft/tests/test_pocketfft.py": 18025182347224285050, + "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_take.py": 1216902953519121176, + "backend/src/core/task_manager/persistence.py": 7896628499516364250, + "venv/lib/python3.13/site-packages/numpy/matlib.py": 112839038090033740, + "venv/lib/python3.13/site-packages/cffi/ffiplatform.py": 6782148110863549472, + "venv/lib/python3.13/site-packages/passlib/utils/__init__.py": 11704122205941631503, + "frontend/src/lib/stores/health.js": 3437957055218721782, + "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/RECORD": 11111103193315065053, + "venv/lib/python3.13/site-packages/starlette/config.py": 16509394679506300256, + "venv/lib/python3.13/site-packages/sqlalchemy/inspection.py": 8563914460959280101, + "backend/src/core/auth/security.py": 8289703096420999159, + "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/util.py": 18279366777506483176, + "venv/lib/python3.13/site-packages/python_multipart/__init__.py": 10290895261363712562, + "venv/lib/python3.13/site-packages/pandas/core/groupby/indexing.py": 18009437216172136227, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py": 8530403239168529668, + "venv/lib/python3.13/site-packages/_pytest/python_api.py": 12953851690889336092, + "venv/lib/python3.13/site-packages/pip/_vendor/certifi/cacert.pem": 15624463015628939254, + "venv/lib/python3.13/site-packages/pygments/lexers/foxpro.py": 14032656072384708293, + "venv/lib/python3.13/site-packages/pygments/styles/tango.py": 12389250878249075539, + "backend/src/api/routes/assistant/_command_parser.py": 2745692387994130159, + "frontend/src/lib/toasts.js": 199299975383904134, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_nlargest.py": 1423106021399469694, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7591/errors.py": 17581857895562494222, + "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_construct_object_arr.py": 4725156416161661681, + "venv/lib/python3.13/site-packages/pygments/lexers/blueprint.py": 6370363226580199085, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/__init__.py": 15130871412783076140, + "backend/src/app.py": 1030174853208129525, + "venv/bin/f2py": 11006035631504708368, + "frontend/src/components/MissingMappingModal.svelte": 11264881226066623003, + "venv/lib/python3.13/site-packages/anyio/_core/_exceptions.py": 11969894261631227715, + "venv/lib/python3.13/site-packages/pandas/tests/generic/test_to_xarray.py": 15341013524814290960, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_deprecations.py": 6015734648984591027, + "venv/lib/python3.13/site-packages/pandas/tests/io/test_iceberg.py": 1726421917529457420, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_formats.py": 17821648708413143557, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_aarch64_gcc.h": 8140470539757491899, + "venv/lib/python3.13/site-packages/pandas/core/reshape/melt.py": 14109947554124551986, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_markdown.py": 9964642152916165317, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_select.py": 7083040959665006634, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_polynomial.py": 3049262771098624825, + "venv/lib/python3.13/site-packages/psycopg2/_range.py": 7184417109068014771, + "venv/lib/python3.13/site-packages/numpy/ma/mrecords.py": 687170905107114309, + "venv/lib/python3.13/site-packages/numpy/ctypeslib/__init__.py": 2401931196871484449, + "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_timezones.py": 1962830142478494009, + "venv/lib/python3.13/site-packages/numpy/lib/_scimath_impl.pyi": 8879196542984811747, + "venv/lib/python3.13/site-packages/sqlalchemy/util/typing.py": 17638587764345605306, + "venv/lib/python3.13/site-packages/uvicorn/workers.py": 7213290478118197047, + "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/caches/__init__.py": 11808051681178127650, + "venv/lib/python3.13/site-packages/pygments/lexers/capnproto.py": 15713281507099411738, + "frontend/src/components/llm/DocPreview.svelte": 9286231407313632900, + "frontend/build/_app/immutable/chunks/BsdYA8vJ.js": 17313445894049649179, + "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/RECORD": 9974324769263969827, + "venv/lib/python3.13/site-packages/pygments/lexers/vip.py": 11287963054551122004, + "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/METADATA": 13633829318759752611, + "venv/lib/python3.13/site-packages/pandas/tests/extension/base/__init__.py": 16123561007855424016, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_infer_objects.py": 16868563755487479303, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_tz_localize.py": 4937713043686953098, + "frontend/src/pages/Settings.svelte": 5110524159352803966, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/strategies.py": 15673926142454922581, + "venv/lib/python3.13/site-packages/pandas/_config/__init__.py": 3577026529387563519, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/matrix.pyi": 15667024840812783911, + "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/resultproxy.cpython-313-x86_64-linux-gnu.so": 6011605826065363427, + "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/WHEEL": 7145482834744213753, + "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/__init__.pyi": 15820654525292895396, + "venv/lib/python3.13/site-packages/starlette/responses.py": 14081178833432955042, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/x25519.pyi": 11455144434558323236, + "venv/lib/python3.13/site-packages/pydantic/v1/networks.py": 13262073155118055511, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/PIL/PdfImagePlugin.py": 16082854250442815862, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_from_dummies.py": 5670811108950300761, + "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/utils.py": 2959395751217827103, + "venv/lib/python3.13/site-packages/pandas/tests/io/test_orc.py": 1248059610437937895, + "venv/lib/python3.13/site-packages/pip/_internal/models/link.py": 7172346414535657925, + "venv/lib/python3.13/site-packages/pip/_vendor/distlib/markers.py": 8297667990263004097, + "venv/lib/python3.13/site-packages/pandas/core/array_algos/quantile.py": 17341029201525362074, + "venv/lib/python3.13/site-packages/authlib/integrations/base_client/__init__.py": 1856412417337875350, + "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_argon2.py": 11345706437113628133, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timedeltas.cpython-313-x86_64-linux-gnu.so": 17089839649971421164, + "venv/lib/python3.13/site-packages/attr/setters.py": 12467854389745942025, + "venv/lib/python3.13/site-packages/pandas/_libs/_cyutility.cpython-313-x86_64-linux-gnu.so": 3372660143512868174, + "venv/lib/python3.13/site-packages/websockets/frames.py": 4901850477414613953, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_monotonic.py": 14648437502004398715, + "venv/lib/python3.13/site-packages/numpy/f2py/rules.pyi": 1342380029484127983, + "venv/lib/python3.13/site-packages/pandas/tests/window/moments/test_moments_consistency_expanding.py": 12504275097476819918, + "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/meta-data": 11957232619107868023, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/OSA_py.py": 2494967094400350388, + "venv/lib/python3.13/site-packages/numpy/_core/memmap.py": 4093510602708416858, + "venv/lib/python3.13/site-packages/annotated_types/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/jeepney/tests/test_bindgen.py": 8637878018232418583, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh23598.f90": 1409455010615482779, + "venv/lib/python3.13/site-packages/pandas/tests/frame/constructors/test_from_dict.py": 4937173601709369119, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_multi_thread.py": 5660352470978621226, + "venv/lib/python3.13/site-packages/urllib3/util/proxy.py": 17667887856427739069, + "frontend/src/routes/datasets/review/+page.svelte": 1567550142023887137, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/filters/__init__.py": 835924536855006596, + "venv/lib/python3.13/site-packages/click/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/ma/__init__.pyi": 1855615156913010107, + "venv/lib/python3.13/site-packages/pillow.libs/libwebpdemux-747f2b49.so.2.0.17": 7615380692384566654, + "venv/lib/python3.13/site-packages/fastapi/temp_pydantic_v1_params.py": 9436036880518047720, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh17859.f": 13562390882286135024, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/string_/test_string_arrow.py": 10008395772220468318, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/Prefix.py": 4672871351134074735, + "venv/lib/python3.13/site-packages/git/config.py": 1724894144987553201, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_validate_args_and_kwargs.py": 3381939712123764154, + "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/PIL/BufrStubImagePlugin.py": 5520941821175895889, + "venv/lib/python3.13/site-packages/pygments/styles/abap.py": 11543320440974964547, + "backend/src/core/config_manager.py": 18161236261317111528, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90": 8821492401453445757, + "backend/src/services/clean_release/stages/internal_sources_only.py": 3635582838654262092, + "backend/logs/app.log.bak": 12967408684782809237, + "backend/src/plugins/llm_analysis/service.py": 6500458189357690080, + "backend/alembic/versions/c4a3a2f74bfe_add_missing_columns_needs_review_.py": 4320606555167902916, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/memmap.pyi": 2834143910417841603, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/flatiter.pyi": 6885824496927786205, + "venv/lib/python3.13/site-packages/attr/_cmp.py": 3297594878548179300, + "venv/lib/python3.13/site-packages/smmap/__init__.py": 4557520096828426601, + "venv/lib/python3.13/site-packages/websockets/cli.py": 14049106025886056110, + "venv/lib/python3.13/site-packages/pydantic/v1/__init__.py": 1642038155370734658, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-expm1.csv": 8710594949902856122, + "venv/lib/python3.13/site-packages/pandas/tests/frame/test_query_eval.py": 17613800806748649144, + "venv/lib/python3.13/site-packages/pip/_internal/cli/status_codes.py": 9143625681947330756, + "venv/lib/python3.13/site-packages/_pytest/config/findpaths.py": 7867603756389940562, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/_typing.py": 10524021526716767489, + "venv/lib/python3.13/site-packages/fastapi/types.py": 3867821246650502267, + "venv/lib/python3.13/site-packages/cffi/cparser.py": 5246372077864988755, + "venv/lib/python3.13/site-packages/numpy/random/_philox.cpython-313-x86_64-linux-gnu.so": 9916143171057774705, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pip/_vendor/certifi/__init__.py": 2833016678144975576, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_alpha_unix.h": 2759424570606117942, + "venv/lib/python3.13/site-packages/pandas/core/arrays/_arrow_string_mixins.py": 16862663427780315543, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_iloc.py": 7586049606891014270, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm32_gcc.h": 3561524604274567339, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/openssl/binding.py": 17078280153372356796, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_abc.py": 10164280045317807365, + "venv/lib/python3.13/site-packages/pip/py.typed": 10243553515949422671, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_round_trip.py": 14684057343786032776, + "venv/lib/python3.13/site-packages/sqlalchemy/util/deprecations.py": 7020540470348910770, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/path_registry.py": 8410829659513707067, + "venv/lib/python3.13/site-packages/jaraco/classes/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/python_multipart/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/__init__.pyi": 10548370574281981402, + "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_infer_dtype.py": 1647214604678171565, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_coercion.py": 3339075591248270762, + "venv/lib/python3.13/site-packages/attrs/validators.py": 10346563361083429998, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_keys.py": 10813898277355150779, + "venv/lib/python3.13/site-packages/anyio/_core/_testing.py": 14024940365851109155, + "venv/lib/python3.13/site-packages/pydantic_settings/exceptions.py": 18300876747412267999, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_emoji_codes.py": 13901854719435716195, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/generate_umath_validation_data.cpp": 10880681943327843928, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_constructors.py": 16197656939536784142, + "venv/lib/python3.13/site-packages/greenlet/__init__.py": 3447613556981242475, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/period/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_autocorr.py": 1092316868398391792, + "venv/lib/python3.13/site-packages/urllib3/util/ssl_match_hostname.py": 7411350247004265632, + "venv/lib/python3.13/site-packages/pygments/lexers/_usd_builtins.py": 8671446144574174964, + "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_macos.py": 7028037591427052891, + "venv/lib/python3.13/site-packages/numpy/lib/user_array.pyi": 1968484998382771986, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-sinh.csv": 12358602501260667480, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_string.py": 9224234539232195189, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ndarray_misc.pyi": 16219573290116396099, + "venv/lib/python3.13/site-packages/pandas/tests/apply/conftest.py": 13798335354961261346, + "venv/lib/python3.13/site-packages/pygments/lexers/apdlexer.py": 14222752852221009085, + "venv/lib/python3.13/site-packages/pip/_vendor/idna/package_data.py": 3078502124870585867, + "venv/lib/python3.13/site-packages/numpy/_core/tests/_locales.py": 18178500267053825979, + "venv/lib/python3.13/site-packages/pandas/_testing/contexts.py": 11714205921752896137, + "venv/lib/python3.13/site-packages/pygments/lexers/_stata_builtins.py": 18053452765493556047, + "venv/lib/python3.13/site-packages/requests/certs.py": 16052880877156864882, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-exp2.csv": 10950201682596097452, + "venv/lib/python3.13/site-packages/uvicorn/__main__.py": 6086938803696646644, + "venv/lib/python3.13/site-packages/cryptography/__about__.py": 10471312538528457144, + "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/licenses/LICENSE": 14316979437290727897, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/routines/funcfortranname.pyf": 1361426175133186231, + "venv/lib/python3.13/site-packages/numpy/polynomial/__init__.pyi": 8708830448398500675, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/hmac.pyi": 9405122752084210696, + "venv/lib/python3.13/site-packages/pandas/core/computation/api.py": 17919983681396223380, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_sort_index.py": 13517883160584591966, + "venv/lib/python3.13/site-packages/httpcore/_ssl.py": 6665087294869504820, + "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pip/_internal/utils/compat.py": 1841193561752758336, + "frontend/src/lib/components/layout/sidebarNavigation.js": 12067620255981492739, + "backend/src/api/routes/dashboards/_detail_routes.py": 12522696473630508473, + "backend/src/api/routes/clean_release_v2.py": 2858037566596334612, + "venv/lib/python3.13/site-packages/numpy/lib/scimath.pyi": 18165025261847276375, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_pyf_src.py": 12351476647369971852, + "venv/lib/python3.13/site-packages/packaging/tags.py": 1999137344425005827, + "frontend/src/components/EnvSelector.svelte": 3937920133889630193, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/decl_class.py": 6328411894571735935, + "venv/lib/python3.13/site-packages/pygments/lexers/asn1.py": 15030988816882821134, + "frontend/build/_app/immutable/nodes/36.DZAutSCl.js": 9000473499840988160, + "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/rsa.py": 7852235015155694076, + "venv/lib/python3.13/site-packages/attr/converters.py": 5179615793507170642, + "venv/lib/python3.13/site-packages/passlib/utils/md4.py": 4521366665754877351, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_shift.py": 14681514853406253657, + "backend/src/scripts/test_dataset_dashboard_relations.py": 6373309008834670516, + "backend/src/api/routes/git/_helpers.py": 6888678759460652166, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/_version.py": 15336513445621042105, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_reshape.py": 5572426834735088916, + "venv/lib/python3.13/site-packages/pandas/tests/test_col.py": 14781555956509956371, + "venv/lib/python3.13/site-packages/PIL/__main__.py": 827665918723937817, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_float.py": 10455718110956856820, + "venv/lib/python3.13/site-packages/httpcore/_async/connection_pool.py": 932468678264370661, + "backend/src/models/assistant.py": 6168086159312177112, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/errors.py": 10750605030539582738, + "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/WHEEL": 13347410390513723930, + "venv/lib/python3.13/site-packages/pydantic/v1/dataclasses.py": 7833468513057242440, + "venv/lib/python3.13/site-packages/jose/backends/rsa_backend.py": 13507186353881931758, + "venv/lib/python3.13/site-packages/pygments/styles/stata_light.py": 16319330015324455277, + "venv/lib/python3.13/site-packages/pydantic_settings/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/jeepney/io/tests/test_trio.py": 7459901627473962540, + "venv/lib/python3.13/site-packages/pip/_internal/utils/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/f2py/src/fortranobject.c": 2519219289444051739, + "venv/lib/python3.13/site-packages/pandas/io/sas/sas_constants.py": 14492427939536692313, + "venv/lib/python3.13/site-packages/apscheduler/executors/base.py": 1980520974511822101, + "venv/lib/python3.13/site-packages/passlib/tests/test_context_deprecated.py": 7876919198015151018, + "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/RECORD": 9502524172853437600, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_upcast.py": 6496794053681247105, + "venv/lib/python3.13/site-packages/rapidfuzz/utils_cpp.cpython-313-x86_64-linux-gnu.so": 16145829319198889672, + "venv/lib/python3.13/site-packages/pip/_vendor/requests/sessions.py": 5400174351499383072, + "venv/lib/python3.13/site-packages/_pytest/skipping.py": 10561585274103209115, + "venv/lib/python3.13/site-packages/pydantic/_internal/_generate_schema.py": 7343380095251236503, + "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/RECORD": 7844752443022514265, + "venv/lib/python3.13/site-packages/sqlalchemy/engine/create.py": 16693261531832306870, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ndarray_shape_manipulation.py": 12598431412396627042, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_character.py": 17168707712220699738, + "venv/lib/python3.13/site-packages/PIL/ImageOps.py": 3884310863548175682, + "venv/lib/python3.13/site-packages/numpy/_core/_ufunc_config.pyi": 9291444594181042963, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/conftest.py": 8406022190801970256, + "venv/lib/python3.13/site-packages/pygments/lexers/func.py": 12257919753150082714, + "venv/lib/python3.13/site-packages/jeepney/io/tests/test_threading.py": 6656552495241857519, + "backend/src/core/__tests__/test_throttled_scheduler.py": 10949494963069000037, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_ints.py": 5616705208267050659, + "venv/lib/python3.13/site-packages/starlette/testclient.py": 16088848330558215194, + "backend/src/services/__tests__/test_resource_service.py": 14435810729789665272, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/x448.pyi": 11733449165276720901, + "backend/src/plugins/backup.py": 9697280948668596192, + "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/licenses/LICENSE": 3868190977070717994, + "venv/lib/python3.13/site-packages/pygments/lexers/haxe.py": 1915270891525929751, + "backend/src/services/notifications/__tests__/test_notification_service.py": 2377464079178202565, + "backend/tests/test_models.py": 3998442321184404421, + "venv/lib/python3.13/site-packages/numpy/core/multiarray.py": 18368443598659711836, + "venv/lib/python3.13/site-packages/_pytest/threadexception.py": 10464996327276961035, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_regression.py": 4611768764484593979, + "venv/lib/python3.13/site-packages/rsa/util.py": 13423880475585138638, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_amd64_unix.h": 16679226724722970205, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_item.py": 17619314877770917080, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_index_equal.py": 10617870815989304510, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_pop.py": 5700439923973346681, + "backend/src/services/clean_release/__tests__/test_audit_service.py": 1679130450221264383, + "venv/lib/python3.13/site-packages/pandas/core/_numba/executor.py": 2205130934861422769, + "venv/lib/python3.13/site-packages/_pytest/tracemalloc.py": 5530234062530858720, + "venv/lib/python3.13/site-packages/pandas/core/array_algos/datetimelike_accumulations.py": 14719894187829729175, + "venv/lib/python3.13/site-packages/pandas/core/ops/invalid.py": 10186546927135277579, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_constructors.py": 12118296571694122743, + "venv/lib/python3.13/site-packages/pip/_internal/models/index.py": 2839270935469791607, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_reductions.py": 17810094294132819208, + "backend/src/services/__init__.py": 15123879863527585264, + "venv/lib/python3.13/site-packages/numpy/f2py/f2py2e.pyi": 14181518821845356636, + "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/exceptions.py": 2873060848310644552, + "venv/lib/python3.13/site-packages/numpy/lib/_format_impl.pyi": 15745512451486888537, + "venv/lib/python3.13/site-packages/httpcore/_async/http11.py": 7565741048880549265, + "venv/lib/python3.13/site-packages/pandas/core/arrays/timedeltas.py": 7318851108932357510, + "venv/lib/python3.13/site-packages/pandas/core/dtypes/inference.py": 2786441797589123900, + "frontend/src/routes/storage/backups/+page.svelte": 3437582895363203695, + "backend/src/models/dataset_review_pkg/_session_models.py": 14346374229033337012, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/array_like.py": 2778905818573625118, + "venv/lib/python3.13/site-packages/websockets/uri.py": 264376168984862773, + "frontend/src/routes/admin/roles/+page.svelte": 12213033002088655108, + "venv/lib/python3.13/site-packages/authlib/jose/jwk.py": 13560749074922587626, + "backend/tests/test_task_manager.py": 1706217361689506763, + "venv/lib/python3.13/site-packages/pip/_internal/commands/uninstall.py": 11003472265011262515, + "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/RECORD": 6488682447051657004, + "venv/lib/python3.13/site-packages/greenlet/tests/test_stack_saved.py": 7767924647054186572, + "venv/lib/python3.13/site-packages/pandas/api/__init__.py": 1145864207387918302, + "venv/lib/python3.13/site-packages/numpy/lib/_polynomial_impl.py": 12771179468704314203, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/array_pad.pyi": 14755435694146003896, + "frontend/src/lib/stores/assistantChat.js": 13807808925025688939, + "frontend/src/routes/+error.svelte": 16649211425103750277, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/datasource.pyi": 16752667877866430577, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_period.py": 3419297908709788013, + "venv/lib/python3.13/site-packages/pip/_internal/index/package_finder.py": 12631116673181479779, + "venv/lib/python3.13/site-packages/referencing/tests/test_core.py": 8280983300775878144, + "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_asof.py": 18383318159051131669, + "venv/lib/python3.13/site-packages/ecdsa/curves.py": 812969717084691115, + "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/oauth2_client.py": 6742098857947604729, + "venv/lib/python3.13/site-packages/pip/_vendor/requests/cookies.py": 4997226307650350876, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/sync.py": 6189260178302531376, + "venv/lib/python3.13/site-packages/pygments/lexers/spice.py": 1376126320935115350, + "venv/lib/python3.13/site-packages/packaging/markers.py": 11602308203217831543, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_integer/foo90.f90": 3492659529812762861, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/fixed_string.f90": 8654788371538544793, + "frontend/src/routes/settings/EnvironmentsTab.svelte": 16246319452479236452, + "venv/lib/python3.13/site-packages/smmap/test/test_mman.py": 8977119225749253844, + "backend/src/models/dataset_review_pkg/__init__.py": 17789694606496652579, + "venv/lib/python3.13/site-packages/authlib/jose/drafts/__init__.py": 4770885427721822507, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/x25519.py": 18229054440703471493, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ndarray.pyi": 14369009813591437391, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/provision.py": 17812733620485633975, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/socks.py": 17581293673028078134, + "venv/lib/python3.13/site-packages/httpcore/_backends/trio.py": 8394426709857317737, + "venv/lib/python3.13/site-packages/uvicorn/importer.py": 5449629250971153435, + "venv/lib/python3.13/site-packages/pip/_internal/operations/build/metadata_editable.py": 12494407279914732338, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_cross.py": 17742712348672218852, + "venv/lib/python3.13/site-packages/pygments/lexers/_cocoa_builtins.py": 15468347167912293394, + "backend/tests/services/clean_release/test_publication_service.py": 17277940125978730159, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_crosstab.py": 6631711416347033281, + "venv/lib/python3.13/site-packages/pandas/tests/io/test_spss.py": 4865360315909532603, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_map.py": 4761668276463940924, + "venv/lib/python3.13/site-packages/passlib/tests/test_registry.py": 15377817946543064293, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_style.py": 6849613206971398029, + "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/licenses/LICENSE": 1424673738228762254, + "venv/lib/python3.13/site-packages/pandas/tests/apply/test_frame_apply_relabeling.py": 5600949862632014700, + "frontend/src/components/tasks/TaskLogPanel.svelte": 7807716346006847037, + "venv/lib/python3.13/site-packages/pandas/core/generic.py": 10174952306641057447, + "venv/lib/python3.13/site-packages/pygments/token.py": 6987328478153445584, + "venv/lib/python3.13/site-packages/pandas/core/indexers/objects.py": 409599993084996593, + "frontend/build/_app/immutable/chunks/DeED_3EO.js": 8217702195318248974, + "venv/lib/python3.13/site-packages/pydantic_settings/utils.py": 14396350455520958703, + "venv/lib/python3.13/site-packages/starlette/datastructures.py": 12097180838087229563, + "venv/lib/python3.13/site-packages/pandas/tests/apply/test_series_transform.py": 18159263102656491974, + "venv/lib/python3.13/site-packages/more_itertools/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/ma/core.pyi": 4829891173366130328, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_format.py": 5231304674283854194, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_head_tail.py": 13047338070883375426, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/status.py": 2214590120238144582, + "venv/lib/python3.13/site-packages/ecdsa/test_jacobi.py": 1249543655136186433, + "venv/lib/python3.13/site-packages/pandas/tests/io/sas/test_byteswap.py": 5090287710338893350, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/cmac.pyi": 16042272072158438261, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7009/__init__.py": 1923528231486706442, + "frontend/src/components/tools/DebugTool.svelte": 17267560034225794881, + "backend/src/scripts/__init__.py": 5400372851656282343, + "backend/src/services/clean_release/demo_data_service.py": 8795028177684641724, + "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_np_datetime.py": 18363183516409621205, + "backend/alembic_test.db": 14995253579408279707, + "venv/lib/python3.13/site-packages/pandas/api/interchange/__init__.py": 181911269762882069, + "backend/src/plugins/translate/superset_executor.py": 454191269003159946, + "venv/lib/python3.13/site-packages/pip/_internal/vcs/mercurial.py": 335201628064585213, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_timezones.py": 8042029178538467146, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/pickleable.py": 7712040860601343075, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/conftest.py": 17897502508251413988, + "venv/lib/python3.13/site-packages/passlib/utils/compat/__init__.py": 17369882236606423129, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-cbrt.csv": 8929553891827331780, + "venv/lib/python3.13/site-packages/starlette/middleware/cors.py": 11384893784314197864, + "venv/lib/python3.13/site-packages/urllib3/util/request.py": 9432067988603015849, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/packaging/_parser.py": 13394093358675095309, + "backend/src/schemas/dataset_review_pkg/_dtos.py": 13301885458265748263, + "venv/lib/python3.13/site-packages/numpy/_core/lib/libnpymath.a": 17555816778997028283, + "venv/lib/python3.13/site-packages/pyasn1/debug.py": 6305633719847955310, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_empty.py": 13006241382741353569, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arraypad.pyi": 12178766981280242620, + "venv/lib/python3.13/site-packages/passlib/tests/utils.py": 15403198680231294263, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_formats.py": 10263085276270778330, + "venv/lib/python3.13/site-packages/packaging/_musllinux.py": 2568338440457080365, + "venv/lib/python3.13/site-packages/numpy/polynomial/hermite.py": 6617116180936986481, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_value_counts.py": 5534713464063604301, + "venv/lib/python3.13/site-packages/pandas/tests/dtypes/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/series/test_missing.py": 3991199131191840903, + "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py2-np0-objarr.npy": 1615546603475261360, + "venv/lib/python3.13/site-packages/pygments/lexers/srcinfo.py": 16466766917840327610, + "venv/lib/python3.13/site-packages/PIL/ImageTk.py": 17063969714816564357, + "backend/src/plugins/translate/__tests__/test_sql_generator.py": 4467071942040481147, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_function_base.py": 15241999259666702619, + "venv/lib/python3.13/site-packages/passlib/tests/test_utils_md4.py": 15270721044910698449, + "venv/lib/python3.13/site-packages/pandas/__init__.py": 793698514004377486, + "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/__init__.py": 3619091571279924576, + "venv/lib/python3.13/site-packages/numpy/linalg/_linalg.py": 9654828595008925976, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_compound.f90": 15012692484070385863, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/conversion.pyi": 16976386782787920450, + "backend/src/scripts/clean_release_tui.py": 7514485779948079886, + "backend/tests/core/migration/test_dry_run_orchestrator.py": 5158126098685923841, + "venv/lib/python3.13/site-packages/pip/_internal/metadata/importlib/__init__.py": 10834852742917144496, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_combine_first.py": 11425059090050867171, + "venv/lib/python3.13/site-packages/numpy/_typing/_extended_precision.py": 4201820494689784136, + "venv/lib/python3.13/site-packages/h11/_writers.py": 8585823094975171480, + "venv/lib/python3.13/site-packages/pandas/tests/frame/constructors/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/data_stmts.f90": 6123192245816905092, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-tan.csv": 6233924374281534211, + "venv/lib/python3.13/site-packages/numpy/_core/records.py": 11414828908088050950, + "venv/lib/python3.13/site-packages/authlib/integrations/sqla_oauth2/client_mixin.py": 17980753662107479779, + "venv/lib/python3.13/site-packages/pip/_internal/distributions/__init__.py": 1343779312297539596, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/columns.py": 8488246354818721406, + "venv/lib/python3.13/site-packages/pillow.libs/libtiff-295fd75c.so.6.2.0": 17866578820357536656, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_indexing.py": 14552860427542050771, + "venv/lib/python3.13/site-packages/apscheduler/schedulers/blocking.py": 3483388533957772681, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/pager.py": 18072372651585577904, + "venv/lib/python3.13/site-packages/pandas/tests/extension/uuid/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/io/test_s3.py": 17425535047477778484, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/datetimes/test_constructors.py": 3440572832185940666, + "venv/lib/python3.13/site-packages/pandas/core/reshape/reshape.py": 5387892304726762127, + "venv/lib/python3.13/site-packages/authlib/common/security.py": 2291133227104016684, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/scoping.py": 18223258186431020473, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/__init__.py": 16146480198665866916, + "venv/lib/python3.13/site-packages/pandas/io/formats/console.py": 10370334487585281127, + "venv/lib/python3.13/site-packages/PIL/BlpImagePlugin.py": 7209218638257731375, + "venv/lib/python3.13/site-packages/pandas/tests/frame/constructors/test_from_records.py": 12217508428903265797, + "venv/lib/python3.13/site-packages/pandas/tests/io/json/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/rapidfuzz/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/rapidfuzz/fuzz.pyi": 7410507092040239447, + "venv/lib/python3.13/site-packages/numpy/testing/overrides.pyi": 17408923209056015964, + "venv/lib/python3.13/site-packages/authlib/jose/errors.py": 15231759002942436632, + "venv/lib/python3.13/site-packages/numpy/f2py/_backends/meson.build.template": 9935732744553086652, + "venv/lib/python3.13/site-packages/pandas/core/ops/array_ops.py": 10061020479033421596, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/traceback.py": 2535227583726271746, + "venv/lib/python3.13/site-packages/PIL/Image.py": 13615925856053031482, + "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/click/shell_completion.py": 5858110451169927373, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/literal.py": 5641382379370828704, + "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/WHEEL": 2823347510103459191, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_quantile.py": 11966156706220948315, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/lib_polynomial.pyi": 4266795948450921502, + "venv/lib/python3.13/site-packages/pip/_internal/locations/_distutils.py": 13559457590971821771, + "venv/lib/python3.13/site-packages/ecdsa/_compat.py": 13034064768731879065, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/pretty.py": 2448541115957861214, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/__init__.py": 15487893533770969571, + "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/immutabledict.pyx": 11739218099400096619, + "venv/lib/python3.13/site-packages/pygments/lexers/savi.py": 95400050302239274, + "venv/lib/python3.13/site-packages/_pytest/cacheprovider.py": 5114545353355728201, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/pbkdf2.py": 3369246520501764730, + "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/WHEEL": 7454950858448014158, + "venv/lib/python3.13/site-packages/numpy/testing/tests/test_utils.py": 5291132432383518704, + "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth1/__init__.py": 13749066369790839334, + "venv/lib/python3.13/site-packages/numpy/core/_dtype_ctypes.py": 17055498803745289016, + "venv/lib/python3.13/site-packages/pandas/core/window/numba_.py": 1444123360986509769, + "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/licenses/LICENSE": 4123064337800029995, + "venv/lib/python3.13/site-packages/greenlet/tests/test_throw.py": 4119265751381210399, + "venv/lib/python3.13/site-packages/fastapi/_compat/may_v1.py": 9880083742927480960, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/clsregistry.py": 1589692649837935355, + "venv/lib/python3.13/site-packages/multipart/decoders.py": 11346752866822986212, + "venv/lib/python3.13/site-packages/pytest/__init__.py": 6137272437722350673, + "venv/lib/python3.13/site-packages/pygments/formatters/other.py": 13124903290103898118, + "venv/lib/python3.13/site-packages/pygments/styles/borland.py": 17570558758932580659, + "frontend/src/lib/stores/__tests__/mocks/stores.js": 14098417748659067309, + "frontend/build/_app/immutable/chunks/hPO6SNG0.js": 8027434811274919386, + "frontend/build/_app/immutable/chunks/GYN4TzDb.js": 14558718419034086057, + "backend/src/schemas/__tests__/test_settings_and_health_schemas.py": 13526616847756581689, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/test_aggregate.py": 15038915958422670700, + "backend/src/core/utils/superset_context_extractor/_base.py": 15730081123519745401, + "backend/src/api/routes/translate/_run_routes.py": 6617818713940695689, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_interpolate.py": 7354685880215444946, + "venv/lib/python3.13/site-packages/jeepney/bindgen.py": 7094585345946943534, + "venv/lib/python3.13/site-packages/git/types.py": 13960696584646279283, + "frontend/build/_app/immutable/chunks/DsnmJJEf.js": 17416107759626312632, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_add_prefix_suffix.py": 4815518357936092237, + "backend/src/models/auth.py": 14495240302739907540, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/scrypt.py": 15294662527620994511, + "venv/lib/python3.13/site-packages/pandas/tests/base/test_fillna.py": 9297637486401098611, + "venv/lib/python3.13/site-packages/pygments/lexers/sgf.py": 6802546617450210439, + "venv/lib/python3.13/site-packages/pip/_internal/commands/configuration.py": 1608697090566485893, + "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/WHEEL": 7314207500206292683, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_api.py": 13739775047493489785, + "venv/lib/python3.13/site-packages/pandas/tests/extension/test_common.py": 9446944526144164255, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_constructors.py": 2786493777737472376, + "venv/lib/python3.13/site-packages/numpy/testing/print_coercion_tables.py": 11758491058846790938, + "venv/lib/python3.13/site-packages/pandas/core/internals/ops.py": 4740509262379451243, + "venv/lib/python3.13/site-packages/pandas/tests/extension/base/methods.py": 8059372834301557565, + "venv/lib/python3.13/site-packages/pandas/tests/extension/decimal/__init__.py": 4761936067832638585, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/style.py": 12654125988995362593, + "venv/lib/python3.13/site-packages/pandas/tests/strings/test_api.py": 10514120091521589282, + "venv/lib/python3.13/site-packages/iniconfig/_parse.py": 11418441008427032090, + "venv/lib/python3.13/site-packages/pandas/tests/generic/test_label_or_level_utils.py": 3423644585913150841, + "venv/lib/python3.13/site-packages/greenlet/greenlet_thread_support.hpp": 7773996382104849037, + "venv/lib/python3.13/site-packages/pandas/tests/strings/__init__.py": 5060190599837877599, + "venv/lib/python3.13/site-packages/uvicorn/supervisors/__init__.py": 15971002342788501945, + "venv/lib/python3.13/site-packages/websockets/legacy/framing.py": 12759022769700230409, + "venv/lib/python3.13/site-packages/pandas/tests/series/test_logical_ops.py": 4438104524064299182, + "venv/lib/python3.13/site-packages/numpy/_core/cversions.py": 9724467539503410469, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_console.py": 11657469008721907972, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/datetimes/test_reductions.py": 1713831062142840146, + "venv/lib/python3.13/site-packages/pygments/modeline.py": 6194365452131561478, + "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pygments/lexers/varnish.py": 3608370156692616959, + "venv/lib/python3.13/site-packages/gitdb/db/base.py": 3375449584942578385, + "venv/lib/python3.13/site-packages/pygments/lexers/macaulay2.py": 8022891778577314212, + "frontend/src/services/taskService.js": 11368052191249479533, + "backend/src/api/routes/translate/_preview_routes.py": 16234500901707822839, + "backend/src/models/connection.py": 7467905739729526898, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_arithmetic.py": 11620920548943067949, + "frontend/src/lib/stores/__tests__/test_sidebar.js": 113566022614194798, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_misc.py": 16393451200513733144, + "backend/src/services/dataset_review/repositories/repository_pkg/_mutations.py": 11718998093543631478, + "venv/lib/python3.13/site-packages/typing_inspection/typing_objects.py": 16856718240972376883, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/test_nat.py": 7400568652984772972, + "venv/lib/python3.13/site-packages/pydantic/config.py": 1450073446492183677, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/jwt_bearer.py": 6973859422068490274, + "venv/lib/python3.13/site-packages/_pytest/config/__init__.py": 12787579251203510616, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/fields.py": 10090313990429695520, + "venv/lib/python3.13/site-packages/pandas/core/arrays/_utils.py": 11574890848475750509, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/util.py": 9373891872370603585, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_julian_date.py": 850085757774959003, + "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/cli.py": 6382193953727339271, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_comment.py": 5603075924832933306, + "venv/lib/python3.13/site-packages/PIL/features.py": 3481835375516797487, + "venv/lib/python3.13/site-packages/numpy/f2py/use_rules.pyi": 18395688193449688360, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_ufunc.py": 3326502989311831856, + "frontend/build/_app/immutable/entry/start.Q6F0ayD4.js": 9740583146990910165, + "venv/lib/python3.13/site-packages/uvicorn/server.py": 15714008348292243019, + "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/WHEEL": 17410883677306885019, + "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/licenses/LICENSE": 6653202620765194772, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_truncate.py": 6478126371906156409, + "venv/lib/python3.13/site-packages/itsdangerous/exc.py": 11181421963755661477, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/syntax.py": 18070449217682341495, + "venv/lib/python3.13/site-packages/pydantic/plugin/_loader.py": 792663962985957671, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame_groupby.py": 12709199432838648700, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_pickle.py": 6232650893735715362, + "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/WHEEL": 16097436423493754389, + "venv/lib/python3.13/site-packages/pandas/io/excel/_pyxlsb.py": 10035587889954731645, + "venv/lib/python3.13/site-packages/git/refs/log.py": 5175801243332619268, + "venv/lib/python3.13/site-packages/pygments/lexers/numbair.py": 17382646010399794697, + "venv/lib/python3.13/site-packages/git/util.py": 7424113599506269603, + "frontend/src/routes/migration/mappings/+page.svelte": 4566398049366943407, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_add_prefix_suffix.py": 8367793476246001244, + "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/INSTALLER": 17282701611721059870, + "backend/src/plugins/llm_analysis/scheduler.py": 14673660738877638091, + "venv/lib/python3.13/site-packages/pandas/tests/extension/list/array.py": 8065856342131357421, + "venv/lib/python3.13/site-packages/starlette/middleware/errors.py": 1337979724602864440, + "venv/lib/python3.13/site-packages/numpy/_configtool.py": 2946953194004101078, + "backend/src/services/dataset_review/repositories/__tests__/test_session_repository.py": 18317443814450756666, + "venv/lib/python3.13/site-packages/numpy/f2py/diagnose.pyi": 8607205990821121708, + "venv/lib/python3.13/site-packages/pandas/tests/extension/test_categorical.py": 1329115818264527103, + "venv/lib/python3.13/site-packages/pygments/lexers/minecraft.py": 10133579583270214110, + "backend/src/api/routes/dashboards/_router.py": 8641007051243802224, + "venv/lib/python3.13/site-packages/jeepney/io/__init__.py": 2568357146184259175, + "venv/lib/python3.13/site-packages/pygments/formatters/groff.py": 6480830447984073574, + "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/keywrap.py": 10424037418528425800, + "venv/lib/python3.13/site-packages/pip/_internal/utils/hashes.py": 17310331665429541812, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_series.py": 16418555817529711079, + "venv/lib/python3.13/site-packages/pandas/tests/window/moments/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/multipart/exceptions.py": 8580522204565816132, + "venv/lib/python3.13/site-packages/pygments/lexers/floscript.py": 944042220740663491, + "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/licenses/LICENSE": 6808958893921859106, + "venv/lib/python3.13/site-packages/pip/_vendor/requests/help.py": 3124654001287175629, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/pkcs7.py": 9623344347519683527, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_html.py": 7732330576029516854, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/markup.py": 5413800947725916538, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_multithreading.py": 12547048606098186681, + "venv/lib/python3.13/site-packages/pandas/core/computation/align.py": 13027916530558901817, + "venv/lib/python3.13/site-packages/authlib/integrations/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_subclass.py": 10949229764696473939, + "frontend/src/routes/migration/+page.svelte": 7821836225621176583, + "venv/lib/python3.13/site-packages/pandas/tests/window/test_rolling_quantile.py": 4225791949463893856, + "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/WHEEL": 2357997949040430835, + "venv/lib/python3.13/site-packages/ecdsa/ellipticcurve.py": 15624510849346629163, + "venv/lib/python3.13/site-packages/itsdangerous/serializer.py": 14271229091461164933, + "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/RECORD": 11788532857617688351, + "venv/lib/python3.13/site-packages/pygments/lexers/modula2.py": 6575895980250662093, + "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/METADATA": 6502714564886871819, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/hashes.pyi": 7385072545198817771, + "frontend/src/lib/stores/__tests__/mocks/navigation.js": 10782992736745205981, + "frontend/src/lib/components/reports/__tests__/reports_page.integration.test.js": 16463062768004950066, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_unsupported.py": 9115440166074553860, + "frontend/build/_app/immutable/chunks/BwABSOzi.js": 12485550378293032886, + "venv/lib/python3.13/site-packages/pandas/core/sparse/api.py": 9094651265692218821, + "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/METADATA": 12295263493152296681, + "venv/lib/python3.13/site-packages/apscheduler/jobstores/redis.py": 11313520438600819390, + "venv/lib/python3.13/site-packages/pyasn1/compat/integer.py": 7365270971777550573, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/common/gh19161.f90": 7691871466158049079, + "venv/lib/python3.13/site-packages/urllib3/http2/__init__.py": 62108352209996836, + "venv/lib/python3.13/site-packages/starlette/types.py": 6372850128669191435, + "venv/lib/python3.13/site-packages/httpx/_types.py": 12461152436147308761, + "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/METADATA": 4954909612926293404, + "venv/lib/python3.13/site-packages/apscheduler/triggers/cron/__init__.py": 14268033439436797364, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/proxy.py": 13008557041076030198, + "venv/lib/python3.13/site-packages/pydantic/v1/annotated_types.py": 12925825196690299531, + "venv/lib/python3.13/site-packages/pandas/tests/window/test_rolling_functions.py": 2255133375699086300, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/dtypes.pyi": 15114028503984522176, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_index.py": 1551768441102117466, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/numpy_/test_indexing.py": 13703573544185051910, + "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/passlib/crypto/scrypt/_gen_files.py": 11149423183253618378, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/utils.py": 7707707044867513457, + "venv/lib/python3.13/site-packages/pygments/styles/emacs.py": 4540417536507245024, + "frontend/src/lib/components/layout/TaskDrawer.svelte": 6654829127438406248, + "frontend/build/_app/immutable/chunks/B-mQ6-tM.js": 4944461039645576568, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_align.py": 6050248183327934780, + "venv/lib/python3.13/site-packages/pip/_internal/cache.py": 210214424535803946, + "venv/lib/python3.13/site-packages/pyasn1/type/error.py": 1479878696626082697, + "venv/lib/python3.13/site-packages/pandas/api/executors/__init__.py": 16954693181142010028, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_dropna.py": 17272771246760486947, + "backend/logs/app.log.5": 4675888931719915527, + "venv/lib/python3.13/site-packages/pillow.libs/libwebp-d8b9687f.so.7.2.0": 116215608212382352, + "venv/lib/python3.13/site-packages/pandas/core/indexes/base.py": 496956059910401121, + "venv/lib/python3.13/site-packages/httpcore/_async/http2.py": 16350817785499681224, + "venv/lib/python3.13/site-packages/numpy/testing/_private/utils.pyi": 17639497083041129225, + "venv/lib/python3.13/site-packages/greenlet/platform/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_cisco.py": 1786475632318043669, + "venv/lib/python3.13/site-packages/jsonschema/_legacy_keywords.py": 16481666133229715822, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/arrayterator.py": 3076316311545674897, + "venv/lib/python3.13/site-packages/websockets/http11.py": 11022534176398053082, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/lib_version.pyi": 18093228021414910594, + "venv/lib/python3.13/site-packages/pip/_vendor/requests/__init__.py": 11009955319062089477, + "venv/lib/python3.13/site-packages/pandas/tests/extension/base/dtype.py": 5553691086633215767, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/dtype.py": 9342837412280377086, + "venv/lib/python3.13/site-packages/pip/_vendor/truststore/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_index.py": 10837492069089787028, + "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_openpyxl.py": 9542840527483618681, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/array_like.pyi": 1968570015765106620, + "venv/lib/python3.13/site-packages/numpy/f2py/_backends/__init__.py": 4265012785873472600, + "venv/lib/python3.13/site-packages/sqlalchemy/util/__init__.py": 15821192733097665649, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_drop_duplicates.py": 12601598844977346213, + "venv/lib/python3.13/site-packages/pygments/lexers/fortran.py": 6859638690245583968, + "frontend/src/routes/+layout.ts": 8392799000856778740, + "frontend/build/_app/immutable/chunks/DoN5Iioi.js": 15272261932303525049, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_stride_tricks.py": 1064774375151677743, + "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/REQUESTED": 15130871412783076140, + "frontend/build/favicon.png": 16740551781088792605, + "venv/lib/python3.13/site-packages/numpy/char/__init__.py": 4428218097234308768, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/base.py": 14734745827490220667, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_formats.py": 2743326139283991615, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/einsumfunc.py": 9944042006439149561, + "backend/src/plugins/translate/__tests__/test_dictionary.py": 17973099740734727535, + "backend/src/api/routes/git/_config_routes.py": 6093940098740660772, + "venv/lib/python3.13/site-packages/pydantic/_internal/_core_metadata.py": 5704137311404303574, + "venv/lib/python3.13/site-packages/pip/_internal/vcs/bazaar.py": 5630511062945201327, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_get_level_values.py": 12490886203425393290, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_hist_method.py": 2109257663592928, + "venv/lib/python3.13/site-packages/pandas/tests/reductions/__init__.py": 16150188643076000414, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/padding.py": 7470483648602195268, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/foo.f": 6349567809926050379, + "venv/lib/python3.13/site-packages/apscheduler/triggers/calendarinterval.py": 12481650996882675949, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_dropna.py": 3168969662216766293, + "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/utils.py": 617314300548081590, + "venv/lib/python3.13/site-packages/pandas/tests/window/test_dtypes.py": 2313400030798822026, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/util.py": 2176177435997659667, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/dh.pyi": 3254633032236269842, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_sh_gcc.h": 3574353221233465215, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/aead.py": 8740476942925346444, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/chararray.pyi": 9683985931409244216, + "venv/lib/python3.13/site-packages/authlib/oidc/core/models.py": 1370998944213578392, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_equals.py": 9903250467264848187, + "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/util.py": 2866856507760047219, + "venv/lib/python3.13/site-packages/rapidfuzz/fuzz_cpp_avx2.cpython-313-x86_64-linux-gnu.so": 12574929384355254457, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_setops.py": 10550603120090683350, + "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/pydantic_settings/sources/utils.py": 8633356372647820801, + "venv/lib/python3.13/site-packages/passlib/hosts.py": 11171402820797380938, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/interval/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/requests/auth.py": 912521029864094489, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_loc.py": 17839380711970027363, + "venv/lib/python3.13/site-packages/pandas/io/parsers/arrow_parser_wrapper.py": 11745253171984606573, + "venv/lib/python3.13/site-packages/greenlet/greenlet_compiler_compat.hpp": 465436185632243991, + "venv/lib/python3.13/site-packages/starlette/staticfiles.py": 11256974306202558529, + "venv/lib/python3.13/site-packages/pandas/_libs/writers.pyi": 10494773026133244183, + "venv/lib/python3.13/site-packages/pandas/tests/frame/test_arithmetic.py": 17043958604607035425, + "venv/lib/python3.13/site-packages/pandas/core/dtypes/generic.py": 17755579497690180620, + "venv/lib/python3.13/site-packages/pydantic_core/_pydantic_core.cpython-313-x86_64-linux-gnu.so": 13917011878259810696, + "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/RECORD": 16558021503346615951, + "venv/lib/python3.13/site-packages/pyasn1/codec/native/decoder.py": 15336592439379775543, + "venv/lib/python3.13/site-packages/_pytest/recwarn.py": 15312759837838083596, + "venv/lib/python3.13/site-packages/numpy/lib/_arrayterator_impl.pyi": 2744889206277418389, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_read_fwf.py": 13684564756628524738, + "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/METADATA": 15888766579203341778, + "venv/lib/python3.13/site-packages/itsdangerous/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/git/index/fun.py": 18338379518768926372, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/Hamming_py.py": 16133454512601432815, + "venv/lib/python3.13/site-packages/pip/_internal/req/req_set.py": 534498057184394558, + "venv/lib/python3.13/site-packages/pygments/console.py": 3540660073442483692, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/openssl/__init__.py": 14571251344510763303, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/multiarray.py": 3224049574922696945, + "venv/lib/python3.13/site-packages/pygments/formatters/html.py": 1918541918263449443, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_unicode_ddl.py": 2569618488804767890, + "venv/lib/python3.13/site-packages/keyring/backends/Windows.py": 4103830951042463184, + "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/unix.py": 13808187640638677050, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh23598Warn.f90": 7589258200398878529, + "venv/lib/python3.13/site-packages/pandas/tests/extension/test_extension.py": 17245018204352082978, + "venv/lib/python3.13/site-packages/sqlalchemy/engine/_py_row.py": 918740441973901148, + "venv/lib/python3.13/site-packages/sqlalchemy/engine/url.py": 1558176735588971829, + "venv/lib/python3.13/site-packages/pygments/styles/friendly.py": 13799024964803741891, + "venv/lib/python3.13/site-packages/anyio/_core/_resources.py": 8463932838064724564, + "venv/lib/python3.13/site-packages/numpy/rec/__init__.pyi": 1782063765067823837, + "venv/lib/python3.13/site-packages/apscheduler/jobstores/rethinkdb.py": 16413299263077970925, + "venv/lib/python3.13/site-packages/pandas/core/arrays/_mixins.py": 14293848457775268010, + "venv/lib/python3.13/site-packages/pygments/lexers/berry.py": 4540479522141160472, + "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/WHEEL": 18203500019759199992, + "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_array_to_datetime.py": 3467480435568672840, + "backend/src/core/migration/dry_run_orchestrator.py": 10939333902806918334, + "venv/lib/python3.13/site-packages/passlib/handlers/misc.py": 18255658377109333797, + "venv/lib/python3.13/site-packages/greenlet/TGreenlet.hpp": 6993553444981671786, + "backend/src/services/mapping_service.py": 5976063352141712188, + "venv/lib/python3.13/site-packages/passlib/tests/test_crypto_des.py": 7198931807116651263, + "frontend/src/routes/profile/__tests__/profile-settings-state.integration.test.js": 3674649277514557450, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/stride_tricks.pyi": 8257977532799807847, + "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/common.py": 9354442374897565498, + "venv/lib/python3.13/site-packages/pandas/core/tools/timedeltas.py": 7221393731712061943, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_formats.py": 2601044064677727807, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/__init__.py": 9884041726796476720, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/__init__.py": 9106887608906281686, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-log2.csv": 13979868713429167140, + "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/passlib/tests/test_apache.py": 12515001998770565375, "venv/lib/python3.13/site-packages/pygments/styles/friendly_grayscale.py": 16840106759769837649, - "venv/lib/python3.13/site-packages/pip/_internal/utils/packaging.py": 15555781487631855604, - "venv/lib/python3.13/site-packages/pygments/lexers/jvm.py": 897669925284011089, + "frontend/src/routes/admin/settings/+page.svelte": 6706258642200752989, + "frontend/src/services/gitService.js": 7044825476968825357, + "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/authorization_server.py": 2913800420669417152, + "venv/lib/python3.13/site-packages/numpy/random/tests/data/pcg64-testset-2.csv": 5423145402839576695, + "venv/lib/python3.13/site-packages/numpy/_core/_string_helpers.pyi": 12043292763005874815, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/x963kdf.py": 14995426099932276090, + "venv/lib/python3.13/site-packages/pandas/_config/localization.py": 11197430792343731762, + "venv/lib/python3.13/site-packages/ecdsa/test_ecdsa.py": 17595025859105321562, + "venv/lib/python3.13/site-packages/authlib/integrations/starlette_client/integration.py": 3085827906490477329, + "venv/lib/python3.13/site-packages/pygments/lexers/futhark.py": 10102535873433759899, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_character.py": 850554362222586199, + "venv/lib/python3.13/site-packages/pygments/lexers/carbon.py": 6753624244809529841, + "venv/lib/python3.13/site-packages/jeepney/low_level.py": 6546206679858571608, + "backend/src/services/clean_release/compliance_orchestrator.py": 10585043190405940115, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_array_api_info.py": 16491629653122827368, + "backend/tests/test_translate_jobs.py": 16585154497956900995, + "venv/lib/python3.13/site-packages/pygments/lexers/mosel.py": 1877592344012288438, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/protocol.py": 932296179250981622, + "run_clean_tui.sh": 14305120550349644601, + "frontend/build/_app/immutable/chunks/BoPlBqXU.js": 15621955836226522600, + "venv/lib/python3.13/site-packages/pandas/tests/window/moments/test_moments_consistency_rolling.py": 11118160360072677569, + "venv/lib/python3.13/site-packages/pillow.libs/libwebpmux-7f11e5ce.so.3.1.2": 13105940093474848953, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/aiomysql.py": 12999962380333482189, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_setops.py": 17350958906336246626, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/config.py": 10707678943298497676, + "venv/lib/python3.13/site-packages/numpy/_core/_struct_ufunc_tests.cpython-313-x86_64-linux-gnu.so": 13269324887178340397, + "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pandas/core/indexers/utils.py": 5861072573716897447, + "frontend/svelte.config.js": 8473636210766821560, + "venv/lib/python3.13/site-packages/numpy/version.pyi": 5075382895829889457, + "frontend/src/lib/components/translate/ScheduleConfig.svelte": 17692328825363231497, + "venv/lib/python3.13/site-packages/pandas/tests/window/test_ewm.py": 13789842684407148830, + "venv/lib/python3.13/site-packages/attr/_typing_compat.pyi": 2823472697859409877, + "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/METADATA": 15970460108484113417, + "frontend/src/lib/stores/activity.js": 14023344642294459631, + "venv/lib/python3.13/site-packages/numpy/_core/_type_aliases.py": 1644743742545329282, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_chained_assignment_deprecation.py": 7694137945143129474, + "venv/lib/python3.13/site-packages/requests/sessions.py": 6936640856092320928, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/pysqlite.py": 16550134594771291234, + "backend/alembic/versions/2a7b8c9d0e1f_add_target_languages_to_translation_jobs.py": 7201017059554918882, + "venv/lib/python3.13/site-packages/passlib/handlers/des_crypt.py": 15304795681178011265, + "venv/lib/python3.13/site-packages/greenlet/PyGreenlet.cpp": 7360124705400993707, + "venv/lib/python3.13/site-packages/keyring/backend.py": 14185808762437650951, + "venv/lib/python3.13/site-packages/referencing/tests/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_categorical.py": 10863578845754547294, + "venv/lib/python3.13/site-packages/pip/_internal/utils/appdirs.py": 539688259643447487, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_unicode.py": 1103608932321322989, + "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/METADATA": 2604612822968175379, + "backend/src/core/utils/superset_context_extractor/_recovery.py": 13298493527065532076, + "venv/lib/python3.13/site-packages/pandas/core/window/__init__.py": 15180240812077877933, + "backend/src/services/dataset_review/orchestrator_pkg/_commands.py": 15474996500928063708, + "venv/lib/python3.13/site-packages/jeepney/tests/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_wrap.py": 17083394123203662880, + "venv/lib/python3.13/site-packages/anyio/__init__.py": 12752386096259972231, + "venv/lib/python3.13/site-packages/pip/_vendor/tomli/_types.py": 7175518113263603341, + "venv/lib/python3.13/site-packages/numpy/_core/lib/npy-pkg-config/mlib.ini": 16151597765994697599, + "venv/lib/python3.13/site-packages/pandas/core/methods/to_dict.py": 4653628436393663485, + "venv/lib/python3.13/site-packages/rapidfuzz/process_cpp_impl.cpython-313-x86_64-linux-gnu.so": 11767771662042404251, + "backend/src/api/routes/translate/_correction_routes.py": 12437040676784563126, + "frontend/src/routes/storage/repos/+page.svelte": 3849368960648953479, + "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/android.py": 8607703347015852195, + "venv/lib/python3.13/site-packages/referencing/_core.py": 14744795336121513230, + "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py2-objarr.npz": 9481735723557962988, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_resolution.py": 6076761538303762297, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_describe.py": 14493300276133670380, + "frontend/src/lib/i18n/index.ts": 2428391315568750665, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/layout.py": 11554376181083053156, + "venv/lib/python3.13/site-packages/numpy/lib/_utils_impl.pyi": 15767546107856827543, + "venv/lib/python3.13/site-packages/pandas/core/accessor.py": 1188716996113179524, + "venv/lib/python3.13/site-packages/PIL/GimpPaletteFile.py": 2040459799887417392, + "venv/lib/python3.13/site-packages/authlib/integrations/sqla_oauth2/__init__.py": 12911374670789466961, + "venv/lib/python3.13/site-packages/pandas/core/interchange/utils.py": 11401792151107207834, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/provision.py": 13156893203444936309, + "venv/lib/python3.13/site-packages/pygments/lexers/bare.py": 18266858932333619451, + "venv/lib/python3.13/site-packages/uvicorn/protocols/http/auto.py": 15947958974558543657, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/serializer.py": 8708767945343850816, + "venv/lib/python3.13/site-packages/pandas/_testing/__init__.py": 10127496080404419481, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_timer.py": 8196003526646080498, + "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_windows.py": 9171347078900057357, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_rename.py": 16148017223289654683, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_size.py": 14032390806503440750, + "venv/lib/python3.13/site-packages/pandas/tests/tools/test_to_timedelta.py": 364160935264757405, + "venv/lib/python3.13/site-packages/numpy/typing/__init__.py": 3608665862759745048, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/gitdb/db/mem.py": 15823812455996199993, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py": 15060063324909302240, + "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/METADATA": 15658158392301945427, + "venv/lib/python3.13/site-packages/pip/_internal/operations/build/metadata_legacy.py": 9226692984248279094, + "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/RECORD": 10264342250058307301, + "venv/lib/python3.13/site-packages/cryptography/x509/oid.py": 13909847799728532602, + "venv/lib/python3.13/site-packages/numpy/lib/_iotools.py": 10522826373041592861, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/warnings_and_errors.pyi": 3151453262733619734, + "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/passlib/crypto/scrypt/__init__.py": 4390908730288159455, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/parameters.py": 5104015814292812973, + "venv/lib/python3.13/site-packages/pandas/core/groupby/grouper.py": 18110568057754450953, + "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/WHEEL": 9100692507274722091, + "venv/lib/python3.13/site-packages/pandas/core/reshape/encoding.py": 12702053687535473061, + "venv/lib/python3.13/site-packages/pygments/lexers/nit.py": 18262907536841158657, + "venv/lib/python3.13/site-packages/pygments/unistring.py": 18037463865539157041, + "venv/lib/python3.13/site-packages/pandas/io/formats/templates/typst.tpl": 5055419073126793137, + "frontend/build/_app/immutable/nodes/17.D5QBfMD6.js": 12662533799528506371, + "backend/src/scripts/init_auth_db.py": 7729644769215024318, + "backend/src/core/task_manager/__tests__/test_context.py": 4211690952139950648, + "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/WHEEL": 9788895026336324100, + "venv/lib/python3.13/site-packages/numpy/tests/test_scripts.py": 5790352482583964348, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_cov_corr.py": 13652339565475304679, + "venv/lib/python3.13/site-packages/apscheduler/schedulers/__init__.py": 16211693040174992594, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_util.py": 16908393806993809474, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_multi.py": 4612816468258071810, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_c_parser_only.py": 3038797485572319804, + "frontend/src/lib/ui/LanguageSwitcher.svelte": 3899734183369041614, + "backend/src/services/notifications/service.py": 7032100258837946310, + "backend/src/services/clean_release/report_builder.py": 6953311294119437848, + "venv/lib/python3.13/site-packages/pip/_internal/vcs/git.py": 17060377178521307324, + "venv/lib/python3.13/site-packages/numpy/lib/_histograms_impl.py": 13446184230476677032, + "backend/src/plugins/translate/prompt_builder.py": 9619706108488955349, + "venv/lib/python3.13/site-packages/sqlalchemy/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/_libs/arrays.pyi": 12629806207276576877, + "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_normalize.py": 3203921571999101793, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_timezones.py": 15157687716502574038, + "venv/lib/python3.13/site-packages/cryptography/hazmat/asn1/asn1.py": 8801155055979135092, + "venv/lib/python3.13/site-packages/pip/_vendor/requests/adapters.py": 2224938661429637508, + "venv/lib/python3.13/site-packages/greenlet/TGreenlet.cpp": 4121171004360760212, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/__init__.py": 237070345717942041, + "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/RECORD": 3288669175908898843, + "venv/lib/python3.13/site-packages/sqlalchemy/event/api.py": 987321343916500337, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/expression.py": 1248029135284283479, + "venv/lib/python3.13/site-packages/numpy/core/_multiarray_umath.py": 10973016138581934035, + "venv/lib/python3.13/site-packages/numpy/conftest.py": 8971879716683736515, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/__multiarray_api.c": 9134176670140958459, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/_initialize_py.py": 6518425342376455821, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh25211.pyf": 10179237442840865225, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_sort_index.py": 14187428934500390688, + "venv/lib/python3.13/site-packages/ecdsa/_rwlock.py": 7971972922423146201, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_limited_api.py": 15788485008764560845, + "venv/lib/python3.13/site-packages/passlib/tests/test_pwd.py": 10089138951415591061, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_mixins.py": 12351373879926460719, + "venv/lib/python3.13/site-packages/numpy/_core/strings.pyi": 1981676808027146409, + "venv/lib/python3.13/site-packages/yaml/tokens.py": 2279161238859232338, + "venv/lib/python3.13/site-packages/dateutil/tz/_common.py": 9009072600471223066, + "venv/lib/python3.13/site-packages/pygments/lexers/sieve.py": 15757825442941567629, + "backend/src/core/encryption_key.py": 10697135200011385036, + "venv/lib/python3.13/site-packages/pip/_vendor/truststore/__init__.py": 1948986914452928735, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/__init__.py": 14571251344510763303, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_drop.py": 17940792593116540139, + "backend/src/core/__tests__/test_superset_profile_lookup.py": 15590077829286810714, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_rowcount.py": 6682800584070485197, + "backend/src/services/reports/__tests__/test_report_service.py": 6045116534626984913, + "backend/src/models/translate.py": 1714500577896249923, + "venv/lib/python3.13/site-packages/cryptography/x509/__init__.py": 4066756344049307453, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/cmac.py": 12011944740750051829, + "venv/lib/python3.13/site-packages/numpy/_core/function_base.py": 5676611841071163854, + "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_json_table_schema_ext_dtype.py": 13021437050542691118, + "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/response.py": 9594165377270752433, + "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/validation": 5398883285871046811, + "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/_cmd.py": 14954780419054588164, + "venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/WHEEL": 2357997949040430835, + "venv/lib/python3.13/site-packages/pygments/lexers/_julia_builtins.py": 8846111188795315103, + "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/numpy/lib/array_utils.pyi": 14646405559193539455, + "backend/src/plugins/git/llm_extension.py": 9347391649685791102, + "backend/alembic/versions/aa1b2c3d4e5f_drop_deprecated_translate_columns.py": 15433357059529111004, + "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py": 6109201994963211857, + "venv/lib/python3.13/site-packages/pydantic/mypy.py": 10034028441785588819, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_period_range.py": 9598872514187524706, + "venv/lib/python3.13/site-packages/pandas/io/parsers/python_parser.py": 7297059565749331767, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_common.py": 3559416690270529904, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_arraypad.py": 4907193085512342162, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_searchsorted.py": 12074107109575676897, + "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/_pytest/main.py": 931018496411984909, + "backend/src/api/routes/translate/_job_routes.py": 217949482917696293, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame_legend.py": 13094583566764796297, + "venv/lib/python3.13/site-packages/more_itertools/more.py": 1631135582441184133, + "venv/lib/python3.13/site-packages/fastapi/openapi/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/traversals.py": 1188980668212022868, + "venv/lib/python3.13/site-packages/PIL/GimpGradientFile.py": 9777026720028891154, + "venv/lib/python3.13/site-packages/dateutil/tz/tz.py": 5258008267965780817, + "venv/lib/python3.13/site-packages/attrs/setters.py": 5775359015245600592, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_hashing.py": 11119284926039008503, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/dml.py": 17308908394336670576, + "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/limited_api_latest.c": 5472633890472031814, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/mod_derived_types.f90": 2556756676983488922, + "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/RECORD": 12575893084587070195, + "venv/lib/python3.13/site-packages/pandas/core/arrays/datetimes.py": 10585034798097337148, + "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/RECORD": 8104089156015954779, + "venv/lib/python3.13/site-packages/pygments/formatters/latex.py": 7514533384468139434, + "venv/lib/python3.13/site-packages/pygments/lexers/sql.py": 15566262873151658034, + "frontend/static/favicon.png": 16740551781088792605, + "frontend/src/lib/ui/Input.svelte": 8632025378593263475, + "venv/lib/python3.13/site-packages/authlib/integrations/flask_client/__init__.py": 9997757256282720103, + "venv/lib/python3.13/site-packages/fastapi/openapi/constants.py": 1111838716953068285, + "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth1/nonce.py": 18219168479887197733, + "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/__init__.py": 4752355175318979033, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_ratio.py": 940213488194452623, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/test_na_scalar.py": 13950899907067372014, + "venv/lib/python3.13/site-packages/pygments/lexers/cddl.py": 1303059539145221713, + "venv/lib/python3.13/site-packages/numpy/f2py/__version__.pyi": 9759534743796867731, + "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/WHEEL": 2357997949040430835, + "venv/lib/python3.13/site-packages/pygments/lexers/maple.py": 7402467573829618534, + "venv/lib/python3.13/site-packages/sqlalchemy/util/_collections.py": 7772437080414835462, + "venv/lib/python3.13/site-packages/numpy/testing/tests/__init__.py": 15130871412783076140, + "frontend/src/lib/ui/Select.svelte": 11354509509920497811, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/misc/extended_precision.pyi": 6541258584648209609, + "venv/lib/python3.13/site-packages/pandas/util/_decorators.py": 14780166101442507665, + "backend/src/services/dataset_review/__init__.py": 15781509495698823404, + "venv/lib/python3.13/site-packages/click/_textwrap.py": 14586282603215052310, + "backend/alembic/env.py": 12540388445794983398, + "venv/lib/python3.13/site-packages/pygments/lexers/nix.py": 15050086330545600356, + "venv/lib/python3.13/site-packages/uvicorn/_types.py": 3339389597716220585, + "venv/lib/python3.13/site-packages/greenlet/greenlet.cpp": 3281107194043468270, + "backend/src/services/__tests__/test_llm_plugin_persistence.py": 2413185961042174999, + "venv/lib/python3.13/site-packages/sqlalchemy/engine/_py_util.py": 13997184496924925110, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/Postfix.pyi": 2700568594438441246, + "frontend/src/lib/components/health/PolicyForm.svelte": 10697252862978287099, + "venv/lib/python3.13/site-packages/pandas/core/window/rolling.py": 6316477981414191778, + "venv/lib/python3.13/site-packages/pip/_internal/vcs/versioncontrol.py": 13742159245132241245, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_overlaps.py": 8287716909793575347, + "venv/lib/python3.13/site-packages/ecdsa/test_malformed_sigs.py": 2606295770491528880, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_insert.py": 6970975909565157982, + "venv/lib/python3.13/site-packages/sqlalchemy/util/queue.py": 1289234691048379395, + "venv/lib/python3.13/site-packages/tzlocal/unix.py": 995019116408448073, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/scoping.py": 17216492046645992674, + "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/licenses/LICENSE": 13479831069780783137, + "frontend/build/favicon.svg": 6451919037497541980, + "backend/src/core/auth/repository.py": 7314530014494164270, + "venv/lib/python3.13/site-packages/pandas/core/dtypes/astype.py": 9925183787411796679, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_nunique.py": 8450574751331186943, + "venv/lib/python3.13/site-packages/pandas/tests/apply/test_series_apply.py": 12349190935180702377, + "venv/lib/python3.13/site-packages/pip/_vendor/packaging/requirements.py": 11478648568700804705, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_rename_axis.py": 13193478481758930128, + "venv/lib/python3.13/site-packages/numpy/polynomial/tests/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_loop.py": 6502725909989655118, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_protocols.py": 5019018645804313814, + "backend/src/api/routes/__tests__/test_tasks_logs.py": 15585487936320145746, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_encoding.py": 6622474614967398246, + "backend/src/models/task.py": 10701108436197477339, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/transform/test_numba.py": 8250377774229977284, + "venv/lib/python3.13/site-packages/numpy/random/_philox.pyi": 7503018432880404291, + "backend/src/core/utils/dataset_mapper.py": 13413818977924738147, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_join.py": 1364886077926604427, + "venv/lib/python3.13/site-packages/anyio/to_thread.py": 12767326212338028587, + "venv/lib/python3.13/site-packages/apscheduler/events.py": 10748346950729364899, + "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_conversion.py": 12184280074522274780, + "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/METADATA": 2810323639884879396, + "frontend/src/lib/components/assistant/__tests__/assistant_chat.integration.test.js": 13047006106880121194, + "venv/lib/python3.13/site-packages/sqlalchemy/event/legacy.py": 13465911776953636949, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/util.py": 955993052529739164, + "backend/src/services/git/_gitea.py": 3585029718367932699, + "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/__init__.py": 13584649922093198724, + "venv/lib/python3.13/site-packages/pygments/plugin.py": 18006138132596504101, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_filters.py": 17271344092069736999, + "backend/src/services/git_service.py": 1930048176535450912, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/hooks.py": 8580161128344266243, + "venv/lib/python3.13/site-packages/numpy/_globals.pyi": 12839879732484756979, + "venv/lib/python3.13/site-packages/pandas/core/internals/construction.py": 893951849732478990, + "venv/lib/python3.13/site-packages/PIL/_webp.cpython-313-x86_64-linux-gnu.so": 11070012119632935103, + "venv/lib/python3.13/site-packages/pygments/lexers/mips.py": 2078929831513352031, + "venv/lib/python3.13/site-packages/pandas/core/ops/docstrings.py": 3721650738518391256, + "venv/lib/python3.13/site-packages/pandas/core/internals/__init__.py": 1377108808392195313, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_arrayobject.py": 13337664596833150958, + "venv/lib/python3.13/site-packages/ecdsa/test_numbertheory.py": 2117130219401053225, + "venv/lib/python3.13/site-packages/passlib/tests/test_crypto_builtin_md4.py": 16840174243259839994, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/query.py": 3867868366067025348, + "venv/lib/python3.13/site-packages/pandas/core/groupby/numba_.py": 15997665748332235683, + "venv/lib/python3.13/site-packages/pycparser/c_generator.py": 14922277346364091122, + "venv/lib/python3.13/site-packages/pygments/lexers/boa.py": 14409319610243925864, + "frontend/build/_app/immutable/nodes/15.BKKY0MZO.js": 14681615552506811594, + "backend/src/plugins/translate/service.py": 10002583160631126287, + "venv/lib/python3.13/site-packages/pip/_internal/operations/prepare.py": 13514839972066861359, + "venv/lib/python3.13/site-packages/passlib/__init__.py": 6987142392711441525, + "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/mean_.py": 3641008929910474457, + "venv/lib/python3.13/site-packages/httpcore/_sync/http2.py": 11167798787131917524, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/unistring.py": 18037463865539157041, + "venv/lib/python3.13/site-packages/numpy/random/bit_generator.cpython-313-x86_64-linux-gnu.so": 2574035311375507054, "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/ocsp.pyi": 8666343427862784832, - "venv/lib/python3.13/site-packages/pandas/io/formats/format.py": 3364941338174434661 + "venv/lib/python3.13/site-packages/pip/_internal/metadata/_json.py": 6718137926109998531, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/assertsql.py": 4633484475514351889, + "venv/lib/python3.13/site-packages/numpy/lib/tests/data/python3.npy": 4957143805477405905, + "frontend/build/_app/immutable/chunks/CzVatF6O.js": 1337487003792124464, + "venv/lib/python3.13/site-packages/numpy/__init__.pxd": 13527602429695748857, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/parsing.pyi": 11967691665766452312, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8693/__init__.py": 11065844267208884531, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/cli/hi77.f": 10617763407280454334, + "venv/lib/python3.13/site-packages/websockets/asyncio/server.py": 885415484558949506, + "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/METADATA": 3814104793342833872, + "venv/lib/python3.13/site-packages/pip/_internal/models/__init__.py": 13482731985065116750, + "venv/lib/python3.13/site-packages/jsonschema/benchmarks/contains.py": 3098087827310439993, + "venv/lib/python3.13/site-packages/pandas/core/interchange/dataframe_protocol.py": 12857147443873820285, + "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/licenses/numpy/_core/src/umath/svml/LICENSE": 9584102918819171104, + "venv/lib/python3.13/site-packages/pygments/styles/gruvbox.py": 9489017112545247388, + "venv/lib/python3.13/site-packages/pygments/lexers/webassembly.py": 17811970490091406867, + "venv/lib/python3.13/site-packages/pandas/core/missing.py": 13332302791063948992, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_subclass.py": 11096337912872573314, + "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/testing/_private/__init__.pyi": 15130871412783076140, + "venv/lib/python3.13/site-packages/urllib3/util/timeout.py": 17922362393077965047, + "venv/lib/python3.13/site-packages/passlib/handlers/mssql.py": 2800599582708170195, + "frontend/src/lib/stores/__tests__/mocks/environment.js": 16653269108049932073, + "backend/src/models/profile.py": 18027673609437659833, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/Jaro.py": 183817263146423033, + "venv/lib/python3.13/site-packages/pygments/lexers/special.py": 4972294202790455038, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/themes.py": 6451091097727599550, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/f77comments.f": 4801926170672147659, + "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/RECORD": 15865206372525596795, + "venv/lib/python3.13/site-packages/pandas/api/internals.py": 5188134630996087511, + "venv/lib/python3.13/site-packages/anyio/abc/_eventloop.py": 2023190981288767991, + "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/METADATA": 317417773265681256, + "backend/src/api/routes/tasks.py": 4058255810929412793, + "venv/lib/python3.13/site-packages/passlib/tests/test_crypto_scrypt.py": 17378030264314664250, + "venv/lib/python3.13/site-packages/ecdsa/_sha3.py": 10353612776869489378, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7636/challenge.py": 6388445104761482746, + "venv/lib/python3.13/site-packages/jsonschema/benchmarks/json_schema_test_suite.py": 6152158310190822762, + "venv/lib/python3.13/site-packages/requests/packages.py": 7733041271118298220, + "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_period.py": 15671388508498441412, + "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_ujson.py": 12184194085993665945, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/scope.py": 4096190764836489091, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/poly1305.pyi": 14119032813912827271, + "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_polyutils.py": 675639791972685455, + "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/WHEEL": 16784970174376303810, + "venv/lib/python3.13/site-packages/gitdb/utils/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/authlib/oidc/core/__init__.py": 16029653645350087968, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/rec.pyi": 9140655366667421698, + "venv/lib/python3.13/site-packages/_pytest/_io/saferepr.py": 8025234471485188730, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arctan.csv": 4581185622290535488, + "venv/lib/python3.13/site-packages/numpy/ctypeslib/_ctypeslib.pyi": 10360538024015064036, + "venv/lib/python3.13/site-packages/pandas/tests/io/sas/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/lib_user_array.py": 8711697474193296376, + "venv/lib/python3.13/site-packages/pandas/core/api.py": 3390809109543982410, + "venv/lib/python3.13/site-packages/numpy/ma/tests/test_core.py": 12712110303898046818, + "venv/lib/python3.13/site-packages/pandas/tests/internals/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/RECORD": 17985800801793506250, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/__multiarray_api.h": 16138871162713175599, + "venv/lib/python3.13/site-packages/passlib/tests/test_ext_django_source.py": 15577951591316518967, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_counting.py": 5628494712451120258, + "venv/lib/python3.13/site-packages/urllib3/filepost.py": 3814725067598042920, + "frontend/src/components/PasswordPrompt.svelte": 14457083234480062595, + "venv/lib/python3.13/site-packages/pandas/tests/frame/test_repr.py": 16609300578827398344, + "venv/lib/python3.13/site-packages/pip/_vendor/msgpack/exceptions.py": 11303331612406662162, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7515/jws.py": 7505219131537941130, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_complex/foo77.f": 7353666717928699883, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_factorize.py": 17995673140216929494, + "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/METADATA": 3179724236887811680, + "backend/src/services/clean_release/source_isolation.py": 10193276492118254392, + "backend/tests/core/migration/test_archive_parser.py": 1909788158234142574, + "venv/lib/python3.13/site-packages/pandas/_libs/missing.cpython-313-x86_64-linux-gnu.so": 1990755879067132155, + "venv/lib/python3.13/site-packages/apscheduler/__init__.py": 8652514118183227412, + "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/RECORD": 2688648742701423549, + "frontend/src/lib/stores/__tests__/taskDrawer.test.js": 12307450726550947042, + "venv/lib/python3.13/site-packages/pandas/tests/extension/date/array.py": 18073740473413382768, + "venv/lib/python3.13/site-packages/numpy/linalg/__init__.pyi": 18409133021422984774, + "venv/lib/python3.13/site-packages/rpds/__init__.py": 5862197328247012275, + "venv/lib/python3.13/site-packages/pip/_internal/commands/lock.py": 14782882714168174465, + "venv/lib/python3.13/site-packages/numpy/_typing/_scalars.py": 17701938912160369190, + "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/RECORD": 8201759541483070364, + "venv/lib/python3.13/site-packages/pygments/lexers/prql.py": 1159462562014166646, + "venv/bin/activate.fish": 5275961582873298085, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pygments/lexers/devicetree.py": 9820277168995231927, + "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/RECORD": 3617343778671172258, + "venv/lib/python3.13/site-packages/passlib/handlers/pbkdf2.py": 16686685453577026643, + "frontend/build/_app/immutable/nodes/18.DnUw7pIE.js": 5294776392406439782, + "venv/lib/python3.13/site-packages/PIL/ImageQt.py": 6607270889359138659, + "venv/lib/python3.13/site-packages/secretstorage/__init__.py": 4535964275649588672, + "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/METADATA": 3390257212824996989, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_describe.py": 11923715539897559626, + "venv/lib/python3.13/site-packages/pyasn1/codec/cer/__init__.py": 15728752901274520502, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_custom_dtypes.py": 12322100282959605055, + "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/WHEEL": 2357997949040430835, + "venv/lib/python3.13/site-packages/pandas/tests/extension/base/dim2.py": 5767600151459095125, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/rsa_key.py": 7092106298733667895, + "venv/lib/python3.13/site-packages/numpy/_utils/_convertions.pyi": 362674842164060822, + "venv/lib/python3.13/site-packages/greenlet/PyGreenlet.hpp": 6366432579621298231, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc_unix.h": 9608771997528633681, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/profiling.py": 16030397164203895281, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh23879.f90": 13174951794239860144, + "venv/lib/python3.13/site-packages/pip/_internal/network/cache.py": 10606522397693824641, + "venv/lib/python3.13/site-packages/git/exc.py": 14278238357119816365, + "venv/lib/python3.13/site-packages/greenlet/TThreadState.hpp": 15599148954148720463, + "venv/lib/python3.13/site-packages/pip/_internal/utils/datetime.py": 6816292030061301011, + "venv/lib/python3.13/site-packages/pandas/io/excel/_odswriter.py": 17220892094904423676, + "venv/lib/python3.13/site-packages/dateutil/parser/__init__.py": 11377431154251655738, + "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_defmatrix.py": 2982572083770917411, + "venv/lib/python3.13/site-packages/charset_normalizer/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pygments/lexers/webidl.py": 8097260111959278117, + "venv/lib/python3.13/site-packages/jeepney/io/tests/test_blocking.py": 6312017389529916004, + "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_fields.py": 16222559851336781264, + "venv/lib/python3.13/site-packages/pygments/lexers/ptx.py": 4855144232064607995, + "venv/lib/python3.13/site-packages/numpy/_typing/_nbit.py": 15498810174380798405, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/linalg.pyi": 269481015135399748, + "venv/lib/python3.13/site-packages/authlib/jose/__init__.py": 317573635113539563, + "backend/_convert_defs.py": 208535643309836247, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_m68k_gcc.h": 6580173800099450404, + "venv/lib/python3.13/site-packages/pygments/styles/pastie.py": 15784474766258831882, + "backend/src/api/routes/dataset_review.py": 3689614039699023362, + "backend/src/services/__tests__/test_llm_prompt_templates.py": 17912427710321938757, + "backend/src/services/health_service.py": 7295235621662158359, + "venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/WHEEL": 5179340427739743287, + "venv/lib/python3.13/site-packages/pygments/lexers/scripting.py": 4167168074165473790, + "backend/tests/test_translate_corrections.py": 1228642484417924184, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/string_/test_concat.py": 3788461606817482165, + "venv/lib/python3.13/site-packages/git/objects/base.py": 11498407361286170399, + "venv/lib/python3.13/site-packages/pandas/io/excel/_openpyxl.py": 6676451564208867775, + "venv/lib/python3.13/site-packages/numpy/random/tests/test_generator_mt19937.py": 7299586490442539723, + "venv/lib/python3.13/site-packages/pip/_internal/utils/wheel.py": 450504439085405418, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c": 17333399794446198412, + "venv/lib/python3.13/site-packages/click-8.3.1.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/licenses/LICENSE.PSF": 13208428090829817329, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_replace.py": 18039668944453454689, + "venv/lib/python3.13/site-packages/numpy/_distributor_init.pyi": 1308368231471324581, + "venv/lib/python3.13/site-packages/numpy/lib/_iotools.pyi": 12873243737872788349, + "venv/lib/python3.13/site-packages/PIL/_imagingft.cpython-313-x86_64-linux-gnu.so": 11054435406031360190, + "venv/lib/python3.13/site-packages/passlib/pwd.py": 14727089240749133060, + "frontend/src/components/TaskRunner.svelte": 18014857434320509117, + "venv/lib/python3.13/site-packages/numpy/lib/_format_impl.py": 1809069379864985298, + "venv/lib/python3.13/site-packages/passlib/apps.py": 4633269405597895766, + "venv/lib/python3.13/site-packages/fastapi/exception_handlers.py": 9907950997607808699, + "venv/lib/python3.13/site-packages/pygments/lexers/verification.py": 16645885125604874183, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/__init__.py": 11157967642611612522, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh23533.f": 12558972205518833024, + "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/licenses/LICENSE.APACHE": 8359973023624924624, + "venv/lib/python3.13/site-packages/numpy/_typing/_ufunc.pyi": 6286629088867436848, + "venv/lib/python3.13/site-packages/numpy/random/_common.pyi": 5094115692952609118, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_monotonic.py": 11817523305776951162, + "venv/lib/python3.13/site-packages/pandas/core/construction.py": 10646956189518908985, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/frequencies/test_frequencies.py": 14039315221824123200, + "venv/lib/python3.13/site-packages/PIL/WebPImagePlugin.py": 5378349556563611996, + "venv/lib/python3.13/site-packages/pandas/tests/util/conftest.py": 11143177766735481660, + "venv/lib/python3.13/site-packages/pygments/lexers/hexdump.py": 10665271113239513484, + "venv/lib/python3.13/site-packages/packaging/requirements.py": 2896326326372719999, + "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/numeric.pyi": 17005748821769179511, + "venv/lib/python3.13/site-packages/numpy/_core/_exceptions.py": 5570375156851166818, + "venv/lib/python3.13/site-packages/jeepney/io/trio.py": 11859775321483330469, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_reindex.py": 15680924058960901067, + "venv/lib/python3.13/site-packages/ecdsa/test_ecdh.py": 3338834550392548171, + "venv/lib/python3.13/site-packages/numpy/f2py/_backends/__init__.pyi": 16164841755339571545, + "venv/lib/python3.13/site-packages/pandas/tests/strings/test_case_justify.py": 8204537837649550062, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/provision.py": 9472538482404392519, + "venv/lib/python3.13/site-packages/PIL/_util.py": 17116054813914373606, + "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/WHEEL": 18203500019759199992, + "venv/lib/python3.13/site-packages/referencing/_attrs.pyi": 10030665705880994025, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ufuncs.pyi": 14995898537484305307, + "venv/lib/python3.13/site-packages/pygments/lexers/make.py": 5345282370426217663, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_cpu_dispatcher.py": 2063037275809439611, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_cut.py": 7800833253841657380, + "venv/lib/python3.13/site-packages/anyio/streams/file.py": 15232345967545920863, + "venv/lib/python3.13/site-packages/anyio/streams/memory.py": 11762722143503428823, + "venv/lib/python3.13/site-packages/pandas/_libs/testing.pyi": 16691791330088523786, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/provision.py": 8707620698060818654, + "frontend/build/_app/immutable/chunks/DmuwojIM.js": 5778224784187071361, + "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/code.py": 9700811903057180696, + "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/WHEEL": 18203500019759199992, + "venv/lib/python3.13/site-packages/numpy/f2py/use_rules.py": 17277594393032382485, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_arithmetic.py": 16829312896275893002, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_equals.py": 6429101196875333574, + "venv/lib/python3.13/site-packages/PIL/XpmImagePlugin.py": 6644626557482464312, + "venv/lib/python3.13/site-packages/PIL/PSDraw.py": 1927169421822446045, + "venv/lib/python3.13/site-packages/pygments/lexers/graph.py": 10445044822847205061, + "venv/lib/python3.13/site-packages/PIL/_imagingft.pyi": 1385456134120145584, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_get_numeric_data.py": 5896318696417090902, + "venv/lib/python3.13/site-packages/pygments/lexers/monte.py": 15158829991357994573, + "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/AUTHORS": 10073225185964928425, + "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/__main__.py": 11917862648584782420, + "venv/lib/python3.13/site-packages/pygments/lexers/dax.py": 10868881057512002309, + "venv/lib/python3.13/site-packages/PIL/Jpeg2KImagePlugin.py": 16905402423248975204, + "venv/lib/python3.13/site-packages/pandas/tests/window/__init__.py": 15130871412783076140, + "backend/src/api/routes/__tests__/test_clean_release_legacy_compat.py": 10703957986116846695, + "venv/lib/python3.13/site-packages/numpy/_pyinstaller/tests/pyinstaller-smoke.py": 13570990531070630950, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/io/test_common.py": 10797243274520625867, + "backend/src/api/routes/dashboards/_action_routes.py": 11814954258886577640, + "venv/lib/python3.13/site-packages/passlib/tests/_test_bad_register.py": 5446848310854472376, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_pct_change.py": 18056235438452125034, + "venv/lib/python3.13/site-packages/PIL/IcnsImagePlugin.py": 1870235606309784691, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/inout.f90": 1521999519583206538, + "venv/lib/python3.13/site-packages/pandas/errors/__init__.py": 13444371880185740908, + "backend/src/core/utils/matching.py": 12567367681677699487, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/histograms.pyi": 2281259341486424755, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_na_indexing.py": 8712547126522523899, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/io/conftest.py": 5864037534050136837, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_first_valid_index.py": 15763400665851423183, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_fiscal.py": 14652343698825214870, + "backend/src/services/clean_release/__tests__/test_source_isolation.py": 17714198919084455758, + "venv/lib/python3.13/site-packages/numpy/core/__init__.py": 10397294636564169377, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_item_selection.py": 1027989019709029615, + "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/assertion_session.py": 18109848200936213195, + "venv/lib/python3.13/site-packages/numpy/ma/core.py": 338350463523585845, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/exceptions.pyi": 9294219058621261971, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_replace.py": 4953527309376861139, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_shares_memory.py": 2911029123657970431, + "venv/lib/python3.13/site-packages/sqlalchemy/pool/impl.py": 4687705587963980337, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame.py": 16757570551941104401, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/default_styles.py": 4469204219504675080, + "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/requests.py": 14847842002253212098, + "venv/lib/python3.13/site-packages/dateutil/easter.py": 14631233890122048084, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/refresh_token.py": 17927903035152872556, + "venv/lib/python3.13/site-packages/pandas/_libs/interval.cpython-313-x86_64-linux-gnu.so": 8964760352224019544, + "venv/lib/python3.13/site-packages/PIL/_imagingmorph.cpython-313-x86_64-linux-gnu.so": 11171810899664471137, + "venv/lib/python3.13/site-packages/pycparser/_ast_gen.py": 5464347629908906775, + "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_css.py": 17765129030290410902, + "venv/lib/python3.13/site-packages/pygments/lexers/bibtex.py": 14652372822443154388, + "venv/lib/python3.13/site-packages/pandas/tests/extension/base/reshaping.py": 18085648077811502689, + "venv/lib/python3.13/site-packages/pygments/lexers/supercollider.py": 15306357945850389082, + "backend/src/core/config_models.py": 4264626520931642357, + "backend/tests/test_translate_history.py": 14504549443376034614, + "venv/lib/python3.13/site-packages/numpy/linalg/lapack_lite.pyi": 14069586330277925998, + "venv/lib/python3.13/site-packages/itsdangerous/signer.py": 3694661094753475840, + "venv/lib/python3.13/site-packages/pandas/tests/frame/test_subclass.py": 16342917051908786497, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_indexing.py": 6539365174681852769, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_arithmetic.py": 4858019700859362660, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_format.py": 16150524965028369071, + "frontend/src/lib/components/translate/TranslationRunResult.svelte": 10499421223016291488, + "venv/lib/python3.13/site-packages/git/refs/tag.py": 9979537867501757110, + "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/signals.py": 10390443713463805090, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/__init__.py": 13331622784664204066, + "venv/lib/python3.13/site-packages/pandas/plotting/__init__.py": 13230487326686617492, + "venv/lib/python3.13/site-packages/pygments/styles/inkpot.py": 10516710471319090846, + "venv/lib/python3.13/site-packages/pygments/lexers/int_fiction.py": 8806961041808606055, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/registration.py": 14639972512303032712, + "venv/lib/python3.13/site-packages/PIL/_imagingcms.cpython-313-x86_64-linux-gnu.so": 15198265718775753589, + "venv/lib/python3.13/site-packages/rapidfuzz/process.py": 3870006735299537016, + "venv/lib/python3.13/site-packages/pip/_internal/metadata/importlib/_compat.py": 4677414058216516380, + "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/reporter.py": 6510864297510700136, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_overrides.py": 92685611709898742, + "venv/lib/python3.13/site-packages/pandas/tests/api/test_types.py": 8889829773923216769, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ma.pyi": 6467636381637286867, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/hashes.py": 8545380307201732345, + "venv/lib/python3.13/site-packages/pip/_internal/resolution/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/multiarray.pyi": 6368268452184570195, + "venv/lib/python3.13/site-packages/anyio/_core/_tasks.py": 14104828341875599130, + "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/WHEEL": 3749476255729626245, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/introspection.py": 5447179017910128771, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_umath.py": 13010939919217862164, + "venv/lib/python3.13/site-packages/numpy/random/tests/data/sfc64_np126.pkl.gz": 1630203486813146863, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/DamerauLevenshtein.pyi": 2700568594438441246, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/authorization_server.py": 13696038495666024258, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/pkcs12.py": 5946672289916692272, + "venv/lib/python3.13/site-packages/passlib/tests/test_utils.py": 10362977406431569031, + "venv/lib/python3.13/site-packages/attrs/exceptions.py": 2871247302586505373, + "venv/lib/python3.13/site-packages/httpcore/_sync/connection.py": 1539337414493486168, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/logging.py": 2426447364230673649, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/utils.h": 3920393832993063886, + "backend/src/services/clean_release/repositories/candidate_repository.py": 14784344453820731941, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/dtype_api.h": 17040779421165903019, + "frontend/src/lib/components/translate/__tests__/test_correction_cell.svelte.js": 2314051239468628554, + "venv/lib/python3.13/site-packages/PIL/ImageCms.py": 5610897002957128546, + "venv/lib/python3.13/site-packages/pandas/_libs/hashing.pyi": 5241441378073929968, + "venv/lib/python3.13/site-packages/numpy/tests/test__all__.py": 10689265249302359388, + "venv/lib/python3.13/site-packages/numpy/random/tests/test_smoke.py": 7476432112986643847, + "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libcom_err-2abe824b.so.2.1": 12870528025628871295, + "venv/lib/python3.13/site-packages/numpy/_typing/_nbit_base.pyi": 6546751036506752550, + "venv/lib/python3.13/site-packages/pygments/styles/coffee.py": 17584414468786822371, + "venv/lib/python3.13/site-packages/pydantic/typing.py": 6661252174518316760, + "venv/lib/python3.13/site-packages/numpy/random/_pickle.py": 7774620933480975313, + "venv/lib/python3.13/site-packages/pandas/_libs/properties.cpython-313-x86_64-linux-gnu.so": 7092136701092358552, + "venv/lib/python3.13/site-packages/numpy.libs/libgfortran-040039e1-0352e75f.so.5.0.0": 13946067868274850557, + "venv/lib/python3.13/site-packages/numpy/tests/test_ctypeslib.py": 9592016432737074765, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_methods.py": 12694335778731418517, + "backend/src/plugins/translate/events.py": 14264965160929343917, + "frontend/src/lib/stores/__tests__/mocks/env_public.js": 2540122820969872185, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/random/bitgen.h": 12421210767114721499, + "venv/lib/python3.13/site-packages/pip/_internal/models/target_python.py": 422323125651848065, + "venv/lib/python3.13/site-packages/pydantic/_internal/_import_utils.py": 4029157986210295967, + "venv/lib/python3.13/site-packages/keyring/core.py": 2764269590123131634, + "venv/lib/python3.13/site-packages/numpy/_core/arrayprint.pyi": 84606125837677197, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/dtype.pyi": 12178008080078679769, + "venv/lib/python3.13/site-packages/numpy/random/tests/test_direct.py": 12680113511641199070, + "backend/src/api/routes/assistant/_routes.py": 6252816315418755346, + "venv/lib/python3.13/site-packages/pandas/util/_exceptions.py": 14426860079366867683, + "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_sparse_accessor.py": 6774374030220202353, + "venv/lib/python3.13/site-packages/pandas/util/__init__.py": 4070574585004336241, + "venv/lib/python3.13/site-packages/PIL/WmfImagePlugin.py": 15685062825106444247, + "venv/lib/python3.13/site-packages/numpy/core/_dtype_ctypes.pyi": 15130871412783076140, + "venv/lib/python3.13/site-packages/authlib/oidc/registration/claims.py": 4161520263207458028, + "venv/lib/python3.13/site-packages/apscheduler/executors/debug.py": 14072221218785494847, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalarbuffer.py": 16859789411010045795, + "venv/lib/python3.13/site-packages/PIL/JpegImagePlugin.py": 10621639599916796689, + "venv/lib/python3.13/site-packages/numpy/_core/printoptions.py": 3897105663572772838, + "venv/lib/python3.13/site-packages/keyring/compat/py312.py": 17581691618899404491, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_na_values.py": 13527837495439739279, + "venv/lib/python3.13/site-packages/jsonschema_specifications/tests/test_jsonschema_specifications.py": 12693210357718751894, + "venv/lib/python3.13/site-packages/numpy/core/function_base.py": 12696640832638144604, + "venv/lib/python3.13/site-packages/PIL/_imaging.cpython-313-x86_64-linux-gnu.so": 1425926264271197601, + "venv/lib/python3.13/site-packages/pygments/lexers/teal.py": 10004159499175716139, + "venv/lib/python3.13/site-packages/pandas/tests/resample/test_resample_api.py": 3278209206670699265, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalarprint.py": 9482100952562512933, + "venv/lib/python3.13/site-packages/pandas/_libs/window/aggregations.cpython-313-x86_64-linux-gnu.so": 16327106317503267067, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/metrics_py.py": 13809503317864539103, + "venv/lib/python3.13/site-packages/pip/_vendor/certifi/__main__.py": 8412594868333244844, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/privatemod.f90": 8999550841368314739, + "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_datetime.py": 4179112383995346046, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_normalize.py": 11373923576259976755, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/test_indexing.py": 9862204223281834360, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_week.py": 5756727157937218128, + "venv/lib/python3.13/site-packages/pygments/styles/bw.py": 869630132791421268, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_datetimes.py": 8863748366184419339, + "venv/lib/python3.13/site-packages/cffi/_shimmed_dist_utils.py": 4824806157907607487, + "frontend/src/components/git/BranchSelector.svelte": 6225347983501401973, + "venv/lib/python3.13/site-packages/PIL/_imagingcms.pyi": 12476347428820346383, + "venv/lib/python3.13/site-packages/referencing/tests/test_retrieval.py": 10782087416909177703, + "frontend/build/_app/immutable/nodes/30.D3JMnFof.js": 16119902291510484631, + "venv/lib/python3.13/site-packages/pandas/core/arrays/sparse/array.py": 3517673819082574078, + "venv/lib/python3.13/site-packages/pandas/tests/series/test_arrow_interface.py": 9757086292358759236, + "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/RECORD": 6518517239543344179, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/validator.py": 11486125578281617670, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_exceptions.py": 12145393002202744314, + "venv/lib/python3.13/site-packages/pygments/lexers/dns.py": 17149871769553794654, + "venv/lib/python3.13/site-packages/greenlet/greenlet_refs.hpp": 8525862687669040510, + "backend/tests/core/test_defensive_guards.py": 1048600814279591148, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/shape_base.pyi": 5046405609030418900, + "venv/lib/python3.13/site-packages/pygments/lexers/jsx.py": 13855228003748707341, + "venv/lib/python3.13/site-packages/pip/_internal/utils/setuptools_build.py": 13594639612360346306, + "venv/lib/python3.13/site-packages/numpy/lib/_index_tricks_impl.pyi": 5892973170789971535, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_constructors.py": 979131987837682435, + "venv/lib/python3.13/site-packages/jsonschema/benchmarks/useless_keywords.py": 11487954623214475915, + "venv/lib/python3.13/site-packages/pygments/lexer.py": 3658450949169647228, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py": 6152202474302791232, + "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/RECORD": 1164466882742493155, + "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_json_table_schema.py": 14454690938977069049, + "venv/lib/python3.13/site-packages/pydantic/_internal/_schema_generation_shared.py": 23345689300073549, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_replace.py": 8165088653532047247, + "venv/lib/python3.13/site-packages/pyasn1/type/opentype.py": 340146737126677655, + "venv/lib/python3.13/site-packages/anyio/_core/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/libs/test_hashtable.py": 7762405492052106717, + "venv/lib/python3.13/site-packages/numpy/_utils/_inspect.pyi": 17825266810219495672, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/flatiter.py": 3066469329738423021, + "venv/lib/python3.13/site-packages/pip/_internal/index/sources.py": 11609272011565024668, + "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/_pytest/compat.py": 10046464101087327473, + "venv/lib/python3.13/site-packages/passlib/tests/tox_support.py": 9200774792427691602, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_to_pydatetime.py": 1129954411080617001, + "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_set_value.py": 4166411740676564820, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/usecols/test_parse_dates.py": 5344929031479212951, + "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/string.f": 17328443345813567449, + "venv/lib/python3.13/site-packages/pip/_internal/index/collector.py": 7454652626329467900, + "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/licenses/LICENSE": 1641332741515411734, + "venv/lib/python3.13/site-packages/numpy/dtypes.pyi": 6713822658171717369, + "venv/lib/python3.13/site-packages/sqlalchemy/util/concurrency.py": 1325673503812009695, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/decl_base.py": 8678387511873412922, + "venv/lib/python3.13/site-packages/pip/_internal/cli/progress_bars.py": 7584699216537478969, + "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_elffile.py": 5728213398707817049, + "venv/lib/python3.13/site-packages/rapidfuzz/process_cpp.py": 16797760903996739079, + "venv/lib/python3.13/site-packages/apscheduler/executors/gevent.py": 17122637996105344344, + "venv/lib/python3.13/site-packages/numpy/random/__init__.py": 11732100564412485633, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_setitem.py": 2059440410065814114, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/bar.py": 12859947592168238832, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/pysqlcipher.py": 11225173272050906977, + "venv/lib/python3.13/site-packages/pygments/lexers/qvt.py": 1895735583818227972, + "backend/src/api/routes/__tests__/conftest.py": 8465980330386544642, + "venv/lib/python3.13/site-packages/pandas/_libs/pandas_parser.cpython-313-x86_64-linux-gnu.so": 18056339336364727359, + "venv/lib/python3.13/site-packages/numpy/ma/__init__.py": 214772578978182427, + "venv/lib/python3.13/site-packages/numpy/_core/_add_newdocs_scalars.pyi": 1826323011169529229, + "venv/lib/python3.13/site-packages/urllib3/_version.py": 839747992523118887, + "venv/lib/python3.13/site-packages/pygments/lexers/mojo.py": 8616283481592061285, + "backend/src/schemas/dataset_review.py": 15720223123457526104, + "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth1/resource_protector.py": 17080006010679257864, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/base.py": 5924592154431932923, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/twodim_base.pyi": 10156504423258357540, + "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/licenses/LICENSE": 9235234428907927646, + "venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py": 7301817934902711510, + "venv/lib/python3.13/site-packages/pygments/styles/murphy.py": 8177992406082781615, + "venv/lib/python3.13/site-packages/pygments/styles/lightbulb.py": 12433916113773598760, + "venv/lib/python3.13/site-packages/pygments/lexers/whiley.py": 218468511185731869, + "venv/lib/python3.13/site-packages/pygments/lexers/_openedge_builtins.py": 4979988747924637739, + "venv/lib/python3.13/site-packages/pandas/_libs/json.cpython-313-x86_64-linux-gnu.so": 2436285663630821963, + "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/idna-3.11.dist-info/METADATA": 14036738037171597049, + "venv/lib/python3.13/site-packages/pygments/styles/default.py": 13992125975366109635, + "venv/lib/python3.13/site-packages/numpy/fft/_pocketfft_umath.cpython-313-x86_64-linux-gnu.so": 16443444849116065961, + "venv/lib/python3.13/site-packages/jeepney/bus.py": 5163075760432139100, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/vectorized.pyi": 15498895254516573071, + "venv/lib/python3.13/site-packages/certifi/core.py": 7472627735517449185, + "venv/lib/python3.13/site-packages/ecdsa/der.py": 9374566189581725372, + "venv/lib/python3.13/site-packages/pydantic/error_wrappers.py": 11273827025986230629, + "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/licenses/LICENSE": 5757922580822401219, + "venv/lib/python3.13/site-packages/_pytest/unraisableexception.py": 4597178803320514675, + "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/RECORD": 11976403473353722969, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/fft.pyi": 14454280827038327842, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/test_arrow_compat.py": 12986187285988432338, + "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/WHEEL": 5990830714395966792, + "backend/src/plugins/translate/__tests__/test_scheduler.py": 4988970087981965515, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/lib_function_base.pyi": 2792940598392356268, + "venv/lib/python3.13/site-packages/pygments/styles/rrt.py": 9490973359165080360, + "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/controller.py": 5450931608244830335, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/__init__.py": 8811477458865810434, + "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/pyproject.py": 12684373765476932108, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh27697.f90": 4990763135487995517, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_cpu_features.py": 955759654189150497, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/live_render.py": 14619617939683800204, + "venv/lib/python3.13/site-packages/pygments/lexers/_cl_builtins.py": 16540712925368297957, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_bin_groupby.py": 14831211659124136806, + "venv/lib/python3.13/site-packages/numpy/_core/numeric.pyi": 17785360553418386488, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-cos.csv": 12896264205153363031, + "venv/lib/python3.13/site-packages/pandas/tests/extension/uuid/test_uuid.py": 13955678427426850807, + "venv/lib/python3.13/site-packages/pygments/lexers/ride.py": 14096748896451437594, + "venv/lib/python3.13/site-packages/pydantic/v1/decorator.py": 6124748023704700724, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/provision.py": 7362363963464621570, + "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/candidates.py": 5951912505933673835, + "venv/lib/python3.13/site-packages/_pytest/debugging.py": 16135285365306979060, + "venv/lib/python3.13/site-packages/_pytest/runner.py": 5772610501857496741, + "venv/lib/python3.13/site-packages/pygments/lexers/jsonnet.py": 1314044008440065525, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_conversion.py": 9159276697339089788, + "backend/src/models/dataset_review_pkg/_clarification_models.py": 1561486208194983219, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_interval.py": 1228451182688768814, + "venv/lib/python3.13/site-packages/numpy/f2py/f90mod_rules.pyi": 18290764713161282980, + "venv/lib/python3.13/site-packages/authlib/integrations/base_client/registry.py": 13306388361671753373, + "venv/lib/python3.13/site-packages/authlib/oidc/discovery/__init__.py": 308178910015974550, + "venv/lib/python3.13/site-packages/h11/_version.py": 9334144031400715479, + "venv/lib/python3.13/site-packages/referencing/tests/test_referencing_suite.py": 8875120876162738440, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timestamps.pyi": 51728851886466199, + "venv/lib/python3.13/site-packages/cryptography/py.typed": 15130871412783076140, + "dist/docker/backend.v1.0.0-rc2-docker.tar": 9693793465773386616, + "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/__init__.py": 18036348770966744795, + "venv/lib/python3.13/site-packages/greenlet/tests/test_generator_nested.py": 12822240347707346718, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_backend.py": 17793139799410518847, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/lambdas.py": 13377298868598623228, + "venv/lib/python3.13/site-packages/fastapi/openapi/utils.py": 9058442333718187759, + "venv/lib/python3.13/site-packages/numpy/random/tests/test_random.py": 4179188367630060654, + "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libpcre-9513aab5.so.1.2.0": 12298861477332583668, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_astype.py": 8505605634958454768, + "venv/lib/python3.13/site-packages/pandas/tests/frame/test_reductions.py": 3227705565578016389, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_as_unit.py": 8492383355919959393, + "venv/lib/python3.13/site-packages/dateutil/tz/__init__.py": 9617254832690762236, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_math.h": 16701045088211015518, + "venv/lib/python3.13/site-packages/numpy/lib/mixins.py": 7404729635424818497, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/conftest.py": 2643915042664055969, + "venv/lib/python3.13/site-packages/pygments/lexers/wgsl.py": 9718384325049172855, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/nested_sequence.pyi": 11245460325970663922, + "venv/lib/python3.13/site-packages/requests/help.py": 1885413874621672882, + "venv/lib/python3.13/site-packages/greenlet/tests/test_cpp.py": 10982107081267457286, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/__init__.py": 3673322722277252961, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/requirements.py": 2362917888844255805, + "frontend/src/types/backup.ts": 1741234034896689348, + "frontend/src/routes/tools/storage/+page.svelte": 2651964385884112547, + "venv/lib/python3.13/site-packages/numpy/_typing/_array_like.py": 2161873439361281488, + "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/WHEEL": 16097436423493754389, + "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/licenses/LICENSE": 14230156892574098522, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/__init__.py": 10357835306532281617, + "venv/lib/python3.13/site-packages/numpy/_pyinstaller/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_spinners.py": 15873416546130487469, + "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_tokenizer.py": 7994281991455916540, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/index_tricks.pyi": 11463747060334597941, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_round.py": 8336918400205461173, + "venv/lib/python3.13/site-packages/websockets/__init__.py": 4916307256304054040, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/twofactor/__init__.py": 18069619555394133945, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_f2py2e.py": 8571347023940385644, + "venv/lib/python3.13/site-packages/pip/_internal/models/search_scope.py": 9282393652860589543, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_equals.py": 18261810467289276844, + "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_insert.py": 11635164392966270621, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_is_full.py": 9577318758326279694, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_select_dtypes.py": 3530442956913622572, + "venv/lib/python3.13/site-packages/pandas/tests/extension/base/io.py": 11072022722163954973, + "venv/lib/python3.13/site-packages/passlib/utils/compat/_ordered_dict.py": 14248790502300368024, + "venv/lib/python3.13/site-packages/pandas/tests/io/test_clipboard.py": 12674078499544938252, + "venv/lib/python3.13/site-packages/pygments/styles/onedark.py": 17580335614588531275, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_searchsorted.py": 11208047646304753715, + "venv/lib/python3.13/site-packages/rapidfuzz/process.pyi": 6959881293311340830, + "venv/lib/python3.13/site-packages/keyring/backends/kwallet.py": 3071915635647280308, + "venv/lib/python3.13/site-packages/numpy/lib/_type_check_impl.pyi": 2667658052734929089, + "venv/lib/python3.13/site-packages/fastapi/responses.py": 6092572095549573593, + "venv/lib/python3.13/site-packages/pydantic/env_settings.py": 18250976255197243083, + "venv/lib/python3.13/site-packages/numpy/random/_common.cpython-313-x86_64-linux-gnu.so": 12834724130890991478, + "venv/lib/python3.13/site-packages/pandas/core/arrays/sparse/scipy_sparse.py": 2091608752719976909, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_to_string.py": 11422235699126032386, + "venv/lib/python3.13/site-packages/pandas/tests/internals/test_api.py": 11217428888457119601, + "venv/lib/python3.13/site-packages/pip/_vendor/distlib/resources.py": 11533706401259147051, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/ssh.py": 16262079536832961001, + "venv/lib/python3.13/site-packages/pygments/lexers/gleam.py": 5161116162065925222, + "venv/lib/python3.13/site-packages/pandas/tests/io/test_parquet.py": 11050150015772440923, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_sample.py": 16877779557071324115, + "venv/lib/python3.13/site-packages/pandas/io/formats/templates/latex_longtable.tpl": 12723621983797415444, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/poly1305.py": 10854598965202354516, + "venv/lib/python3.13/site-packages/keyring/http.py": 1408024724330078009, + "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/METADATA": 11759004913807981650, + "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_deprecated_kwargs.py": 10379929935087904974, + "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/RECORD": 3283324710045856319, + "venv/lib/python3.13/site-packages/pygments/lexers/css.py": 517586374264113606, + "backend/src/api/routes/translate/_metrics_routes.py": 13468336445030118059, + "venv/lib/python3.13/site-packages/greenlet/greenlet_exceptions.hpp": 8819301638282185623, + "backend/src/models/dataset_review.py": 5814500849969423218, + "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_string.py": 15542851215119662814, + "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/METADATA": 9458019064618635438, + "venv/lib/python3.13/site-packages/pandas/tests/api/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libldap-2974a1ba.so.2.0.200": 13590569080612602445, + "venv/lib/python3.13/site-packages/fastapi/openapi/models.py": 1680354178147364813, + "venv/lib/python3.13/site-packages/numpy/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/smmap/test/test_util.py": 5634593621291240094, + "venv/lib/python3.13/site-packages/pandas/tests/config/test_localization.py": 9524481848419616725, + "frontend/src/lib/components/reports/__tests__/report_detail.ux.test.js": 11878832350632571462, + "venv/lib/python3.13/site-packages/pygments/lexers/thingsdb.py": 6073447481627395832, + "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/WHEEL": 16097436423493754389, + "venv/lib/python3.13/site-packages/numpy/polynomial/polyutils.py": 12355826783958402233, + "venv/lib/python3.13/site-packages/sqlalchemy/util/topological.py": 11586868018611359415, + "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/RECORD": 13494296690334916257, + "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_laguerre.py": 7475592201750602042, + "venv/lib/python3.13/site-packages/pygments/lexers/ada.py": 17032408976634308999, + "venv/lib/python3.13/site-packages/psycopg2/extensions.py": 14197445323992851566, + "venv/lib/python3.13/site-packages/pygments/lexers/ezhil.py": 10294520768762308887, + "venv/lib/python3.13/site-packages/anyio/_core/_sockets.py": 10525237827959090532, + "venv/lib/python3.13/site-packages/fastapi/exceptions.py": 12665775976182239091, + "venv/lib/python3.13/site-packages/pygments/lexers/ambient.py": 18106929781201758080, + "backend/src/plugins/translate/__tests__/test_orthogonal_fixes.py": 17679703384686060315, + "backend/src/api/routes/__tests__/test_migration_routes.py": 4357515184436771537, + "backend/alembic.ini": 8897071018956157084, + "backend/alembic/versions/ed310b33f02c_multi_language_translation_tables.py": 1424919631205944664, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7521/__init__.py": 635200170992032966, + "venv/lib/python3.13/site-packages/pandas/tests/resample/test_resampler_grouper.py": 8388490036390951341, + "venv/lib/python3.13/site-packages/jsonschema/__init__.py": 6925762200139836824, + "venv/lib/python3.13/site-packages/pip/_internal/operations/build/wheel.py": 7728646523045538484, + "venv/lib/python3.13/site-packages/pandas/tests/internals/test_internals.py": 2049484047553296860, + "frontend/build/_app/immutable/chunks/B59ks8Wc.js": 12257988639088999545, + "venv/lib/python3.13/site-packages/pip/_internal/cli/__init__.py": 11914508471759255927, + "venv/lib/python3.13/site-packages/authlib/integrations/base_client/errors.py": 6538052228921426956, + "venv/lib/python3.13/site-packages/httpcore/_sync/__init__.py": 7676937747094511752, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_read.py": 8825002468745406134, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_value_counts.py": 12340872812120847127, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_floats.py": 3064615530495290792, + "venv/lib/python3.13/site-packages/pygments/formatters/pangomarkup.py": 17135620955205945255, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_categorical_equal.py": 7942323667866280872, + "venv/lib/python3.13/site-packages/PIL/_imagingmath.pyi": 18222325750818585549, + "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_generic.py": 1098361087956787007, + "venv/lib/python3.13/site-packages/authlib/__init__.py": 8957417237987377675, + "venv/lib/python3.13/site-packages/jsonschema/tests/test_format.py": 1947585389944838076, + "backend/src/schemas/__init__.py": 8700952869915187087, + "venv/lib/python3.13/site-packages/pyasn1/codec/ber/eoo.py": 5126566925877730303, + "venv/lib/python3.13/site-packages/authlib/oidc/core/errors.py": 18154419146257747681, + "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/dotenv.py": 5872848911499749500, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/hybrid.py": 5793056975404534989, + "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/METADATA": 6596896092754256988, + "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/licenses/LICENSE": 6965457853328313914, + "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/_libs/groupby.cpython-313-x86_64-linux-gnu.so": 14931394220112658268, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/operators.py": 2468046993343796128, + "venv/lib/python3.13/site-packages/packaging/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pillow.libs/libfreetype-ee1c40c4.so.6.20.4": 12301510769231120312, + "backend/tests/services/clean_release/test_policy_resolution_service.py": 3471271299977247598, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/array_api_info.pyi": 7887489694871300469, + "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/resource_protector.py": 4823504113176750140, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/fromnumeric.py": 3792079757208879362, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ufunc_config.pyi": 11754104063443791746, + "venv/lib/python3.13/site-packages/PIL/BdfFontFile.py": 10811640174253687845, + "backend/src/services/clean_release/repositories/report_repository.py": 17952038790457725175, + "venv/lib/python3.13/site-packages/jeepney/tests/secrets_introspect.xml": 10717038359151125278, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_update.py": 12293424926920594944, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/names.py": 705261158040926128, + "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_numba.py": 18148155441554555618, + "venv/lib/python3.13/site-packages/pip/_vendor/typing_extensions.py": 10158933506062403688, + "venv/lib/python3.13/site-packages/pygments/filters/__init__.py": 2992007913496948339, + "venv/lib/python3.13/site-packages/pygments/lexers/promql.py": 8929925488296216854, + "venv/lib/python3.13/site-packages/httpcore/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/passlib/utils/handlers.py": 10182859005870689026, + "venv/lib/python3.13/site-packages/numpy/exceptions.pyi": 13942486291715303235, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/_cryptography_key.py": 388489172928969873, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/_orm_constructors.py": 4276726508722638048, + "venv/lib/python3.13/site-packages/pluggy/_warnings.py": 2664977718908223842, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/mysqlconnector.py": 17538029557373507617, + "venv/lib/python3.13/site-packages/urllib3/__init__.py": 1854778274753799815, + "venv/lib/python3.13/site-packages/pygments/lexers/tlb.py": 1169242051301155885, + "backend/src/api/routes/environments.py": 6892252055515346170, + "venv/lib/python3.13/site-packages/pygments/lexers/urbi.py": 1611762607688882372, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_fillna.py": 7349777469648334282, + "frontend/src/lib/ui/Button.svelte": 921807193049478213, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/multiarray.pyi": 17232959648651278910, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/common.py": 11384497819737275399, + "venv/lib/python3.13/site-packages/gitdb/const.py": 14122142034887286559, + "venv/lib/python3.13/site-packages/passlib/ext/django/utils.py": 8118896525895185626, + "venv/lib/python3.13/site-packages/pandas/io/formats/templates/latex_table.tpl": 8706980975714184465, + "venv/lib/python3.13/site-packages/sqlalchemy/engine/events.py": 15099787454570172797, + "venv/lib/python3.13/site-packages/h11/_events.py": 13800479928851716538, + "venv/lib/python3.13/site-packages/jeepney/io/threading.py": 525625939662612746, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ma.pyi": 8186102816080813799, + "venv/lib/python3.13/site-packages/numpy/random/tests/test_randomstate_regression.py": 17425202198134409689, + "venv/lib/python3.13/site-packages/numpy/ma/tests/test_extras.py": 16160090335191788104, + "venv/lib/python3.13/site-packages/pandas/tests/extension/base/accumulate.py": 5780225603819849877, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_map.py": 6556132946198785761, + "venv/lib/python3.13/site-packages/rpds/rpds.cpython-313-x86_64-linux-gnu.so": 561326734302492859, + "venv/lib/python3.13/site-packages/numpy/lib/_polynomial_impl.pyi": 2042169688753984918, + "venv/lib/python3.13/site-packages/httpcore/_backends/base.py": 5491727479625093183, + "venv/lib/python3.13/site-packages/pygments/styles/algol_nu.py": 6229131016121450375, + "frontend/src/lib/components/assistant/AssistantChatPanel.svelte": 15111082609123137207, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_mips_unix.h": 17373389962405490482, + "venv/lib/python3.13/site-packages/numpy/_core/arrayprint.py": 1262543237476191714, + "backend/src/api/routes/__tests__/test_reports_detail_api.py": 6960149894653710507, + "venv/lib/python3.13/site-packages/anyio/from_thread.py": 7973678341601453474, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_format.py": 9331389900588353667, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/ed25519.py": 2285778903282667561, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/constrain.py": 6513876973118703677, + "frontend/build/_app/immutable/chunks/B28PfaP6.js": 2526537581472307531, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc_linux.h": 15772978805500070727, + "venv/lib/python3.13/site-packages/pandas/_libs/interval.pyi": 15698173755300703836, + "venv/lib/python3.13/site-packages/pandas/core/dtypes/api.py": 9829629144629841277, + "backend/src/core/superset_client/_user_projection.py": 16484323195475306883, + "backend/src/plugins/storage/__init__.py.bak": 7062955918227442388, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_to_latex.py": 2628895559914914693, + "venv/lib/python3.13/site-packages/pip/_vendor/requests/structures.py": 2668010839316715865, + "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/RECORD": 2963644632913976754, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/numpyconfig.h": 13339221870252345205, + "venv/lib/python3.13/site-packages/pandas/tests/extension/test_masked.py": 5380551301916549925, + "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_inference.py": 16402427186697071465, + "venv/lib/python3.13/site-packages/pygments/lexers/pascal.py": 5992422120590352714, + "frontend/src/lib/components/layout/TopNavbar.svelte": 14489256050586877364, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_indexing.py": 6039808271042864401, + "venv/lib/python3.13/site-packages/pydantic/networks.py": 15767095796055034509, + "venv/lib/python3.13/site-packages/numpy/lib/_nanfunctions_impl.py": 11621577915097515056, + "venv/lib/python3.13/site-packages/numpy/random/_sfc64.cpython-313-x86_64-linux-gnu.so": 17186695607612591922, + "venv/lib/python3.13/site-packages/numpy/_core/strings.py": 3623885046208831106, + "venv/lib/python3.13/site-packages/pygments/lexers/_googlesql_builtins.py": 12251289884604745945, + "frontend/src/routes/dashboards/health/+page.svelte": 5234355531444674267, + "frontend/src/routes/tools/debug/+page.svelte": 8699044541980877686, + "venv/lib/python3.13/site-packages/pandas/tests/interchange/test_utils.py": 2329717399120006435, + "frontend/src/services/connectionService.js": 16613277497380191542, + "venv/lib/python3.13/site-packages/pydantic/deprecated/config.py": 12280996227531856230, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/publicmod.f90": 2174121054736811903, + "venv/lib/python3.13/site-packages/pandas/tests/construction/test_extract_array.py": 3100523370314150013, + "venv/lib/python3.13/site-packages/pillow.libs/libjpeg-32d42e18.so.62.4.0": 11717944412021329207, + "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/shared.py": 1162754506656505196, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_ticks.py": 11649965080303468085, + "frontend/src/components/llm/ProviderConfig.svelte": 1564511833097781020, + "venv/lib/python3.13/site-packages/pygments/lexers/rego.py": 16022844238903541738, + "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_setitem.py": 14920902525192671548, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_astype.py": 8633811117672837999, + "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/RECORD": 7266315886702289726, + "venv/lib/python3.13/site-packages/tzlocal-5.3.1.dist-info/WHEEL": 5076688779572520166, + "backend/src/api/routes/git/_repo_lifecycle_routes.py": 6605622512801609889, + "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/__init__.py": 5027355874704300832, + "venv/lib/python3.13/site-packages/pillow.libs/liblzma-61b1002e.so.5.8.2": 11405063484938458842, + "frontend/src/lib/utils.js": 5436516952434475239, + "backend/src/api/routes/dataset_review_pkg/_routes.py": 11040245149296528009, + "venv/lib/python3.13/site-packages/pydantic/alias_generators.py": 5991580234179623842, + "venv/lib/python3.13/site-packages/pygments/lexers/go.py": 11118104397271513417, + "backend/tests/test_core_scheduler.py": 6589618269087393661, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/scalars.py": 3468820466230647963, + "venv/lib/python3.13/site-packages/pydantic/_internal/_git.py": 8760779092674434712, + "venv/lib/python3.13/site-packages/pygments/lexers/teraterm.py": 16132676290138105984, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_combine.py": 4446011286411407708, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_copy.py": 3114918520437707410, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/arrayscalars.h": 16142050006935459679, + "venv/lib/python3.13/site-packages/PIL/ImageChops.py": 16368812693381154921, + "backend/src/models/dataset_review_pkg/_finding_models.py": 17608383421420046491, + "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/licenses/LICENSE": 4672913476475760762, + "venv/lib/python3.13/site-packages/gitdb/stream.py": 3035738824550231197, + "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_hermite_e.py": 8912795372542950449, + "venv/lib/python3.13/site-packages/pandas/core/groupby/base.py": 16888506204910366302, + "venv/lib/python3.13/site-packages/_yaml/__init__.py": 3395829783751571350, + "venv/lib/python3.13/site-packages/_pytest/setupplan.py": 7496801885995567141, + "venv/lib/python3.13/site-packages/numpy/testing/__init__.py": 2831275254313750978, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/_neighborhood_iterator_imp.h": 10634781863364525895, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/test_federal.py": 16758212916399857971, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_rank.py": 14115215895836854973, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/__init__.py": 8632038387100622009, + "venv/lib/python3.13/site-packages/pip/_internal/utils/misc.py": 17461379236189029253, + "venv/lib/python3.13/site-packages/attr/_config.py": 1864824728504480204, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/six.py": 1161259802604920635, + "venv/lib/python3.13/site-packages/authlib/integrations/base_client/sync_app.py": 14788764260762890368, + "venv/lib/python3.13/site-packages/pandas/core/tools/numeric.py": 8510988912136285022, + "venv/lib/python3.13/site-packages/anyio/abc/__init__.py": 11428476337116642278, + "venv/lib/python3.13/site-packages/fastapi/middleware/httpsredirect.py": 5775982317459922443, + "venv/lib/python3.13/site-packages/pip/_internal/commands/debug.py": 13528633965821062950, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_compat.py": 11481259393140789881, + "venv/lib/python3.13/site-packages/_pytest/_io/pprint.py": 11202117031437223527, + "venv/lib/python3.13/site-packages/pip/_internal/index/__init__.py": 14829074315307489628, + "venv/lib/python3.13/site-packages/numpy/random/bit_generator.pyi": 15790738442952696034, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_deprecate_kwarg.py": 10417724544218303733, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/cymysql.py": 5570881524647789741, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_frame_equal.py": 12459816298158655274, + "venv/lib/python3.13/site-packages/uvicorn/protocols/http/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/ecdsa/test_curves.py": 6577762025900435885, + "venv/lib/python3.13/site-packages/pygments/lexers/j.py": 9766594937623918053, + "backend/src/core/task_manager/manager.py": 5748204558787054193, + "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_pbkdf2.py": 4977067068389993374, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_equals.py": 11041884432990762650, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_chaining_and_caching.py": 11784574265874608859, + "venv/lib/python3.13/site-packages/pandas/tests/generic/test_series.py": 2980850649986213051, + "frontend/src/lib/stores/__tests__/sidebar.test.js": 5168138864675110669, + "venv/lib/python3.13/site-packages/greenlet/tests/test_version.py": 6317733744899804292, + "venv/lib/python3.13/site-packages/pandas/io/json/_json.py": 1393095374713367445, + "venv/lib/python3.13/site-packages/numpy/f2py/f90mod_rules.py": 2953876934840155920, + "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/pydantic/functional_validators.py": 5835339743072048940, + "backend/src/api/routes/__tests__/test_dashboards.py": 14899529124453053148, + "venv/lib/python3.13/site-packages/pygments/lexers/jvm.py": 897669925284011089, + "backend/src/api/routes/health.py": 4494840518139445701, + "venv/lib/python3.13/site-packages/apscheduler/jobstores/mongodb.py": 5310116401542377882, + "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/_arrow_utils.py": 17808805047762566525, + "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libkeyutils-dfe70bd6.so.1.5": 9414227432578104677, + "venv/lib/python3.13/site-packages/cryptography/hazmat/backends/openssl/__init__.py": 4870269250323682576, + "venv/lib/python3.13/site-packages/pandas/tests/window/test_win_type.py": 18105114803686556748, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/base.py": 13634605726041717070, + "venv/lib/python3.13/site-packages/pygments/lexers/idl.py": 11454152060351801696, + "venv/lib/python3.13/site-packages/websockets/http.py": 9406523480132204760, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_compat.py": 6032546839876195115, + "venv/lib/python3.13/site-packages/uvicorn/loops/auto.py": 13086005977087619545, + "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/METADATA": 14608873187265321271, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/base.py": 5294446834530589760, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/ufuncobject.h": 5112456258078662871, + "venv/lib/python3.13/site-packages/pandas/tests/extension/test_sparse.py": 14343335524508450058, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ufuncs.pyi": 1808147181379894521, + "venv/lib/python3.13/site-packages/pandas/tests/io/sas/test_sas.py": 9446226619493404132, + "venv/lib/python3.13/site-packages/authlib/integrations/starlette_client/__init__.py": 9083396324667433335, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_sort_values.py": 15072305514178699398, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_cumulative.py": 11752712818547022872, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_fillna.py": 4610666845291315333, + "build.sh": 37085706669440656, + "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/METADATA": 15876173086384975957, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_errors.py": 3301889847545579393, + "venv/lib/python3.13/site-packages/pydantic/_internal/_discriminated_union.py": 1818179910730401509, + "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_parse_iso8601.py": 9100947620267156161, + "venv/lib/python3.13/site-packages/pip/_internal/utils/egg_link.py": 18211947508793805393, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/Indel.pyi": 16372699564794732463, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/connection.py": 8190661510572400096, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_align.py": 10284128457194204574, + "venv/lib/python3.13/site-packages/authlib/oidc/core/claims.py": 2035724920423374302, + "venv/lib/python3.13/site-packages/pandas/io/xml.py": 326466573926392764, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_numerictypes.py": 8836108334624807647, + "venv/lib/python3.13/site-packages/pandas/_libs/index.cpython-313-x86_64-linux-gnu.so": 18409579812171549318, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/abstract_interface/gh18403_mod.f90": 6219951399575860362, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/np_datetime.cpython-313-x86_64-linux-gnu.so": 7840846965295537844, + "venv/lib/python3.13/site-packages/git/diff.py": 6691274015605451565, + "run.sh": 4808871544409245302, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/lexers/__init__.py": 7316739139609490520, + "venv/lib/python3.13/site-packages/numpy/_utils/_pep440.py": 15854257948148516490, + "venv/lib/python3.13/site-packages/numpy/fft/_helper.py": 15906444100774706395, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_join.py": 13115782559805895662, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_set_name.py": 9094608008538024609, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-cosh.csv": 9287774220881887502, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_skew.py": 5276102682005383261, + "venv/lib/python3.13/site-packages/psycopg2/_psycopg.cpython-313-x86_64-linux-gnu.so": 13471342289207537479, + "venv/lib/python3.13/site-packages/authlib/integrations/base_client/framework_integration.py": 3935346152156572025, + "venv/lib/python3.13/site-packages/pip/_vendor/certifi/core.py": 2300277198409164253, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_dataframe.py": 14945138617962156057, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/interfaces.py": 5371646629319169153, + "frontend/src/lib/components/dataset-review/LaunchConfirmationPanel.svelte": 5965510319309867257, + "venv/lib/python3.13/site-packages/pip/_vendor/distlib/index.py": 2763962019423787504, + "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/setup.py": 5482352991573617756, + "venv/lib/python3.13/site-packages/numpy/_core/_add_newdocs.py": 15657897994221955882, + "venv/lib/python3.13/site-packages/greenlet/tests/fail_switch_two_greenlets.py": 11156275429806391390, + "backend/src/api/routes/__tests__/test_clean_release_source_policy.py": 15242462571646635922, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_numeric_only.py": 13610631681447961840, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8414/well_known.py": 7183795183137931709, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/queue.py": 7820997545569991670, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_antijoin.py": 14435396877404907826, + "frontend/build/_app/immutable/chunks/C9a28aU5.js": 5513483692277369740, + "backend/src/services/clean_release/repositories/audit_repository.py": 9617813121624417458, + "venv/lib/python3.13/site-packages/numpy/__init__.cython-30.pxd": 1476688171642957054, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/lib/mixins.pyi": 15597536290223628777, + "venv/lib/python3.13/site-packages/numpy/_core/defchararray.py": 15550230459945996915, + "venv/lib/python3.13/site-packages/dotenv/cli.py": 7952654621986067973, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/url.py": 9692934100602135106, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arcsinh.csv": 13695545125848146013, + "frontend/build/_app/immutable/chunks/Bxli7MEx.js": 13142003860484323974, + "venv/lib/python3.13/site-packages/pygments/lexers/basic.py": 12723021007042054402, + "venv/lib/python3.13/site-packages/pip/_internal/req/req_install.py": 7181005402818830655, + "venv/bin/pyrsa-encrypt": 5858278204727417482, + "frontend/src/lib/components/reports/__tests__/report_card.ux.test.js": 14899927226278257748, + "venv/lib/python3.13/site-packages/numpy/tests/test_configtool.py": 8208415015478205502, + "venv/lib/python3.13/site-packages/pandas/_libs/parsers.pyi": 18402185996588014111, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/test_other.py": 783701524491896337, + "backend/src/services/clean_release/__tests__/test_stages.py": 15353751625742444422, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_scalar_compat.py": 10068989979144965125, + "venv/lib/python3.13/site-packages/pygments/lexers/dalvik.py": 5549983892200382076, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/routines/funcfortranname.f": 9330535808093475892, + "venv/lib/python3.13/site-packages/pandas/util/_validators.py": 10201915528715968165, + "venv/lib/python3.13/site-packages/numpy/_core/shape_base.pyi": 10225243791643474943, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_join.py": 1131792466825856990, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-sin.csv": 1443087417808027268, + "venv/lib/python3.13/site-packages/fastapi/middleware/trustedhost.py": 4285622102799027823, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_network.py": 13159427333040109523, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_to_numpy.py": 14845850776625255794, + "backend/src/api/routes/storage.py": 15226523387798112491, + "venv/lib/python3.13/site-packages/numpy/_core/_asarray.py": 3468915833437229425, + "backend/src/services/dataset_review/clarification_engine.py": 13640221555439415988, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/dh.py": 5728866271812501558, + "venv/lib/python3.13/site-packages/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz": 17626265752554406355, + "venv/lib/python3.13/site-packages/fastapi/_compat/shared.py": 5249003014594464718, + "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/requests.py": 6703055041957748929, + "venv/lib/python3.13/site-packages/idna/intranges.py": 12536174834761591006, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_index.py": 4908727359687606870, + "frontend/src/routes/dashboards/health/__tests__/health_page.integration.test.js": 11653729504599199718, + "backend/src/core/database.py": 7064138501006682572, + "venv/lib/python3.13/site-packages/requests/cookies.py": 4997226307650350876, + "venv/lib/python3.13/site-packages/authlib/jose/util.py": 14843923624043422219, + "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/METADATA": 9041650844081036822, + "venv/lib/python3.13/site-packages/pip/_internal/cli/parser.py": 1064209424435927674, + "venv/lib/python3.13/site-packages/uvicorn/supervisors/watchfilesreload.py": 13062440477475586751, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_no_deprecated_api.h": 7896028550808252043, + "backend/src/core/async_superset_client.py": 17097960069181151584, + "venv/lib/python3.13/site-packages/click/_winconsole.py": 8133229457213704188, + "venv/lib/python3.13/site-packages/httpcore/_async/interfaces.py": 18250473733460571816, + "frontend/src/routes/settings/automation/+page.svelte": 15129032082642700205, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/instrumentation.py": 13198832283145198959, + "backend/test_pat_api.py": 4206656943734821967, + "venv/lib/python3.13/site-packages/fastapi/templating.py": 10760135144345238340, + "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/licenses/LICENSE": 2345070715845618109, + "backend/src/models/dataset_review_pkg/_enums.py": 2243691494729792539, + "venv/lib/python3.13/site-packages/keyring/completion.py": 1027436016070040568, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/fixtures/sql.py": 13315906751371033170, + "venv/lib/python3.13/site-packages/PIL/ImageEnhance.py": 3218405223202808764, + "venv/lib/python3.13/site-packages/cryptography/x509/verification.py": 1079694784860492682, + "docker/backend.Dockerfile": 10320070102635663967, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/scalars.pyi": 3130685119595923378, + "venv/lib/python3.13/site-packages/PIL/ImImagePlugin.py": 15452956038794399492, + "backend/src/models/dataset_review_pkg/_profile_models.py": 3121807680272913669, + "venv/lib/python3.13/site-packages/PIL/_imaging.pyi": 17119084207765761921, + "venv/lib/python3.13/site-packages/pandas/core/arrays/categorical.py": 15993211255162930859, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/pg_catalog.py": 15726448028057859831, + "venv/lib/python3.13/site-packages/PIL/TiffImagePlugin.py": 6845043550424565106, + "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/LICENSE": 6581019367004699816, + "venv/lib/python3.13/site-packages/uvicorn/protocols/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/fastapi/cli.py": 13972351579061154035, + "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_classes.py": 1440926036579216168, + "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_downcast.py": 10399746645741452200, + "venv/lib/python3.13/site-packages/pluggy/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_setops.py": 9991233160569430204, + "venv/lib/python3.13/site-packages/pandas/tests/frame/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/rpds/py.typed": 15130871412783076140, + "frontend/build/_app/immutable/chunks/YCgcezOr.js": 10021400156442571831, + "frontend/src/components/git/__tests__/git_manager.unfinished_merge.integration.test.js": 2437475749409257490, + "venv/lib/python3.13/site-packages/numpy/lib/_utils_impl.py": 13012775703413938576, + "venv/lib/python3.13/site-packages/pygments/lexers/graphql.py": 2307854666015224677, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/util.py": 4890614159013873000, + "venv/lib/python3.13/site-packages/pygments/lexers/arrow.py": 6699009974224818979, + "venv/lib/python3.13/site-packages/starlette/background.py": 10232175205397808417, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/lexers/_mapping.py": 17519715342700184302, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/asyncmy.py": 11808138763443525443, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arithmetic.pyi": 467927803068643024, + "venv/lib/python3.13/site-packages/pandas/_libs/arrays.cpython-313-x86_64-linux-gnu.so": 8634234308863090562, + "venv/lib/python3.13/site-packages/pandas/tests/apply/test_str.py": 149688376805129532, + "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_fillna.py": 16297834601116528166, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_datetime.py": 11417836378782978454, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_analytics.py": 8155550493311083506, + "venv/lib/python3.13/site-packages/pydantic/_internal/_core_utils.py": 13248004771466837645, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/mapped_collection.py": 11377280960650304531, + "venv/lib/python3.13/site-packages/PIL/WalImageFile.py": 12442826195371137238, + "venv/lib/python3.13/site-packages/PIL/_imagingtk.cpython-313-x86_64-linux-gnu.so": 1708198947135304326, + "venv/lib/python3.13/site-packages/PIL/ImageFile.py": 15765130658900167517, + "venv/lib/python3.13/site-packages/git/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/METADATA": 3643456577199395707, + "frontend/src/routes/reports/llm/[taskId]/+page.svelte": 14394593511269407852, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ufuncs.py": 12732599294816239111, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/operators.f90": 5949265961908386974, + "venv/lib/python3.13/site-packages/pygments/lexers/hare.py": 8693002231020751711, + "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/concatkdf.py": 6712732248328458871, + "backend/src/core/utils/superset_context_extractor/_pii.py": 14826864290194304173, + "backend/src/core/superset_client/_dashboards_crud.py": 4664728216214173491, + "backend/src/plugins/translate/__tests__/test_orchestrator.py": 6546216896393785602, + "venv/lib/python3.13/site-packages/pydantic/tools.py": 8931184638883701008, + "venv/lib/python3.13/site-packages/pillow.libs/libXau-154567c4.so.6.0.0": 4340972632724893052, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_os.h": 7883047506449405400, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/Indel.py": 17112989332785349705, + "venv/lib/python3.13/site-packages/gitdb/db/git.py": 13552203494737962026, + "venv/lib/python3.13/site-packages/_pytest/warnings.py": 8633394774569709013, + "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/ecdsa/ecdh.py": 12596317261561755793, + "venv/lib/python3.13/site-packages/numpy/lib/format.pyi": 11752225430594536662, + "venv/lib/python3.13/site-packages/numpy/random/tests/test_regression.py": 9375525053479844400, + "venv/lib/python3.13/site-packages/pandas/core/reshape/pivot.py": 4736553530021653868, + "venv/lib/python3.13/site-packages/authlib/oauth1/errors.py": 1154126353335030046, + "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/METADATA": 8985010079096958084, + "venv/lib/python3.13/site-packages/packaging/version.py": 13470993734108007779, + "venv/lib/python3.13/site-packages/pyasn1/compat/__init__.py": 5902203086150636670, + "venv/lib/python3.13/site-packages/pandas/tests/base/test_constructors.py": 2439700578107653984, + "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/METADATA": 18410956221497090898, + "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/licenses/LICENSE": 8364608327598414179, + "venv/lib/python3.13/site-packages/rsa/__init__.py": 14623742580410014505, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_indexing.py": 16623126293364224089, + "venv/lib/python3.13/site-packages/PIL/report.py": 9428754440615681790, + "backend/src/services/clean_release/candidate_service.py": 14044982155441302890, + "venv/lib/python3.13/site-packages/attr/_funcs.py": 5302917072419624193, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/jwk.py": 6458001384702613165, + "venv/lib/python3.13/site-packages/apscheduler/executors/tornado.py": 6635576580306890718, + "backend/src/core/superset_client/_databases.py": 14837101840847724937, + "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/WHEEL": 2357997949040430835, + "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/licenses/LICENSE": 3509878235770224233, + "frontend/build/_app/immutable/chunks/CAvRWKcP.js": 11625217357725761813, + "backend/src/api/routes/__tests__/test_dataset_review_api.py": 17381354465400611694, + "backend/src/services/clean_release/stages/__init__.py": 11216464651705158032, + "venv/lib/python3.13/site-packages/urllib3-2.6.2.dist-info/METADATA": 2624107638694809013, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_repr.py": 5577699046802107144, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/annotation.py": 15855576199737688124, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py": 7624316342162916928, + "venv/lib/python3.13/site-packages/jsonschema/_keywords.py": 949562792260528762, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/abc.py": 6227782083136374888, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_normalize.py": 7378656958631172603, + "venv/lib/python3.13/site-packages/smmap/test/test_buf.py": 6910367739329016619, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_clip.py": 8087139801274517318, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/interval/test_interval_new.py": 3893421355544517336, + "backend/src/models/__tests__/test_clean_release.py": 3448406855108346883, + "backend/tests/test_task_persistence.py": 1764267414712263025, + "venv/lib/python3.13/site-packages/keyring/backends/libsecret.py": 11621088556661567306, + "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/endpoints.py": 18334891787808122725, + "venv/lib/python3.13/site-packages/pygments/lexers/theorem.py": 15666523910367201285, + "venv/lib/python3.13/site-packages/pluggy/__init__.py": 8269188363563356631, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_rank.py": 5398520257852104723, + "backend/src/services/reports/report_service.py": 17586405613867657190, + "venv/lib/python3.13/site-packages/numpy/tests/test_warnings.py": 3154249157134620649, + "venv/lib/python3.13/site-packages/passlib/handlers/sun_md5_crypt.py": 1949993216707182407, + "venv/lib/python3.13/site-packages/sqlalchemy/event/registry.py": 2857989070743633709, + "venv/lib/python3.13/site-packages/gitdb/util.py": 645937410168583692, + "venv/lib/python3.13/site-packages/websockets/sync/connection.py": 2791040669094103200, + "venv/lib/python3.13/site-packages/pip/_internal/cli/cmdoptions.py": 12107733000019393631, + "venv/lib/python3.13/site-packages/numpy/_typing/__init__.py": 18242238390157333247, + "venv/lib/python3.13/site-packages/passlib/crypto/scrypt/_builtin.py": 74545289993348593, + "venv/lib/python3.13/site-packages/sqlalchemy/__init__.py": 9751988289698484530, + "backend/src/core/auth/__tests__/test_auth.py": 14999763239648705195, + "venv/lib/python3.13/site-packages/numpy/random/_examples/cffi/extending.py": 9859383893070793914, + "venv/lib/python3.13/site-packages/starlette/authentication.py": 10905269573809129547, + "venv/lib/python3.13/site-packages/pandas/tests/frame/common.py": 7426635866622531875, + "backend/src/models/report.py": 9185954411073383239, + "venv/lib/python3.13/site-packages/pandas/tests/window/test_api.py": 6439927798101672423, + "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/typing/tests/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/passlib/handlers/phpass.py": 16489430001449160264, + "frontend/build/_app/immutable/nodes/22.STjI15IE.js": 217759497864778118, + "backend/src/api/auth.py": 16577622718621592661, + "backend/src/api/routes/dashboards/__init__.py": 15214026957520044598, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_datetimelike.py": 15246580603900811749, + "venv/lib/python3.13/site-packages/pandas/tests/base/test_misc.py": 9190561773853901527, + "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_set_value.py": 17480833128128893268, + "venv/lib/python3.13/site-packages/pandas/core/window/doc.py": 4204367435727844696, + "venv/lib/python3.13/site-packages/sqlalchemy/util/_py_collections.py": 16825222625411635946, + "frontend/src/components/storage/FileList.svelte": 11661146151896000393, + "venv/lib/python3.13/site-packages/pandas/tests/extension/list/test_list.py": 4538625980063375611, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/__init__.py": 15130871412783076140, + "frontend/src/routes/profile/+page.svelte": 17979719303737794427, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/_asymmetric.py": 6903778603779934572, + "venv/lib/python3.13/site-packages/numpy/f2py/common_rules.py": 7352635707860427145, + "venv/lib/python3.13/site-packages/pip/_internal/utils/direct_url_helpers.py": 6075890513530296650, + "venv/lib/python3.13/site-packages/pandas/_libs/pandas_datetime.cpython-313-x86_64-linux-gnu.so": 15874094681262240628, + "frontend/src/lib/ui/Icon.svelte": 2201964532717139995, + "venv/lib/python3.13/site-packages/pip/_internal/main.py": 13711402795965346761, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/tree.py": 4991806303236874829, + "venv/lib/python3.13/site-packages/pip/_internal/network/download.py": 5256731341219268693, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_combine.py": 16193618152415684421, + "venv/lib/python3.13/site-packages/pandas/tests/base/common.py": 13335865314907577354, + "venv/lib/python3.13/site-packages/annotated_doc/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/yaml/representer.py": 10550136298978225013, + "frontend/src/routes/datasets/review/__tests__/dataset_review_entry.test.js": 7689381541193660594, + "backend/tests/core/test_git_service_gitea_pr.py": 6098719224379185148, + "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/keyring/devpi_client.py": 3445890176686211982, + "venv/lib/python3.13/site-packages/authlib/integrations/base_client/sync_openid.py": 5670082466989878756, + "venv/lib/python3.13/site-packages/pip/_internal/distributions/base.py": 16714704323747942110, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_series.py": 10922287546912569276, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_comparison.py": 4611207880323503098, + "venv/lib/python3.13/site-packages/passlib/crypto/digest.py": 15890463288512025688, + "venv/lib/python3.13/site-packages/pandas/io/formats/printing.py": 3054136648863371285, + "venv/lib/python3.13/site-packages/sqlalchemy/pool/events.py": 13473858896579666058, + "venv/lib/python3.13/site-packages/pyasn1/type/tag.py": 13912273274509186651, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_drop_duplicates.py": 2397396876872403048, + "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_datetime64.py": 16272266806084058743, + "venv/lib/python3.13/site-packages/pandas/io/pickle.py": 5418646169167774144, + "venv/lib/python3.13/site-packages/dateutil/parser/isoparser.py": 18015430204844361067, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_shape_base.py": 8837845103338426570, + "venv/lib/python3.13/site-packages/pip/_vendor/idna/compat.py": 9758194415584776667, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_common_basic.py": 1945891789924713537, + "venv/lib/python3.13/site-packages/_pytest/mark/__init__.py": 9343015549300275714, + "venv/lib/python3.13/site-packages/smmap/util.py": 13276170835044840023, + "venv/lib/python3.13/site-packages/pygments/lexers/asc.py": 10744437946030875496, + "frontend/src/routes/dashboards/[id]/components/DashboardGitManager.svelte": 4990524146294551357, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7009/parameters.py": 1647490964392525933, + "venv/lib/python3.13/site-packages/click/core.py": 16793133181718891193, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/util.py": 6088868370298560146, + "venv/lib/python3.13/site-packages/urllib3/_base_connection.py": 14495079097019980154, + "venv/lib/python3.13/site-packages/requests/hooks.py": 9888227370911151341, + "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/test_support.pyi": 3893434234020223151, + "venv/lib/python3.13/site-packages/numpy/_core/fromnumeric.py": 9409852116555866847, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_size.py": 8527839563560550806, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/plugin/bootstrap.py": 3865947239497500815, + "venv/lib/python3.13/site-packages/charset_normalizer/__main__.py": 8887772289570078278, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_x64_masm.asm": 15349921092257597740, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_at_time.py": 15352346149584081864, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_count.py": 16947194157984708529, + "venv/lib/python3.13/site-packages/numpy/tests/test_matlib.py": 14395481530627870882, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_isin.py": 8136794647591341784, + "venv/lib/python3.13/site-packages/pip/_internal/network/auth.py": 6159841209618753296, + "venv/lib/python3.13/site-packages/authlib/oauth2/client.py": 7237359250450222680, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/_cipheralgorithm.py": 10057637461647348368, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_engines.py": 2790877023773269276, + "venv/lib/python3.13/site-packages/pandas/tests/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/licenses/numpy/_core/src/highway/LICENSE": 15636145745140922094, + "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/RECORD": 16740224557818847141, + "venv/lib/python3.13/site-packages/numpy/core/_dtype.pyi": 15130871412783076140, + "venv/lib/python3.13/site-packages/uvicorn/middleware/wsgi.py": 9179913252056394958, + "frontend/src/lib/stores/datasetReviewSession.js": 3915919349382526215, + "backend/src/services/__tests__/test_llm_provider.py": 4705572506930455768, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/enumerated.py": 16623643153933348755, + "venv/lib/python3.13/site-packages/pip/_internal/operations/build/wheel_legacy.py": 12735901522735836481, + "venv/lib/python3.13/site-packages/apscheduler/triggers/cron/expressions.py": 8015786996064244656, + "venv/lib/python3.13/site-packages/pytest_asyncio/__init__.py": 8162213292669110211, + "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/licenses/LICENSE": 3996324383113221529, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_datetimelike.py": 5317270578347271174, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_logical/foo77.f": 16250175448122328648, + "venv/lib/python3.13/site-packages/websockets/server.py": 16599051743322571790, + "venv/lib/python3.13/site-packages/pyasn1/__init__.py": 8089201217593738032, + "venv/lib/python3.13/site-packages/pip/_internal/distributions/wheel.py": 13979536782410081712, + "venv/lib/python3.13/site-packages/pandas/tests/io/excel/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/fastapi/_compat/__init__.py": 12380131786677943349, + "venv/lib/python3.13/site-packages/httpcore/_backends/mock.py": 6849131425727092784, + "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pydantic/_internal/_generics.py": 16438159042939059717, + "venv/lib/python3.13/site-packages/anyio/_core/_synchronization.py": 7050001375718876608, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/resource_protector.py": 11539718751174980004, + "frontend/src/lib/ui/index.ts": 6883965364006817450, + "frontend/src/routes/datasets/+page.svelte": 18132315883450880052, + "frontend/src/components/storage/FileUpload.svelte": 14805293086068620697, + "venv/lib/python3.13/site-packages/numpy/random/_sfc64.pyi": 3536657185495782642, + "venv/lib/python3.13/site-packages/numpy/polynomial/laguerre.py": 151202984060101867, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_regression.py": 6742646011852052645, + "venv/lib/python3.13/site-packages/yaml/scanner.py": 8554164423030397366, + "frontend/build/_app/immutable/nodes/1.NnkkqxwF.js": 2557541528204355497, + "venv/lib/python3.13/site-packages/pluggy/_manager.py": 18202550145040079612, + "venv/lib/python3.13/site-packages/jsonschema_specifications/tests/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/console.py": 3540660073442483692, + "venv/lib/python3.13/site-packages/pydantic/experimental/pipeline.py": 9493054841465227788, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_groupby.py": 16180421154734310873, + "venv/lib/python3.13/site-packages/apscheduler/jobstores/zookeeper.py": 4318643109309626098, + "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_indexing.py": 81180636019259296, + "venv/lib/python3.13/site-packages/authlib/oidc/discovery/models.py": 6924198551176217533, + "venv/lib/python3.13/site-packages/pandas/tests/frame/test_alter_axes.py": 11338712836362534969, + "venv/lib/python3.13/site-packages/pygments/lexers/zig.py": 470431199354307668, + "backend/src/models/dashboard.py": 8479838979214366697, + "venv/lib/python3.13/site-packages/pip/_vendor/requests/__version__.py": 14138134075118474134, + "venv/lib/python3.13/site-packages/requests/structures.py": 2668010839316715865, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/nbit_base_example.pyi": 8571452382806614924, + "venv/lib/python3.13/site-packages/numpy/typing/__init__.pyi": 10058149460938883683, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_arithmetics.py": 16527169124402715210, + "venv/lib/python3.13/site-packages/jeepney/wrappers.py": 15234251727654692435, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_api.py": 14120915875574640262, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_x64_msvc.h": 17581467060937454503, + "venv/lib/python3.13/site-packages/pygments/lexers/__init__.py": 4627540245914849670, + "venv/lib/python3.13/site-packages/numpy/random/_examples/cython/extending_distributions.pyx": 15302775787158991386, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_take.py": 14969455660160053080, + "venv/lib/python3.13/site-packages/cffi/recompiler.py": 17809252277700094304, + "venv/lib/python3.13/site-packages/sqlalchemy/events.py": 9329355486544822483, + "venv/lib/python3.13/site-packages/pygments/lexers/c_cpp.py": 1211842877043321095, + "venv/lib/python3.13/site-packages/charset_normalizer/md__mypyc.cpython-313-x86_64-linux-gnu.so": 12629680116730190225, + "venv/lib/python3.13/site-packages/numpy/lib/stride_tricks.pyi": 5879290708972838025, + "venv/lib/python3.13/site-packages/pygments/lexers/prolog.py": 599539463980699865, + "backend/src/services/dataset_review/orchestrator_pkg/_helpers.py": 11613130235340753050, + "venv/lib/python3.13/site-packages/pygments/lexers/wowtoc.py": 17527844575999013592, + "venv/lib/python3.13/site-packages/pydantic/deprecated/json.py": 17692639396786690144, + "backend/src/api/routes/assistant/_history.py": 16318881016647964852, + "venv/lib/python3.13/site-packages/numpy/_core/fromnumeric.pyi": 13945478633722616250, + "backend/src/services/clean_release/repository.py": 3077298775936340703, + "venv/lib/python3.13/site-packages/pandas/tests/generic/test_finalize.py": 12539815426478689538, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test__version.py": 9037916251087760255, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_indexing.py": 4063662953863959087, + "backend/src/plugins/translate/metrics.py": 16289306156708185830, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/region.py": 12579403230062395563, + "venv/lib/python3.13/site-packages/pandas/io/formats/templates/html_table.tpl": 17198355067645888735, + "venv/lib/python3.13/site-packages/pygments/lexers/sas.py": 6128008194712914874, + "venv/lib/python3.13/site-packages/apscheduler/triggers/cron/fields.py": 8923326131649837922, + "venv/lib/python3.13/site-packages/pandas/io/sas/sas_xport.py": 16525568795475918874, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_strings.py": 7168544888340296373, + "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/licenses/LICENSE": 17020744174398828059, + "venv/lib/python3.13/site-packages/pip/_vendor/distlib/version.py": 6401479036177132374, + "venv/lib/python3.13/site-packages/ecdsa/__init__.py": 6237633580090653788, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/random.pyi": 9425735458050148191, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/module_data_docstring.f90": 18245403117623015312, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/__ufunc_api.h": 4516275133897904047, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/text.py": 6096215585499446070, + "venv/lib/python3.13/site-packages/pandas/core/common.py": 14578909424716153057, + "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_readers.py": 2136472634307645842, + "venv/lib/python3.13/site-packages/pandas/tests/extension/test_interval.py": 14749388246573356959, + "venv/lib/python3.13/site-packages/sqlalchemy/log.py": 10101221585967121334, + "backend/src/plugins/git/__init__.py": 2144831474780401625, + "venv/lib/python3.13/site-packages/pydantic/_internal/_decorators_v1.py": 16723743964226526155, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/npyio.pyi": 14147712281086095231, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/base.py": 13269563625127294513, + "venv/lib/python3.13/site-packages/jsonschema/benchmarks/const_vs_enum.py": 12873459583943748931, + "venv/lib/python3.13/site-packages/passlib/tests/test_hosts.py": 8284535274820610802, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_arithmetic.py": 17449383588949771785, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_scalar.py": 2434773821902319678, + "backend/src/services/clean_release/policy_engine.py": 3180817867716931725, + "venv/lib/python3.13/site-packages/pip/_vendor/msgpack/__init__.py": 5896924546560667519, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/errors.py": 12777931960088171310, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/interchange/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pyasn1/codec/der/decoder.py": 11876648884087997745, + "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_nanfunctions.py": 2356468092336024365, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_custom_business_month.py": 1613806538807726074, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_round.py": 14996007456708990295, + "venv/lib/python3.13/site-packages/cffi/vengine_gen.py": 6582900613549620556, + "venv/lib/python3.13/site-packages/authlib/integrations/django_client/__init__.py": 14186136918454802843, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_nth.py": 17151595277666975085, + "venv/lib/python3.13/site-packages/jeepney-0.9.0.dist-info/WHEEL": 12054782055241301457, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_swaplevel.py": 3584770792383216626, + "venv/lib/python3.13/site-packages/charset_normalizer/cli/__main__.py": 2148876100501691980, + "venv/lib/python3.13/site-packages/pandas/_version.py": 3480474785419232091, + "venv/lib/python3.13/site-packages/websockets/headers.py": 13587146967490088657, + "venv/lib/python3.13/site-packages/pandas/tests/reductions/test_stat_reductions.py": 11569525436540769152, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_qcut.py": 8972418112914954758, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/timedeltas/test_cumulative.py": 8178093067175155877, + "venv/lib/python3.13/site-packages/anyio/_core/_tempfile.py": 230288423480899091, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/asymmetric_key.py": 14948661854506285135, + "venv/lib/python3.13/site-packages/websockets/legacy/protocol.py": 762692033188392424, + "venv/lib/python3.13/site-packages/greenlet/tests/_test_extension.cpython-313-x86_64-linux-gnu.so": 1211491156495529145, + "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/WHEEL": 14550174241288068152, + "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py3-objarr.npz": 12369168483236619421, + "venv/lib/python3.13/site-packages/pandas/tests/tools/test_to_datetime.py": 3499461736474530062, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7662/models.py": 11521700876708601977, + "venv/lib/python3.13/site-packages/numpy/lib/tests/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/secretstorage/collection.py": 17903258621904912493, + "venv/lib/python3.13/site-packages/anyio/streams/text.py": 12507591237176920223, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90": 8079594129222364031, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/gh26920/two_mods_with_one_public_routine.f90": 7957683453180939605, + "venv/lib/python3.13/site-packages/pandas/tests/apply/test_invalid_arg.py": 610891871484326055, + "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_odf.py": 15484940480924122966, + "venv/lib/python3.13/site-packages/fastapi/__main__.py": 10755252341326986079, + "venv/lib/python3.13/site-packages/gitdb/db/pack.py": 13460574575424209609, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/RECORD": 5612689057373270213, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_libsparse.py": 1859997684694949029, + "venv/lib/python3.13/site-packages/pygments/lexers/robotframework.py": 11507713622179102496, + "venv/lib/python3.13/site-packages/pygments/lexers/unicon.py": 1155454077052833821, + "frontend/src/lib/auth/permissions.js": 12787489292887903923, + "backend/src/services/__tests__/test_rbac_permission_catalog.py": 5190751380981933250, + "backend/tests/test_resource_hubs.py": 3990299394875930767, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/ed448.pyi": 13016654355866474644, + "venv/lib/python3.13/site-packages/pandas/core/tools/times.py": 6560679305255812809, + "venv/lib/python3.13/site-packages/numpy/lib/_arraypad_impl.pyi": 2186875333484796630, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_append.py": 9644955836191900614, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_integer.py": 16102640589300356639, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_loongarch64_linux.h": 6566098590441297326, + "venv/lib/python3.13/site-packages/pydantic/_internal/_dataclasses.py": 15256193972947054890, + "venv/lib/python3.13/site-packages/ecdsa/ssh.py": 17010933326090778158, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/argon2.py": 15389474901714096890, + "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/websockets_sansio_impl.py": 17221368219485351394, + "venv/lib/python3.13/site-packages/passlib/tests/sample_config_1s.cfg": 1809713544666311828, + "venv/lib/python3.13/site-packages/fastapi/_compat/model_field.py": 392699021682253569, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/test_function.py": 644452398244782315, + "backend/src/core/utils/network.py": 2917454689057905472, + "venv/lib/python3.13/site-packages/pygments/lexers/gcodelexer.py": 13712494327007684318, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_repr.py": 13147587049887075335, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_ddl.py": 3690189094298044728, + "venv/lib/python3.13/site-packages/rapidfuzz/utils.py": 5682627611354455144, + "venv/lib/python3.13/site-packages/pydantic/v1/main.py": 213087273729911492, + "venv/lib/python3.13/site-packages/numpy/f2py/crackfortran.py": 12796890117561096360, + "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py": 17873236864291624476, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_reindex.py": 8772423071604000084, + "backend/src/api/routes/git_schemas.py": 9243114525622127446, + "venv/lib/python3.13/site-packages/pandas/core/computation/expr.py": 13085709365673019494, + "venv/lib/python3.13/site-packages/pygments/lexers/oberon.py": 15220143799603451830, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_reset_index.py": 5946666595195952693, + "frontend/src/routes/tools/backups/+page.svelte": 6796050751535238723, + "venv/lib/python3.13/site-packages/pandas/io/excel/__init__.py": 6662687963241471393, + "venv/lib/python3.13/site-packages/fastapi/datastructures.py": 727178955746650271, + "frontend/build/_app/immutable/chunks/NoAbU4pR.js": 10213250914533162255, + "venv/lib/python3.13/site-packages/passlib/tests/backports.py": 17098448557554464521, + "venv/lib/python3.13/site-packages/pandas/tests/io/generate_legacy_storage_files.py": 11015954144633661960, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_arithmetic.py": 15071337112968886738, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/functions.py": 16567226076808693246, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_csky_gcc.h": 12929785267195988209, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/securetransport.py": 12104888897121018676, + "venv/lib/python3.13/site-packages/jose/__init__.py": 15575670403380555945, + "venv/lib/python3.13/site-packages/httpx/_main.py": 1812303705973265093, + "venv/lib/python3.13/site-packages/pandas/_libs/groupby.pyi": 6154952803757623626, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/assertions.py": 5556667947376168765, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/infer.py": 12541904372617915365, + "venv/lib/python3.13/site-packages/git/objects/submodule/__init__.py": 12958523219496107878, + "venv/lib/python3.13/site-packages/_pytest/unittest.py": 10848803633530338204, + "venv/lib/python3.13/site-packages/pandas/tests/resample/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_range.py": 3544406211185340973, + "venv/lib/python3.13/site-packages/dateutil/relativedelta.py": 5903095963079475484, + "backend/src/api/routes/__tests__/test_assistant_api.py": 16438212076178324033, + "backend/tests/test_smoke_plugins.py": 10704454611361370435, + "venv/lib/python3.13/site-packages/pandas/io/common.py": 12088195203620154171, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/einsumfunc.pyi": 8902765738896588686, + "venv/lib/python3.13/site-packages/numpy/polynomial/polyutils.pyi": 8195943561787777127, + "venv/lib/python3.13/site-packages/numpy/polynomial/chebyshev.py": 1590647503660777156, + "venv/lib/python3.13/site-packages/attr/exceptions.pyi": 12323493441583681402, + "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/client_auth.py": 3301527187487914220, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timestamps.cpython-313-x86_64-linux-gnu.so": 13209491675968970365, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_construction.py": 10619501873883861745, + "venv/lib/python3.13/site-packages/pydantic/dataclasses.py": 12384956801113860889, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/plugin/__init__.py": 10470644151952252331, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_common.py": 9097104320321411408, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_get_dummies.py": 16112674981222844375, + "venv/lib/python3.13/site-packages/authlib/integrations/sqla_oauth2/tokens_mixins.py": 9923721909178724437, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/__init__.py": 5933622200264572885, + "venv/lib/python3.13/site-packages/pandas/tests/series/test_formats.py": 13752366280743004410, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/expression.py": 15511250785671695359, + "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/METADATA": 6960169108624303030, + "venv/lib/python3.13/site-packages/websockets/speedups.cpython-313-x86_64-linux-gnu.so": 10941658763526595989, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/persistence.py": 17908437937265384125, + "venv/lib/python3.13/site-packages/dateutil/parser/_parser.py": 9443336890192151397, + "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/licenses/LICENSE": 12684353321716745791, + "venv/lib/python3.13/site-packages/pydantic/_internal/_serializers.py": 12077180322353709930, + "venv/lib/python3.13/site-packages/pygments/lexers/tact.py": 1164971357219795420, + "venv/lib/python3.13/site-packages/pygments/lexers/markup.py": 10311057264960923433, + "venv/lib/python3.13/site-packages/annotated_doc/main.py": 3384049281532298500, + "venv/lib/python3.13/site-packages/pygments/lexers/compiled.py": 8215290039991205531, + "frontend/src/lib/api/assistant.js": 15470667170083225911, + "backend/src/api/routes/assistant/_schemas.py": 6735060826070731731, + "venv/lib/python3.13/site-packages/passlib/handlers/fshp.py": 13298827601291507295, + "backend/src/api/routes/assistant/__init__.py": 14959302162073618175, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/__init__.py": 3577295959173028042, + "venv/lib/python3.13/site-packages/pandas/_libs/sparse.pyi": 12526865400413362140, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/oracledb.py": 7158791242292470472, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_easter.py": 3397863170068576196, + "backend/src/api/routes/translate/__init__.py": 6357999798616465776, + "venv/lib/python3.13/site-packages/attr/filters.py": 14156141488477438777, + "venv/lib/python3.13/site-packages/numpy.libs/libscipy_openblas64_-096271d3.so": 14338208504131470036, + "venv/lib/python3.13/site-packages/pip/_internal/wheel_builder.py": 3893922370396791826, + "venv/lib/python3.13/site-packages/gitdb/pack.py": 7828244200815444166, + "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pydantic/fields.py": 4142211199816898047, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_io.py": 4199750143323741326, + "venv/lib/python3.13/site-packages/secretstorage/item.py": 15486045386471912693, + "venv/lib/python3.13/site-packages/numpy/lib/_array_utils_impl.pyi": 11535882608355652318, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/linalg.pyi": 7217817172953767893, + "frontend/src/lib/components/translate/TermCorrectionPopup.svelte": 572725570855489866, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_to_typst.py": 14619529283550788275, + "venv/lib/python3.13/site-packages/psycopg2/extras.py": 7510107741729866600, + "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/__init__.py": 17630019785411546070, + "venv/lib/python3.13/site-packages/pygments/lexers/json5.py": 9736695186548899403, + "backend/src/services/clean_release/manifest_service.py": 10873340336255220063, + "venv/lib/python3.13/site-packages/urllib3/exceptions.py": 9687187566231423953, + "frontend/src/components/TaskHistory.svelte": 7819646903874958430, + "venv/lib/python3.13/site-packages/pandas/tseries/__init__.py": 2648641118117738895, + "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/METADATA": 1862765380818895200, + "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_mask.py": 5451866071307236899, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/flatiter.pyi": 9598576095384661517, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_docs.py": 17898499890274685198, + "backend/src/services/clean_release/repositories/manifest_repository.py": 12395698948312301073, + "venv/lib/python3.13/site-packages/pandas/tests/tools/test_to_numeric.py": 18037815278545274402, + "backend/delete_running_tasks.py": 4453015771820664913, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/polynomial/hermite.pyi": 3573629536236108391, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_infer_objects.py": 6769980076977692890, + "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/RECORD": 8971487317739420905, + "venv/lib/python3.13/site-packages/numpy/_typing/_add_docstring.py": 14657346268890680694, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/declarative_asn1.pyi": 16934250836612138541, + "venv/lib/python3.13/site-packages/charset_normalizer/cli/__init__.py": 9702005609966176016, + "venv/lib/python3.13/site-packages/pandas/_libs/missing.pyi": 13543139288840944411, + "venv/lib/python3.13/site-packages/numpy/_core/getlimits.py": 7842717073693731093, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_case_when.py": 4133174129660834805, + "venv/lib/python3.13/site-packages/authlib/oauth2/__init__.py": 13682931764896414722, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_pop.py": 14885271225856187795, + "venv/lib/python3.13/site-packages/jose/jwt.py": 3405491994268385178, + "venv/lib/python3.13/site-packages/httpx/_utils.py": 4836536051177895209, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_missing.py": 7034102519042351965, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/test_timedelta.py": 12822713918114715561, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_eng_formatting.py": 14768815444701392013, + "venv/lib/python3.13/site-packages/cffi/model.py": 13544803366359102016, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_array_coercion.py": 3551994404797560483, + "venv/lib/python3.13/site-packages/pandas/core/internals/managers.py": 13547912653290063698, + "venv/lib/python3.13/site-packages/pandas/tests/util/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/click/parser.py": 13988544851350599869, + "venv/lib/python3.13/site-packages/httpcore/_sync/http_proxy.py": 14037211594707072958, + "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/licenses/LICENSE": 7959949171752474553, + "venv/lib/python3.13/site-packages/pygments/lexers/chapel.py": 7619603166448145621, + "venv/lib/python3.13/site-packages/pygments/lexers/kusto.py": 16285533608924436308, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/validator.py": 14200019408839159476, + "venv/lib/python3.13/site-packages/pip/_vendor/idna/__init__.py": 6489437464172324468, + "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/METADATA": 4868544280955034757, + "venv/lib/python3.13/site-packages/rapidfuzz/fuzz.py": 1094797446508902066, + "venv/lib/python3.13/site-packages/pip/_internal/models/wheel.py": 10473287225032326206, + "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/licenses/LICENSE": 8438117004702803716, + "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/licenses/LICENSE": 3868190977070717994, + "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/limited_api2.pyx": 15936470837420356071, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timezones.cpython-313-x86_64-linux-gnu.so": 1137453907225619959, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/io/orc.py": 12754290195886557668, + "venv/lib/python3.13/site-packages/sqlalchemy/engine/reflection.py": 5951113078754792806, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/properties.py": 5799883762127872919, + "venv/lib/python3.13/site-packages/numpy/_core/_umath_tests.cpython-313-x86_64-linux-gnu.so": 3478629877770507853, + "venv/lib/python3.13/site-packages/jeepney/io/tests/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pip/_internal/utils/urls.py": 8698341051522816167, + "venv/lib/python3.13/site-packages/pandas/compat/_constants.py": 3909166275649444824, + "venv/lib/python3.13/site-packages/tzlocal/utils.py": 7893867974548929154, + "frontend/build/_app/immutable/chunks/D9dVwiHl.js": 14131011399955207172, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_interval_tree.py": 15789443159423302291, + "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pandas/tests/series/test_npfuncs.py": 13987318550267921389, + "backend/tests/test_auth.py": 6167020718035755646, + "backend/src/services/git/_base.py": 4172145857123113006, + "venv/lib/python3.13/site-packages/httpx/__version__.py": 9473642134297828811, + "venv/lib/python3.13/site-packages/click-8.3.1.dist-info/WHEEL": 8600534672961461758, + "venv/lib/python3.13/site-packages/pygments/lexers/tls.py": 3552078393009383412, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_set_axis.py": 4097534573847151853, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_sort_values.py": 12064896795288302730, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_doc.py": 7865575374100528149, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/twofactor/totp.py": 11888568940387752607, + "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/heuristics.py": 1422768761337195135, + "venv/lib/python3.13/site-packages/greenlet/TUserGreenlet.cpp": 16258622236210473101, + "venv/lib/python3.13/site-packages/pip/_internal/models/candidate.py": 3099785363867247334, + "venv/lib/python3.13/site-packages/pip/_vendor/tomli_w/py.typed": 9796674040111366709, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_abstract_interface.py": 17625870734108222276, + "venv/lib/python3.13/site-packages/fastapi/routing.py": 466387159689567541, + "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/licenses/LICENSE": 11199044866758471950, + "venv/lib/python3.13/site-packages/pydantic/experimental/missing_sentinel.py": 1637241331832367709, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/quoted_character/foo.f": 15318083678609435813, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/random/distributions.h": 17162252287980242413, + "venv/lib/python3.13/site-packages/numpy/_core/_dtype_ctypes.pyi": 14543653817631274394, + "venv/lib/python3.13/site-packages/pandas/_version_meson.py": 4875297137037630519, + "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/core": 6622984507059115517, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_reindex.py": 16348619731902304844, + "venv/lib/python3.13/site-packages/click/decorators.py": 2920877667855377423, + "venv/lib/python3.13/site-packages/pip/_vendor/distlib/wheel.py": 828222664427570058, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_asof.py": 8656532774394927388, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_dst.py": 12243642467695371088, + "venv/lib/python3.13/site-packages/pandas/tests/io/test_http_headers.py": 13187746870209705951, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_iterrows.py": 3791886201566670087, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_quoting.py": 1147992698412929658, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_astype.py": 15384141282611151560, + "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/util.pyx": 649821942746469002, + "venv/lib/python3.13/site-packages/numpy/random/tests/data/pcg64dxsm-testset-2.csv": 16611724551361692999, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_nat.py": 18428782698385974380, + "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/RECORD": 2024211292009381421, + "venv/lib/python3.13/site-packages/PIL/SpiderImagePlugin.py": 12234762087257163606, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_any_index.py": 10800968419286329268, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/arrayterator.pyi": 15722265241660279277, + "venv/lib/python3.13/site-packages/pygments/lexers/_mysql_builtins.py": 16087227298679432006, + "frontend/src/lib/utils/debounce.js": 16884470786640632815, + "backend/logs/app.log.2": 6692440785424103264, + "venv/lib/python3.13/site-packages/pygments/lexers/other.py": 6893672181003034910, + "venv/lib/python3.13/site-packages/cffi/verifier.py": 8473599757770867754, + "venv/lib/python3.13/site-packages/pandas/_libs/lib.pyi": 3049004444338566197, + "scripts/scan_secrets.sh": 599173385111063848, + "backend/src/schemas/dataset_review_pkg/_composites.py": 1898056130177244572, + "venv/lib/python3.13/site-packages/pandas/core/strings/accessor.py": 14021462534679430426, + "backend/tests/services/dataset_review/test_superset_matrix.py": 5114797134613078913, + "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/resource_protector.py": 9147671710440653567, + "venv/lib/python3.13/site-packages/pygments/lexers/dsls.py": 11696359794961833087, + "venv/lib/python3.13/site-packages/numpy/tests/test_numpy_config.py": 3636377988901907424, + "venv/lib/python3.13/site-packages/pandas/util/_doctools.py": 3766479022075611396, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_extension_array_equal.py": 16119106336497630796, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/util.py": 10640907133050862176, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/roles.py": 5448455900674232810, + "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_compression.py": 8577756801858495168, + "venv/lib/python3.13/site-packages/fastapi/param_functions.py": 14585101566697773072, + "venv/lib/python3.13/site-packages/pandas/tests/frame/test_ufunc.py": 5025605639221470838, + "venv/lib/python3.13/site-packages/_pytest/terminal.py": 885450969703476729, + "venv/lib/python3.13/site-packages/pandas/_libs/index.pyi": 17679349633640606985, + "backend/tests/services/clean_release/test_demo_mode_isolation.py": 1970652424726919519, + "venv/lib/python3.13/site-packages/_pytest/_py/error.py": 2257336434271433543, + "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/LICENSE": 16343563559291870811, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/array_constructors.pyi": 164538008396001632, + "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/implicit.py": 5400555157488808948, + "venv/lib/python3.13/site-packages/pygments/lexers/ampl.py": 4594260378653369985, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_file_buffer_url.py": 15377043158761455858, + "venv/lib/python3.13/site-packages/attr/_version_info.py": 3850449653182103457, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_block_docstring.py": 18146459246837890489, + "venv/lib/python3.13/site-packages/PIL/ImageWin.py": 13635870584232081323, + "venv/lib/python3.13/site-packages/sqlalchemy/event/__init__.py": 16182540084654095394, + "venv/lib/python3.13/site-packages/pandas/core/groupby/groupby.py": 5536922766239875007, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_get_set.py": 14375107704596905983, + "venv/lib/python3.13/site-packages/pyasn1/error.py": 11036037300994516747, + "venv/lib/python3.13/site-packages/urllib3/response.py": 1987354357306756790, + "venv/lib/python3.13/site-packages/apscheduler/schedulers/background.py": 2105814165112049750, + "venv/lib/python3.13/site-packages/websockets/speedups.c": 11800200877763464246, + "venv/lib/python3.13/site-packages/pyasn1/type/tagmap.py": 14075859042659927673, + "venv/lib/python3.13/site-packages/websockets/sync/router.py": 10335595955948355382, + "venv/lib/python3.13/site-packages/pip/_internal/commands/wheel.py": 16397273591245583356, + "venv/lib/python3.13/site-packages/jose/backends/native.py": 50023158618000658, + "venv/lib/python3.13/site-packages/passlib/tests/sample1c.cfg": 13088198405762342506, + "venv/lib/python3.13/site-packages/pandas/tests/extension/test_string.py": 13234624995755549329, + "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_cat_accessor.py": 4304062895283374927, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-log.csv": 221209423454319618, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/lib_version.pyi": 3636944488233043883, + "venv/lib/python3.13/site-packages/sqlalchemy/schema.py": 16029542421991709659, + "venv/lib/python3.13/site-packages/pycparser/__init__.py": 16499940957411260458, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_between.py": 337429135216881486, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/models.py": 16636119441941357281, + "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/METADATA": 7788873460115135563, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_time_series.py": 5205199092955498507, + "frontend/src/components/tasks/LogEntryRow.svelte": 10992388311554587653, + "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/yaml.py": 17801117405950663611, + "backend/src/services/dataset_review/clarification_pkg/_helpers.py": 4822867945130807759, + "venv/lib/python3.13/site-packages/numpy/lib/recfunctions.py": 3001896031623204147, + "venv/lib/python3.13/site-packages/pandas/core/arrays/sparse/accessor.py": 8373575175447947401, + "venv/lib/python3.13/site-packages/pandas/io/parsers/readers.py": 7899068668225389287, + "venv/lib/python3.13/site-packages/pandas/core/arrays/floating.py": 1215586266958421991, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/rule.py": 5318344538761246105, + "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/meson.build": 8784756284679859367, + "venv/lib/python3.13/site-packages/pygments/lexers/php.py": 17636450950688953288, + "venv/lib/python3.13/site-packages/pygments/lexers/amdgpu.py": 17249439604111838979, + "backend/test_auth.db": 18214842050920965999, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/modes.py": 6832635056228445650, + "venv/lib/python3.13/site-packages/numpy/random/tests/test_seed_sequence.py": 7687465232954593311, + "venv/lib/python3.13/site-packages/pandas/io/clipboards.py": 5183212433608887727, + "venv/lib/python3.13/site-packages/fastapi/__init__.py": 11054203163075417954, + "frontend/src/lib/api/__tests__/reports_api.test.js": 11820587361929895100, + "venv/lib/python3.13/site-packages/pandas/tests/extension/test_datetime.py": 1678885152993000592, + "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/licenses/LICENSE": 17284252174641192866, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/dtypes/test_categorical.py": 9615571808720893016, + "venv/lib/python3.13/site-packages/click/types.py": 6491651131669287534, + "venv/lib/python3.13/site-packages/pandas/core/computation/ops.py": 18250656489649699560, + "venv/lib/python3.13/site-packages/pyasn1/codec/cer/decoder.py": 17559787396729804535, + "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py": 5324490103277723813, + "venv/lib/python3.13/site-packages/jaraco/classes/py.typed": 15130871412783076140, + "frontend/src/components/git/GitManager.svelte": 10046788495793334635, + "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/RECORD": 9803861100978586236, + "frontend/src/lib/stores/__tests__/test_taskDrawer.js": 13582869875796637016, + "backend/src/services/clean_release/repositories/__init__.py": 9926779835387630811, + "venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/RECORD": 12015288851076448205, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/f2cmap/isoFortranEnvMap.f90": 15768643271492041853, + "venv/lib/python3.13/site-packages/tzlocal-5.3.1.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/PIL/BmpImagePlugin.py": 16682567630621529903, + "venv/lib/python3.13/site-packages/numpy/typing/tests/test_typing.py": 10311989961588249147, + "venv/lib/python3.13/site-packages/pandas/io/stata.py": 14370692318835340323, + "frontend/src/lib/stores/__tests__/test_datasetReviewSession.js": 12620073136419991103, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/base_key.py": 10402800587070352851, + "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/WHEEL": 16097436423493754389, + "venv/lib/python3.13/site-packages/numpy/linalg/_linalg.pyi": 9629457630163613604, + "venv/lib/python3.13/site-packages/pydantic/aliases.py": 14481980467204711659, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_comparisons.py": 2764694394636775220, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_drop_duplicates.py": 5874427993953991216, + "venv/lib/python3.13/site-packages/numpy/_core/numerictypes.py": 6205675182996213576, + "venv/lib/python3.13/site-packages/pandas/core/util/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/io/formats/templates/html.tpl": 12550218314797699304, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_multiarray.py": 5928288171180750841, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_array.py": 16867692337986161626, + "venv/lib/python3.13/site-packages/PIL/AvifImagePlugin.py": 1872412416505003364, + "backend/src/scripts/seed_permissions.py": 12022710984424584961, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_join.py": 11910166566689889389, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_offsets.py": 4499538899492148499, + "backend/src/core/auth/__init__.py": 16435384828055133073, + "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libk5crypto-b1f99d5c.so.3.1": 10669523137596317954, + "venv/lib/python3.13/site-packages/pydantic/_internal/_utils.py": 10936299012115637790, + "venv/lib/python3.13/site-packages/sqlalchemy/event/attr.py": 5971663429221923939, + "venv/lib/python3.13/site-packages/pygments/lexers/codeql.py": 4254046699692048717, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/endpoint.py": 8519226897299461194, + "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/licenses/numpy/ma/LICENSE": 6723325434476453127, + "venv/lib/python3.13/site-packages/numpy/_core/umath.pyi": 11775804030935134661, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_contains.py": 5273759677032634868, + "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/METADATA": 6438256145634479451, + "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_matrix_linalg.py": 2858987911347541177, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/aiosqlite.py": 9888795404090331319, + "venv/lib/python3.13/site-packages/jeepney/tests/test_low_level.py": 3579024079580951234, + "venv/lib/python3.13/site-packages/pip/_vendor/idna/codec.py": 14814999235499530522, + "venv/lib/python3.13/site-packages/numpy/_core/_internal.py": 13056946834347643109, + "venv/lib/python3.13/site-packages/numpy/linalg/lapack_lite.cpython-313-x86_64-linux-gnu.so": 11074560904305737689, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/testing.pyi": 16263777835572515739, + "venv/lib/python3.13/site-packages/pandas/core/window/online.py": 13551140636252302201, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_dict.py": 808180749933361743, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_formats.py": 1265319125235346745, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_multiprocessing.py": 5522490547285108448, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_diff.py": 2216748778018882333, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/naming.py": 14503932124671438340, + "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/RECORD": 6349071557579241461, + "venv/lib/python3.13/site-packages/pygments/lexers/iolang.py": 10997512999728724130, + "venv/lib/python3.13/site-packages/numpy/typing/tests/test_runtime.py": 12534621594420844770, + "frontend/src/types/dashboard.ts": 9718666955722367566, + "frontend/src/components/git/DeploymentModal.svelte": 6232413208557068848, + "venv/lib/python3.13/site-packages/jsonschema/validators.py": 3832874295500213309, + "venv/lib/python3.13/site-packages/jose/exceptions.py": 8562012933958941039, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_integrity.py": 12010564145080323987, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_real/foo90.f90": 58572216018544419, + "venv/lib/python3.13/site-packages/sqlalchemy/util/compat.py": 16148553252010089561, + "backend/src/services/notifications/__init__.py": 13930898146447654299, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pygments/lexers/tablegen.py": 2917626373516779857, + "venv/lib/python3.13/site-packages/pandas/tests/tools/test_to_time.py": 10463741033950978270, + "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/jeepney/tests/test_wrappers.py": 4813328996575597980, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/warnings_and_errors.pyi": 9019577563960071498, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_repeat.py": 16971624301893342868, + "venv/lib/python3.13/site-packages/secretstorage/dhcrypto.py": 8860116996905452758, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ufunc_config.py": 14728417910466146460, + "venv/lib/python3.13/site-packages/passlib/handlers/md5_crypt.py": 7669328623914474137, + "venv/lib/python3.13/site-packages/pandas/core/indexes/datetimelike.py": 4356700619632833878, + "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/WHEEL": 13232065379159720345, + "venv/lib/python3.13/site-packages/PIL/py.typed": 15130871412783076140, + "frontend/tailwind.config.js": 13139381085024634801, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/visitors.py": 5190923415390076080, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/__init__.py": 6532094538918910232, + "venv/lib/python3.13/site-packages/pandas/tests/computation/test_eval.py": 2921337784087808487, + "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/METADATA": 1684451390569121499, + "venv/lib/python3.13/site-packages/rsa/parallel.py": 4968566722541778371, + "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/licenses/LICENSE": 16147999986886816451, + "venv/lib/python3.13/site-packages/rapidfuzz/_feature_detector.py": 15458248567257759500, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_reshape.py": 10576230966727810832, + "frontend/src/lib/stores/__tests__/mocks/state.js": 3616783395254238777, + "venv/lib/python3.13/site-packages/apscheduler/jobstores/base.py": 11386927749822539057, + "frontend/src/services/toolsService.js": 1568142461283466080, + "venv/lib/python3.13/site-packages/starlette/middleware/exceptions.py": 10408538054406276433, + "venv/lib/python3.13/site-packages/pygments/formatter.py": 11156733836937309465, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalarmath.py": 9762951701352556447, + "backend/tests/test_logger.py": 11506419828617508917, + "venv/lib/python3.13/site-packages/cryptography/hazmat/asn1/__init__.py": 4290669519959060720, + "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/RECORD": 9678861487447993169, + "frontend/src/lib/components/layout/__tests__/test_topNavbar.svelte.js": 11053755879172333925, + "venv/lib/python3.13/site-packages/apscheduler/jobstores/memory.py": 9947113720821563254, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_common.py": 2223069451949206319, + "frontend/src/lib/components/translate/TranslationPreview.svelte": 192144965481842186, + "venv/lib/python3.13/site-packages/pip/_internal/network/utils.py": 13421242949994555055, + "backend/src/services/clean_release/publication_service.py": 5215271639026811180, + "venv/lib/python3.13/site-packages/apscheduler/triggers/combining.py": 1264860868414723829, + "venv/lib/python3.13/site-packages/numpy/ma/extras.py": 7559838309481824664, + "venv/lib/python3.13/site-packages/pandas/tests/apply/test_frame_apply.py": 8103417303073393969, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_api.py": 1910541672533352625, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_timegrouper.py": 276805119790266454, + "venv/lib/python3.13/site-packages/_pytest/deprecated.py": 5452408732344157294, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/JaroWinkler_py.py": 16189204441438239231, + "venv/lib/python3.13/site-packages/pip/_internal/commands/install.py": 17631777189475433503, + "venv/lib/python3.13/site-packages/numpy/_typing/_nbit_base.py": 7446626038222262489, + "venv/lib/python3.13/site-packages/greenlet/platform/setup_switch_x64_masm.cmd": 8473866644286785815, + "venv/lib/python3.13/site-packages/numpy/random/_pcg64.pyi": 14785496840737986355, + "venv/lib/python3.13/site-packages/requests/_internal_utils.py": 4091305333167213279, + "backend/src/api/routes/translate/_helpers.py": 13265933139767815312, + "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/METADATA": 14070889071949105584, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_shape_base.py": 4117141349022217163, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/block_docstring/foo.f": 2489756567993745076, + "venv/lib/python3.13/site-packages/greenlet/TPythonState.cpp": 12828594265749606443, + "venv/lib/python3.13/site-packages/fastapi/utils.py": 15402403831700548944, + "venv/lib/python3.13/site-packages/itsdangerous/url_safe.py": 13454753900702274266, + "venv/lib/python3.13/site-packages/gitdb/__init__.py": 15381521749253695923, + "venv/lib/python3.13/site-packages/pydantic/experimental/__init__.py": 492399139963056461, + "venv/lib/python3.13/site-packages/passlib/crypto/scrypt/_salsa.py": 1756536674254931838, + "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libcrypto-2e26a48f.so.3": 3658133521245392852, + "venv/lib/python3.13/site-packages/pandas/tests/apply/test_frame_transform.py": 6759417099641034692, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_missing.py": 2976310411820303374, + "venv/lib/python3.13/site-packages/numpy/f2py/_src_pyf.py": 546976622482819095, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_to_julian_date.py": 6868080396693831272, + "venv/lib/python3.13/site-packages/pandas/core/indexes/range.py": 3838277376774246164, + "venv/lib/python3.13/site-packages/pandas/tests/libs/test_lib.py": 6721066015604956469, + "venv/lib/python3.13/site-packages/greenlet/tests/fail_clearing_run_switches.py": 3020294789560975101, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_size.py": 16658280641516916790, + "venv/lib/python3.13/site-packages/pydantic_core/_pydantic_core.pyi": 16799580742094025110, + "venv/lib/python3.13/site-packages/pillow.libs/libavif-01e67780.so.16.3.0": 13947441788826399574, + "venv/lib/python3.13/site-packages/pyasn1/codec/der/encoder.py": 4790267438222037867, + "venv/lib/python3.13/site-packages/git/objects/__init__.py": 2110615482320355676, + "venv/lib/python3.13/site-packages/urllib3/py.typed": 12220177918227495093, + "frontend/eslint.config.js": 14296985543214702398, + "backend/src/core/mapping_service.py": 15428037653286485748, + "backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py": 6773352403538028864, + "frontend/build/_app/immutable/chunks/7w4QGhl2.js": 163809850003626570, + "venv/lib/python3.13/site-packages/numpy/_typing/_ufunc.py": 16859854811012717088, + "venv/lib/python3.13/site-packages/websockets/exceptions.py": 12048063047468402740, + "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/METADATA": 16498441272591167134, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_matplotlib.py": 12775850858284584296, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_types.py": 4083297168618981717, + "venv/lib/python3.13/site-packages/PIL/ImageMorph.py": 13861961228125789866, + "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/METADATA": 13776251749114562660, + "venv/lib/python3.13/site-packages/uvicorn/middleware/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/vector.py": 9941185556118343263, + "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_libfrequencies.py": 16302676625743291594, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_cpu.h": 13799366908726531089, + "venv/lib/python3.13/site-packages/numpy/linalg/tests/test_deprecations.py": 14624516389510242394, + "venv/lib/python3.13/site-packages/tzlocal/win32.py": 1949985224569608978, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/authenticate_client.py": 16886645731942472285, + "venv/lib/python3.13/site-packages/rsa/pkcs1_v2.py": 3533398238491175229, + "venv/lib/python3.13/site-packages/pip/_internal/distributions/sdist.py": 9490366272695301385, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_index_new.py": 796607958391882182, + "venv/lib/python3.13/site-packages/click/_utils.py": 16491408631876616271, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_produces_warning.py": 750781117570375777, + "venv/lib/python3.13/site-packages/pip/_vendor/requests/exceptions.py": 14982764273485726199, + "venv/lib/python3.13/site-packages/pandas/tests/extension/test_period.py": 6047041810867211174, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_accessor.py": 10074496835594855786, + "venv/lib/python3.13/site-packages/pandas/io/api.py": 8275376846208437741, + "venv/lib/python3.13/site-packages/dateutil/zoneinfo/__init__.py": 10261654903106416888, + "venv/lib/python3.13/site-packages/click/_termui_impl.py": 3296085065310341855, + "venv/lib/python3.13/site-packages/gitdb/typ.py": 16374739906244805047, + "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/__init__.py": 71159121705871510, + "venv/lib/python3.13/site-packages/numpy/_core/_simd.pyi": 13553578040186939249, + "venv/lib/python3.13/site-packages/passlib/utils/pbkdf2.py": 15802959653228956404, + "venv/lib/python3.13/site-packages/git/objects/fun.py": 15014209679156260865, + "venv/lib/python3.13/site-packages/pygments/lexers/snobol.py": 414946539602526513, + "venv/lib/python3.13/site-packages/numpy/random/tests/data/sfc64-testset-1.csv": 5708101386018266998, + "venv/lib/python3.13/site-packages/numpy/_core/_dtype.py": 7796703383405149774, + "venv/lib/python3.13/site-packages/PIL/MpoImagePlugin.py": 644327650732339301, + "venv/lib/python3.13/site-packages/pandas/core/arrays/datetimelike.py": 394614958716301173, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/__init__.py": 15130871412783076140, + "frontend/src/routes/storage/+page.svelte": 5003283673039328108, + "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/numpy/lib/_user_array_impl.py": 13115032674230220791, + "backend/src/api/routes/git/_router.py": 8701683910668868827, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_einsum.py": 17286384318722237180, + "venv/lib/python3.13/site-packages/httpcore/_async/connection.py": 2155744160496556069, + "venv/bin/websockets": 12099863324306500376, + "dist/docker/frontend.v1.0.0-rc2-docker.tar": 1705027241971137937, + "venv/lib/python3.13/site-packages/psycopg2/errors.py": 10441360078612452560, + "venv/lib/python3.13/site-packages/_pytest/capture.py": 17850967053989495422, + "venv/lib/python3.13/site-packages/apscheduler/jobstores/sqlalchemy.py": 811968833735951956, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/random.py": 12722750410117529986, + "venv/lib/python3.13/site-packages/passlib/apache.py": 2357244937629445006, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_combine_first.py": 3100691245280812910, + "frontend/src/components/llm/ValidationReport.svelte": 11810571826279890996, + "venv/lib/python3.13/site-packages/pyasn1/codec/streaming.py": 13202773554072937140, + "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/tools.py": 6437315459200419827, + "venv/lib/python3.13/site-packages/pandas/_testing/_warnings.py": 5640964566228306285, + "venv/lib/python3.13/site-packages/pillow.libs/libsharpyuv-95d8a097.so.0.1.2": 5320647379976541240, + "venv/lib/python3.13/site-packages/pandas/io/sas/sasreader.py": 12766780210114366112, + "venv/lib/python3.13/site-packages/pygments/lexers/julia.py": 13516407944275342328, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/util.py": 5252158959761945519, + "venv/lib/python3.13/site-packages/pandas/tests/io/test_compression.py": 3167245427092658522, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/datasource.pyi": 80441145804744162, + "venv/lib/python3.13/site-packages/pandas/_libs/reshape.cpython-313-x86_64-linux-gnu.so": 10639750501333255943, + "venv/lib/python3.13/site-packages/pandas/core/array_algos/masked_reductions.py": 633644255158859565, + "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libselinux-0922c95c.so.1": 16516617710645376769, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_value_attrspec.py": 7741590618654448240, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/provision.py": 2676876852726658063, + "venv/lib/python3.13/site-packages/_pytest/terminalprogress.py": 5490989904517343259, + "docker/backend.entrypoint.sh": 16079402358996730188, + "backend/src/core/superset_profile_lookup.py": 7009220677319131100, + "frontend/src/lib/components/reports/reportTypeProfiles.js": 10752964062056890725, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_mangle_dupes.py": 15613858733226279352, + "venv/lib/python3.13/site-packages/urllib3/contrib/socks.py": 645086578806871685, + "venv/lib/python3.13/site-packages/pydantic/v1/color.py": 14545509649623975912, + "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/RECORD": 12555714734722889695, + "backend/logs/app.log.1": 5033969853318871181, + "venv/lib/python3.13/site-packages/anyio/lowlevel.py": 11919467357746648592, + "venv/lib/python3.13/site-packages/pip/_internal/commands/check.py": 6937252393012787214, + "venv/lib/python3.13/site-packages/pip/_vendor/distlib/compat.py": 17520043776344667309, + "venv/lib/python3.13/site-packages/numpy/lib/_shape_base_impl.pyi": 12052895927933479005, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/fromnumeric.pyi": 6708743411405679061, + "venv/lib/python3.13/site-packages/pygments/lexers/apl.py": 16767474673619335683, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ufunclike.pyi": 14623308681600207918, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/__init__.py": 15130871412783076140, + "frontend/src/routes/+page.svelte": 5766160745549070101, + "venv/lib/python3.13/site-packages/passlib/crypto/_blowfish/_gen_files.py": 6273314671315377131, + "venv/lib/python3.13/site-packages/PIL/McIdasImagePlugin.py": 14137545069906812251, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/negative_bounds/issue_20853.f90": 3911644649277659333, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7662/introspection.py": 14645217065508644154, + "venv/bin/activate.csh": 14513616043256836238, + "frontend/src/routes/settings/notifications/+page.svelte": 14504217413720856827, + "frontend/src/components/auth/ProtectedRoute.svelte": 7705373237339863677, + "venv/lib/python3.13/site-packages/numpy/random/tests/data/sfc64-testset-2.csv": 4052796393463357888, + "frontend/src/lib/components/layout/Breadcrumbs.svelte": 17883872226488804922, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/ranges.py": 14549386056660231279, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_umath_accuracy.py": 3904008607472505376, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_insert.py": 9195027887301180927, + "venv/lib/python3.13/site-packages/httpx/_transports/__init__.py": 5931944625631942279, + "venv/lib/python3.13/site-packages/apscheduler/util.py": 11440701924954413440, + "venv/lib/python3.13/site-packages/gitdb/db/__init__.py": 2615504918450276693, + "venv/lib/python3.13/site-packages/_pytest/_code/code.py": 5248836309618416369, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/base.py": 7110726987481713080, + "venv/lib/python3.13/site-packages/pip/__main__.py": 574438877257676911, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_concat.py": 1351478313334379336, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/writeonly.py": 14213960431308620600, + "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/toml.py": 2225382735669153136, + "venv/lib/python3.13/site-packages/numpy/strings/__init__.pyi": 6213864891045042045, + "venv/lib/python3.13/site-packages/pandas/io/formats/string.py": 14718123345899686696, + "venv/lib/python3.13/site-packages/pygments/lexers/csound.py": 2175454840368374515, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/Hamming.py": 3762934316884129514, + "venv/bin/httpx": 6651007446865716794, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/client.py": 18443944554871937480, + "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/RECORD": 8956798822782402202, + "venv/bin/pip3": 13861749540792881808, + "venv/lib/python3.13/site-packages/pandas/tests/generic/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_indexing.py": 16264430536704066847, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_append_common.py": 2377351120083195530, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/jupyter.py": 4446535289156468239, + "venv/lib/python3.13/site-packages/pandas/tseries/holiday.py": 1134358927599488799, + "venv/lib/python3.13/site-packages/uvicorn/protocols/utils.py": 6147480543268737542, + "venv/lib/python3.13/site-packages/pygments/lexers/_php_builtins.py": 2344562378679281201, + "venv/lib/python3.13/site-packages/pygments/lexers/esoteric.py": 16839499623020685146, + "backend/src/services/git/_merge.py": 16183885992149357137, + "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_box_unbox.py": 7579587620530953711, + "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/METADATA": 14126682758562488244, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/filesize.py": 13234856188049714485, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_sort.py": 11941630642630249576, + "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/signature.py": 3614545297259098566, + "venv/lib/python3.13/site-packages/numpy/ma/README.rst": 13203411621071845216, + "venv/lib/python3.13/site-packages/numpy/f2py/setup.cfg": 17974180080760231128, + "venv/lib/python3.13/site-packages/click/globals.py": 18353671282454331523, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_timezones.py": 4771674179164304731, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/mariadbconnector.py": 14865906347579451546, + "venv/lib/python3.13/site-packages/pygments/lexers/ldap.py": 17455983150181177257, + "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/WHEEL": 5838667082726674838, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/arrayprint.pyi": 2424868797160722318, + "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_numeric.py": 17391095502314929042, + "venv/lib/python3.13/site-packages/numpy/random/tests/data/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/core/computation/engines.py": 1889823242704769952, + "venv/lib/python3.13/site-packages/greenlet/greenlet_internal.hpp": 13173115501223013762, + "venv/lib/python3.13/site-packages/greenlet/TExceptionState.cpp": 17617354576371846109, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_constructors.py": 17392287676196409733, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_nlargest_nsmallest.py": 11049656379959696695, + "venv/lib/python3.13/site-packages/uvicorn/middleware/proxy_headers.py": 13206297306768491360, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_character/foo90.f90": 2435648607844815947, + "venv/lib/python3.13/site-packages/pandas/core/groupby/ops.py": 2036968385544457016, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_windows.py": 13341168721223961872, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_simd.py": 7577408467041941595, + "venv/lib/python3.13/site-packages/pandas/core/array_algos/putmask.py": 10934101690788549526, + "venv/lib/python3.13/site-packages/passlib/ifc.py": 14479133654556657428, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/shape.py": 13410030168622484801, + "venv/lib/python3.13/site-packages/numpy/strings/__init__.py": 6523674574341354095, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/__init__.py": 12975130533860125272, + "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_structures.py": 16375837477294135345, + "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_symbol.py": 10792387279408528886, + "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_xs.py": 11073752361562791165, + "venv/lib/python3.13/site-packages/pip/_internal/cli/autocompletion.py": 7651919329635563739, + "venv/lib/python3.13/site-packages/numpy/core/overrides.py": 11228841530565061867, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_sequence.py": 3721630758772772345, + "scripts/generate_financial_arrears_data.py": 15989529185799374517, + "venv/lib/python3.13/site-packages/pandas/core/computation/scope.py": 16859504937881548797, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/gh25337/data.f90": 13833561828029901615, + "frontend/src/lib/stores/environmentContext.js": 1762535408632658714, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/mapper.py": 16715864918034312591, + "frontend/build/_app/immutable/chunks/D9yKQnUv.js": 14194129519610241122, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/parsing.cpython-313-x86_64-linux-gnu.so": 13104135217735363438, + "frontend/build/_app/immutable/nodes/7.DPFqrug7.js": 12760418087468020149, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_x86_msvc.h": 2465089365642299646, + "venv/lib/python3.13/site-packages/pydantic/v1/_hypothesis_plugin.py": 6383299780629629080, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/datetimes/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/LICENSE": 11167201188673981085, + "venv/lib/python3.13/site-packages/urllib3/util/response.py": 6106698559175827207, + "frontend/vite.config.js": 6182424215365912367, + "frontend/src/lib/stores/sidebar.js": 8409084311045055153, + "backend/src/core/auth/jwt.py": 2300190538212143465, + "backend/src/api/routes/datasets.py": 10960880516483380521, + "venv/lib/python3.13/site-packages/numpy/f2py/cfuncs.pyi": 8232620851756907417, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/orderinglist.py": 10162099108656794338, + "venv/include/site/python3.13/greenlet/greenlet.h": 16216120538647882082, + "venv/lib/python3.13/site-packages/pandas/tests/io/xml/test_xml.py": 6906547816798138000, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_repr.py": 11737029058271003097, + "venv/lib/python3.13/site-packages/pygments/lexers/grammar_notation.py": 9009644754106884095, + "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/WHEEL": 9788895026336324100, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/arrayobject.h": 4345432890284821918, + "venv/lib/python3.13/site-packages/pygments/sphinxext.py": 2768161754523156130, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/assumed_shape/foo_use.f90": 2657057181044959432, + "venv/lib/python3.13/site-packages/websockets/legacy/http.py": 16266924390281399720, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/dtype.pyi": 465999539608816848, + "venv/lib/python3.13/site-packages/pygments/lexers/_ada_builtins.py": 16331776886501464264, + "venv/lib/python3.13/site-packages/httpcore/_backends/sync.py": 576247220834179928, + "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/WHEEL": 8600534672961461758, + "venv/lib/python3.13/site-packages/git/objects/tree.py": 10239027037919781330, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/__init__.py": 11526998905763262175, + "venv/lib/python3.13/site-packages/gitdb/test/test_util.py": 541144638852210407, + "venv/lib/python3.13/site-packages/pygments/lexers/shell.py": 3842338968014057744, + "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/keyring/backend_complete.zsh": 14339032329370660432, + "venv/lib/python3.13/site-packages/rsa/key.py": 4783269051050521475, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-exp.csv": 601782991752922510, + "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/METADATA": 14543822270526146783, + "venv/lib/python3.13/site-packages/rapidfuzz/__pyinstaller/test_rapidfuzz_packaging.py": 5189055608193366093, + "venv/lib/python3.13/site-packages/numpy/_utils/__init__.py": 7731065084036767848, + "venv/lib/python3.13/site-packages/uvicorn/lifespan/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pygments/lexers/_sql_builtins.py": 5906655440517434734, + "venv/lib/python3.13/site-packages/anyio/abc/_sockets.py": 15042495744291042062, + "venv/lib/python3.13/site-packages/attr/converters.pyi": 17675091788614033166, + "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/LICENSE": 8423899413955829149, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/jwe_encs.py": 9703572751543253904, + "venv/lib/python3.13/site-packages/numpy/_core/lib/pkgconfig/numpy.pc": 14713682399742251335, + "venv/lib/python3.13/site-packages/pandas/tests/window/moments/conftest.py": 6137462119729731945, + "docker/all-in-one.Dockerfile": 10896793266219904099, + "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/WHEEL": 2357997949040430835, + "venv/lib/python3.13/site-packages/cffi/cffi_opcode.py": 8411344362428947268, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_formats.py": 13500155167624433622, + "venv/lib/python3.13/site-packages/pip/_internal/utils/packaging.py": 15555781487631855604, + "venv/lib/python3.13/site-packages/ecdsa/ecdsa.py": 9770689913380927623, + "venv/lib/python3.13/site-packages/httpx/_transports/base.py": 6498990531443644896, + "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_construct_ndarray.py": 6863874753941288585, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_common.py": 12064185052519470358, + "venv/lib/python3.13/site-packages/greenlet/tests/__init__.py": 1181423074160870921, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_month.py": 8485374160446988786, + "venv/lib/python3.13/site-packages/pandas/tests/series/test_cumulative.py": 16283954014170928273, + "venv/lib/python3.13/site-packages/pycparser/_c_ast.cfg": 2649342580905806389, + "venv/lib/python3.13/site-packages/jaraco/classes/meta.py": 15930255620248873425, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_arrayterator.py": 1646530870049791291, + "venv/lib/python3.13/site-packages/cryptography/fernet.py": 10137792148038140630, + "venv/lib/python3.13/site-packages/sqlalchemy/engine/base.py": 6509914623926583629, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_replace.py": 8784361132920473760, + "venv/lib/python3.13/site-packages/numpy/random/tests/data/generator_pcg64_np126.pkl.gz": 9677994062701347206, + "venv/lib/python3.13/site-packages/tzlocal-5.3.1.dist-info/RECORD": 15574202654585730126, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/dictionary.py": 9599439750713575741, + "venv/lib/python3.13/site-packages/pygments/styles/autumn.py": 8750937312198920971, + "venv/lib/python3.13/site-packages/pygments/lexers/openscad.py": 13045825115225232396, + "venv/bin/py.test": 2593802493707545818, + "backend/src/core/__tests__/test_superset_preview_pipeline.py": 5338719285630543394, + "venv/lib/python3.13/site-packages/pygments/lexers/cplint.py": 13990118342267278047, + "backend/src/core/migration_engine.py": 1303635539349402052, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/selectable.py": 14646717349365560549, + "backend/src/services/git/_status.py": 8680190871452171795, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_s390_unix.h": 5161826643658505126, + "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/accessors.py": 12743680296510533030, + "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_coercion.py": 7261787308019145312, + "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_str_accessor.py": 4066094997616994612, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_comparison.py": 5348781442514871089, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/polynomial_polyutils.pyi": 3841660741524427413, + "venv/lib/python3.13/site-packages/git/compat.py": 16843345645628515492, + "venv/lib/python3.13/site-packages/apscheduler/schedulers/twisted.py": 16059862619165885730, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/__init__.py": 2345997696115514124, + "venv/lib/python3.13/site-packages/uvicorn/protocols/http/flow_control.py": 4822804840057360506, + "venv/lib/python3.13/site-packages/PIL/_avif.cpython-313-x86_64-linux-gnu.so": 5243449968857258659, + "backend/src/core/scheduler.py.bak": 15045927989195339728, + "venv/lib/python3.13/site-packages/keyring/backends/macOS/api.py": 4502902558534812719, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_between_time.py": 14266333058913745751, + "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/licenses/AUTHORS": 2987771679926243782, + "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_get.py": 6509102681661636928, + "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/WHEEL": 2357997949040430835, + "frontend/build/_app/immutable/chunks/CTtgwBHs.js": 9488056280956425328, + "venv/lib/python3.13/site-packages/py.py": 16248211404003181569, + "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/licenses/LICENSE.BSD": 16833702494864671773, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/warnings_and_errors.py": 11172336980866895356, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_explode.py": 18263694040596159591, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_construction.py": 13953424340346625390, + "venv/lib/python3.13/site-packages/pandas/tests/io/sas/test_xport.py": 14080914637071212225, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/getlimits.pyi": 93747984191461691, + "venv/lib/python3.13/site-packages/numpy/lib/_index_tricks_impl.py": 13574106461973044500, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_indexing.py": 4334578480714520407, + "venv/lib/python3.13/site-packages/jeepney/io/asyncio.py": 13239992245695516007, + "venv/lib/python3.13/site-packages/pillow.libs/liblcms2-cc10e42f.so.2.0.17": 4221600618602131476, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/backports/weakref_finalize.py": 7019253290755243568, + "venv/lib/python3.13/site-packages/pydantic/annotated_handlers.py": 10186120300163345360, + "venv/lib/python3.13/site-packages/authlib/common/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/histograms.pyi": 9255620158831643201, + "venv/lib/python3.13/site-packages/pandas/core/interchange/from_dataframe.py": 8278998381856028462, + "venv/lib/python3.13/site-packages/pandas/tests/io/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/multipart/multipart.py": 26386459953377432, + "venv/lib/python3.13/site-packages/pyasn1/type/char.py": 16518487114777185541, + "backend/src/core/utils/fileio.py": 5783081738676692209, + "backend/src/api/routes/mappings.py": 7071183920129492341, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/crud.py": 805684028038896506, + "venv/lib/python3.13/site-packages/pydantic_core/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_validate_inclusive.py": 1389676378885557519, + "venv/lib/python3.13/site-packages/pandas/tests/series/test_reductions.py": 2816859231048302619, + "venv/lib/python3.13/site-packages/sqlalchemy/future/__init__.py": 17688444679736059779, + "backend/src/services/auth_service.py": 17642785219801916280, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/kbkdf.py": 1359143503575245224, + "venv/lib/python3.13/site-packages/requests/__version__.py": 6677532709758546816, + "venv/lib/python3.13/site-packages/cryptography/x509/name.py": 15338066443257445241, + "venv/lib/python3.13/site-packages/pygments/filter.py": 16846063190466267618, + "venv/lib/python3.13/site-packages/fastapi/requests.py": 14587947416691824903, + "venv/lib/python3.13/site-packages/numpy/testing/overrides.py": 11819432487830192978, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_shift.py": 9952689832827833247, + "venv/lib/python3.13/site-packages/numpy/fft/_pocketfft.py": 6142062990691556076, + "venv/lib/python3.13/site-packages/pandas/io/formats/__init__.py": 18140261896107421679, + "venv/lib/python3.13/site-packages/certifi/__main__.py": 13417658012431779061, + "venv/lib/python3.13/site-packages/pygments/lexers/math.py": 1647133236144311250, + "venv/lib/python3.13/site-packages/numpy/_core/shape_base.py": 3996519099530770308, + "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/env.py": 1254612137164491329, + "venv/lib/python3.13/site-packages/pandas/core/arrays/numeric.py": 17834058423729918687, + "venv/lib/python3.13/site-packages/pandas/_libs/ops_dispatch.cpython-313-x86_64-linux-gnu.so": 5284769758475394095, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_numpy.py": 222383250675686477, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame_subplots.py": 4596089143375088346, + "venv/lib/python3.13/site-packages/httpx/_transports/wsgi.py": 11981127094916412794, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/rsa.pyi": 13850254283540522444, + "venv/lib/python3.13/site-packages/jsonschema/cli.py": 9813914882090789748, + "venv/lib/python3.13/site-packages/h11/py.typed": 12358286306858197118, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_utils.py": 15197339054699289627, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/LCSseq_py.py": 16054175754674285311, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/__init__.py": 2397613800206300456, + "venv/lib/python3.13/site-packages/pydantic_settings/__init__.py": 4374954204580208673, + "venv/lib/python3.13/site-packages/numpy/typing/mypy_plugin.py": 1306129775649200113, + "venv/lib/python3.13/site-packages/jsonschema/tests/test_validators.py": 14178329676643700151, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_records.py": 18167578114159312327, + "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/array.py": 12658302948819867972, + "venv/lib/python3.13/site-packages/cryptography/x509/general_name.py": 4481582226129488535, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_conversion_utils.py": 1567199588622767277, + "venv/lib/python3.13/site-packages/pandas/errors/cow.py": 14381282473643980776, + "venv/lib/python3.13/site-packages/greenlet/TThreadStateDestroy.cpp": 13749797532421836328, + "venv/lib/python3.13/site-packages/pandas/tests/test_downstream.py": 5635510753354256507, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_pickle.py": 388513670243918273, + "venv/lib/python3.13/site-packages/greenlet/tests/test_greenlet_trash.py": 6191655521667576604, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/object/test_astype.py": 563689238486630866, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/Levenshtein_py.py": 11350239659973489646, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_sample.py": 4641567828238191927, + "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/lib/_arraypad_impl.py": 6348811074249398741, + "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/zip-safe": 15240312484046875203, + "venv/lib/python3.13/site-packages/rapidfuzz/__init__.pyi": 13131938031654453415, + "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/WHEEL": 16097436423493754389, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_parameter.py": 15173522343126004527, + "venv/lib/python3.13/site-packages/_pytest/_code/__init__.py": 6211607282116942091, + "venv/lib/python3.13/site-packages/pandas/_libs/testing.cpython-313-x86_64-linux-gnu.so": 16758333404587340103, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_numba.py": 1668304729617150075, + "venv/lib/python3.13/site-packages/attrs/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/common.py": 2075178842766962782, + "venv/lib/python3.13/site-packages/authlib/integrations/flask_client/integration.py": 12670848015915724967, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_concatenate_chunks.py": 9693420220003544490, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_droplevel.py": 2071197388394658690, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_array.py": 11271807719833350332, + "venv/lib/python3.13/site-packages/websockets/sync/server.py": 7966978001578584901, + "venv/lib/python3.13/site-packages/PIL/PngImagePlugin.py": 5076219228736706283, + "venv/lib/python3.13/site-packages/PIL/PalmImagePlugin.py": 13008868719182630239, + "venv/lib/python3.13/site-packages/jeepney-0.9.0.dist-info/METADATA": 15225661995655327539, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/align.py": 6078666505647454830, + "venv/lib/python3.13/site-packages/pygments/lexers/igor.py": 6506221273085723501, + "venv/lib/python3.13/site-packages/urllib3/util/connection.py": 15511685694589961094, + "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/METADATA": 15987199384245264478, + "venv/lib/python3.13/site-packages/numpy/fft/tests/test_helper.py": 5362180645056413158, + "venv/lib/python3.13/site-packages/PIL/_imagingtk.pyi": 18222325750818585549, + "venv/lib/python3.13/site-packages/httpcore/_synchronization.py": 10997080307461682786, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_interpolate.py": 6154072863387383113, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_bar.py": 7791068963246005463, + "venv/lib/python3.13/site-packages/pycparser/ply/ygen.py": 5520340773074632724, + "venv/lib/python3.13/site-packages/starlette/exceptions.py": 15978811612997200737, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_map.py": 32086858815359344, + "venv/lib/python3.13/site-packages/pygments/lexers/html.py": 17288963642862550116, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_finfo.py": 17174674209412768422, + "venv/lib/python3.13/site-packages/git/repo/__init__.py": 6173604284490891047, + "venv/lib/python3.13/site-packages/pygments/lexers/solidity.py": 5071425960622305629, + "frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js": 15091004230843271151, + "frontend/src/components/Navbar.svelte": 12353588862181566761, + "frontend/build/_app/immutable/nodes/3.TrEd7Loa.js": 18117679530551903771, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/modules.pyi": 131293606732000587, + "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py": 5995058808539530576, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_hour.py": 13754646634123368797, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/test_observance.py": 18178414966262524534, + "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_musllinux.py": 2423350951094915747, + "frontend/build/_app/immutable/chunks/DOxI2NAm.js": 11236647372068635428, + "backend/src/core/auth/oauth.py": 9925908783612235042, + "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/numpy/ma/tests/test_old_ma.py": 18116460138221458026, + "venv/lib/python3.13/site-packages/rapidfuzz/_utils.py": 14374663810542207121, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/polynomial_series.pyi": 7112486730197067087, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_equals.py": 9405821443172167066, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/reflection.py": 1799734694597531652, + "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_setitem.py": 15731267129055947469, + "venv/lib/python3.13/site-packages/pygments/lexers/pony.py": 2720635393743617141, + "venv/lib/python3.13/site-packages/pandas/api/typing/__init__.py": 6438268275857060114, + "venv/lib/python3.13/site-packages/numpy/random/tests/__init__.py": 15130871412783076140, + "merge_kilo.py": 4282227344165325430, + "venv/lib/python3.13/site-packages/greenlet/greenlet_cpython_compat.hpp": 8396413256279803400, + "venv/lib/python3.13/site-packages/numpy/typing/tests/test_isfile.py": 14544060093268573418, + "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pip/_vendor/tomli_w/_writer.py": 15053365792216907149, + "venv/lib/python3.13/site-packages/numpy/_core/numerictypes.pyi": 12144531601504755948, + "venv/lib/python3.13/site-packages/numpy/ctypeslib/__init__.pyi": 13208953770241664384, + "venv/lib/python3.13/site-packages/pandas/core/indexes/interval.py": 17965911911189276907, + "venv/lib/python3.13/site-packages/pandas/tests/frame/test_stack_unstack.py": 3737891757817696405, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_converter.py": 7709581879446228856, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_partial_indexing.py": 4132091154215910029, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_shift.py": 14026124784027171225, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_validate_args.py": 5821040955806257450, + "venv/lib/python3.13/site-packages/starlette/middleware/authentication.py": 15211131264936212938, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/einsumfunc.pyi": 200771351328522379, + "venv/lib/python3.13/site-packages/numpy/_pyinstaller/hook-numpy.py": 5221550291012182443, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/fields.cpython-313-x86_64-linux-gnu.so": 16927263232848238698, + "venv/lib/python3.13/site-packages/fastapi/middleware/__init__.py": 5289703478893407762, + "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_polynomial.py": 777287409151500309, + "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/macos.py": 17442393555211213147, + "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/METADATA": 13695483537390128881, + "venv/lib/python3.13/site-packages/pandas/tests/strings/test_strings.py": 17398806130402098912, + "venv/lib/python3.13/site-packages/numpy/f2py/__init__.py": 7470157159992827389, + "venv/lib/python3.13/site-packages/pip/_vendor/distlib/locators.py": 7638945613579396718, + "venv/lib/python3.13/site-packages/pip/_internal/models/direct_url.py": 4619204214785230341, + "venv/lib/python3.13/site-packages/pandas/compat/pickle_compat.py": 11073483984394766474, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_astype.py": 11386658862732393123, + "venv/lib/python3.13/site-packages/websockets/asyncio/router.py": 15039562376314233669, + "venv/lib/python3.13/site-packages/numpy/random/lib/libnpyrandom.a": 1802449692091040396, + "venv/lib/python3.13/site-packages/secretstorage/defines.py": 9590959702075554048, + "venv/lib/python3.13/site-packages/passlib/handlers/cisco.py": 15004707325761459775, + "venv/lib/python3.13/site-packages/pandas/plotting/_core.py": 6766059152026241747, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_attr_equal.py": 5612259834202470413, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_construction.py": 6564829381134214401, + "venv/lib/python3.13/site-packages/httpx/_urls.py": 4219389176352582046, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/hmac.py": 18132740541139891824, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/nested_sequence.pyi": 10985533017688918283, + "venv/lib/python3.13/site-packages/pandas/testing.py": 18352975429944961593, + "venv/lib/python3.13/site-packages/urllib3/util/ssl_.py": 11720964010284185952, + "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/RECORD": 16874983218652404911, + "venv/lib/python3.13/site-packages/numpy/random/c_distributions.pxd": 16574161095720077595, + "venv/lib/python3.13/site-packages/pygments/styles/gh_dark.py": 7717523746712391809, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_period.py": 9715843209581883915, + "venv/lib/python3.13/site-packages/pygments/lexers/_vim_builtins.py": 6842381248727719900, + "venv/lib/python3.13/site-packages/pandas/core/arrays/sparse/__init__.py": 6758781485387665020, + "venv/lib/python3.13/site-packages/fastapi/openapi/docs.py": 16735218221639179927, + "venv/lib/python3.13/site-packages/pandas/tests/base/test_value_counts.py": 9352540710376306520, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_sorting.py": 10523740688498427929, + "venv/lib/python3.13/site-packages/charset_normalizer/cd.py": 8687667152597941021, + "frontend/src/routes/settings/__tests__/settings_page.integration.test.js": 13008989176397099996, + "frontend/src/components/RepositoryDashboardGrid.svelte": 17100594220040865069, + "frontend/build/_app/immutable/chunks/BURGrVTR.js": 9373329903010633175, + "backend/src/core/superset_client/_dashboards_list.py": 16574697057051064609, + "backend/src/core/plugin_base.py": 11649432288706102843, + "backend/src/models/config.py": 7631082065091961320, + "backend/src/services/reports/type_profiles.py": 8365014439236739390, + "venv/lib/python3.13/site-packages/pygments/lexers/q.py": 15426466074881683794, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7519/jwt.py": 9642615960197748105, + "venv/lib/python3.13/site-packages/idna/idnadata.py": 200840860629525970, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/arithmetic.pyi": 10265823318697442495, + "venv/lib/python3.13/site-packages/httpx/_status_codes.py": 1758440600462491839, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/comparisons.pyi": 9338084426044982038, + "venv/lib/python3.13/site-packages/jaraco/context/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/_pytest/warning_types.py": 10695097290648045427, + "venv/lib/python3.13/site-packages/numpy/random/tests/test_randomstate.py": 11205714006000849926, + "venv/lib/python3.13/site-packages/keyring/compat/__init__.py": 7578020229796085753, + "venv/lib/python3.13/site-packages/numpy/dtypes.py": 14128421398870718692, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/common.py": 16314033415206173235, + "venv/lib/python3.13/site-packages/pandas/io/spss.py": 864838144958947906, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/random.pyi": 1808392097712315455, + "venv/lib/python3.13/site-packages/anyio/to_interpreter.py": 8369454842687342401, + "frontend/src/lib/components/reports/ReportDetailPanel.svelte": 16014663571033060148, + "venv/lib/python3.13/site-packages/pandas/_libs/internals.cpython-313-x86_64-linux-gnu.so": 2008633361686956377, + "backend/src/services/clean_release/repositories/publication_repository.py": 11208425895213508165, + "backend/src/services/reports/__init__.py": 11818812865847046400, + "venv/lib/python3.13/site-packages/httpx/_content.py": 1301854837767395687, + "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/RECORD": 1051307407005554409, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/jwe_zips.py": 5184894018177148648, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/lower_f2py_fortran.f90": 13315882216322269383, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/wrappers.py": 315409799569602977, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/bitwise_ops.pyi": 15598239133239520456, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_analytics.py": 4510712334676848202, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalar_ctors.py": 631744056514965940, + "venv/lib/python3.13/site-packages/pandas/core/interchange/column.py": 9498044216416177656, + "venv/lib/python3.13/site-packages/pydantic/_internal/_signature.py": 17075003201648027250, + "venv/lib/python3.13/site-packages/numpy/f2py/auxfuncs.pyi": 10077265709692546934, + "venv/lib/python3.13/site-packages/dotenv/parser.py": 17651523026132242005, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh24662.f90": 4241310200087270990, + "venv/lib/python3.13/site-packages/pandas/_libs/indexing.cpython-313-x86_64-linux-gnu.so": 13188040757764159731, + "venv/lib/python3.13/site-packages/pandas/core/computation/parsing.py": 3084943521520476999, + "venv/lib/python3.13/site-packages/pandas/core/indexers/__init__.py": 1756397319068017890, + "venv/lib/python3.13/site-packages/pydantic/v1/parse.py": 5875950480538559709, + "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/validation": 13992741783834278677, + "venv/lib/python3.13/site-packages/pyasn1/codec/ber/encoder.py": 8912119133548489544, + "venv/lib/python3.13/site-packages/pip/_vendor/requests/api.py": 12339139862411341381, + "venv/lib/python3.13/site-packages/pandas/core/methods/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8414/models.py": 3567900447243180991, + "venv/lib/python3.13/site-packages/git/index/util.py": 5022401275553420722, + "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/METADATA": 12747626683405487434, + "venv/lib/python3.13/site-packages/numpy/lib/introspect.py": 5706729538356302335, + "venv/lib/python3.13/site-packages/uvicorn/__init__.py": 11517239807926185665, + "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/RECORD": 9964194961227523130, + "venv/lib/python3.13/site-packages/pygments/lexers/usd.py": 934820244673741695, + "venv/lib/python3.13/site-packages/numpy/lib/scimath.py": 7616377937400918724, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/ccalendar.cpython-313-x86_64-linux-gnu.so": 11019871270094058038, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/twofactor/hotp.py": 18325640697829098192, + "venv/lib/python3.13/site-packages/charset_normalizer/md.py": 2029760700380476138, + "frontend/src/lib/stores.js": 8062876368729352764, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/size/foo.f90": 18067977329435720684, + "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/cython/checks.pyx": 13187505236986855177, + "frontend/src/components/TaskList.svelte": 13727273029173605651, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/dependency.py": 7300594038182867460, + "venv/lib/python3.13/site-packages/PIL/ImageTransform.py": 7825940907094338808, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/containers.py": 5969831151685016772, + "venv/lib/python3.13/site-packages/urllib3/fields.py": 9503202008440141421, + "venv/lib/python3.13/site-packages/pandas/tests/strings/test_find_replace.py": 262184394614748386, + "venv/lib/python3.13/site-packages/urllib3/http2/probe.py": 4069929463671970243, + "venv/lib/python3.13/site-packages/pandas/tests/extension/list/__init__.py": 10072943986583771248, + "venv/lib/python3.13/site-packages/git/index/typ.py": 11661540784850363024, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/fixtures/orm.py": 7554417559838785150, + "venv/lib/python3.13/site-packages/pydantic/deprecated/decorator.py": 8609500261161560793, + "venv/lib/python3.13/site-packages/pandas/tests/resample/test_datetime_index.py": 15448494560143263150, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ndarray_conversion.py": 6205112277291935767, + "venv/lib/python3.13/site-packages/pandas/tests/test_errors.py": 10116716310156374885, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/conftest.py": 13388202260795998613, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_scalar_compat.py": 10534925655070162459, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_constructors.py": 7466113171256856591, + "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/WHEEL": 7795541085444298627, + "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/style.py": 15214295655795348821, + "venv/lib/python3.13/site-packages/pandas/io/iceberg.py": 13137128885014736233, + "venv/lib/python3.13/site-packages/uvicorn/supervisors/statreload.py": 5018382301336802445, + "venv/lib/python3.13/site-packages/pygments/lexers/resource.py": 8057351545636349791, + "frontend/build/_app/immutable/nodes/6.CQhNV4xO.js": 10554106729411192187, + "backend/src/core/scheduler.py": 2472649939852521889, + "backend/src/services/clean_release/__tests__/test_policy_engine.py": 9953185933720550640, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_pick.py": 15760492005471315814, + "frontend/build/_app/immutable/chunks/BrvzRogk.js": 16712439889682616806, + "venv/lib/python3.13/site-packages/psycopg2/__init__.py": 15798412693009721199, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh17797.f90": 17319074662077763768, + "venv/lib/python3.13/site-packages/pydantic/_migration.py": 17982816821930887921, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/asn1.pyi": 16048852379621461316, + "venv/lib/python3.13/site-packages/referencing/jsonschema.py": 14596871117484757502, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/Jaro_py.py": 11991492232381887787, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_indexing.py": 14717641281147152159, + "venv/lib/python3.13/site-packages/pandas/tests/extension/base/index.py": 15694995431926521471, + "venv/lib/python3.13/site-packages/annotated_doc/__init__.py": 6834198874252778425, + "venv/lib/python3.13/site-packages/pandas/tests/test_flags.py": 411845322592830527, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_indexing.py": 5910217172351020811, + "venv/lib/python3.13/site-packages/PIL/GbrImagePlugin.py": 7681313333602257802, + "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/RECORD": 17341460504914308184, + "backend/src/core/superset_client/__init__.py": 6869599313455380203, + "backend/src/api/__init__.py": 5287505122015708040, + "backend/src/services/git/_branch.py": 7552472942680784566, + "frontend/build/_app/immutable/chunks/2dOUpm6k.js": 11811637653151731489, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_header.py": 3564391095263545879, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_rewrite_warning.py": 4895919872954538758, + "backend/src/api/routes/dashboards/_schemas.py": 10686942001147126057, + "frontend/src/routes/dashboards/[id]/components/DashboardHeader.svelte": 5572977872383619871, + "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/licenses/LICENSE.BSD": 3858254215169937333, + "venv/lib/python3.13/site-packages/httpx/_api.py": 6697370469329778523, + "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/serialize.py": 11139432164346742421, + "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_regression.py": 16266600037241221681, + "venv/lib/python3.13/site-packages/pandas/core/arrays/masked.py": 13977195666947626206, + "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth1/cache.py": 15037055977924167732, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_pickle.py": 16196792378104396231, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/tzconversion.pyi": 10947021928755741366, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_emoji_replace.py": 8166203537440976347, + "venv/lib/python3.13/site-packages/pip/_internal/req/req_uninstall.py": 3515239440812977025, + "venv/lib/python3.13/site-packages/pyasn1/codec/native/encoder.py": 120921270972591880, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_astype.py": 4178231007649608531, + "frontend/src/lib/api/reports.js": 2328857814720054000, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/Levenshtein.pyi": 12925006572914814268, + "venv/lib/python3.13/site-packages/pip/_internal/cli/spinners.py": 7664056305019151182, + "venv/lib/python3.13/site-packages/authlib/integrations/base_client/async_openid.py": 8708980645667847439, + "venv/lib/python3.13/site-packages/authlib/oauth1/__init__.py": 3692257288065292607, + "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/types.py": 1343652083039949282, + "venv/lib/python3.13/site-packages/pydantic/v1/class_validators.py": 6471688474853407718, + "venv/lib/python3.13/site-packages/httpx/__init__.py": 6383055693166097719, + "venv/lib/python3.13/site-packages/_pytest/config/exceptions.py": 3199245296954654462, + "venv/lib/python3.13/site-packages/fastapi/dependencies/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pillow.libs/libbrotlicommon-c55a5f7a.so.1.2.0": 2635192149914499986, + "venv/lib/python3.13/site-packages/pandas/tests/frame/test_arrow_interface.py": 5231449831607036031, + "venv/lib/python3.13/site-packages/charset_normalizer/legacy.py": 1706599349563920562, + "frontend/src/lib/auth/__tests__/permissions.test.js": 13555349356008297952, + "venv/lib/python3.13/site-packages/_pytest/reports.py": 13930709338396699351, + "venv/lib/python3.13/site-packages/pycparser/c_lexer.py": 10964496587169353564, + "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/immutabledict.cpython-313-x86_64-linux-gnu.so": 12776951671822017500, + "backend/src/models/__tests__/test_models.py": 15975002719327784362, + "backend/src/services/git/_remote_providers.py": 12661659133898682960, + "venv/lib/python3.13/site-packages/psycopg2/sql.py": 18041240927130590808, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/value_attrspec/gh21665.f90": 11945588837236968550, + "venv/lib/python3.13/site-packages/passlib/handlers/mysql.py": 11165762635383041460, + "venv/lib/python3.13/site-packages/pandas/io/feather_format.py": 13242733585787888812, + "venv/lib/python3.13/site-packages/pygments/lexers/gdscript.py": 12775803139854052838, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_deprecations.py": 16124509063246256847, + "venv/lib/python3.13/site-packages/yaml/cyaml.py": 9157893742065554693, + "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/assertion_client.py": 4261295109880943573, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/table.py": 16856253349556498073, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_simd_module.py": 7122050193390298178, + "venv/lib/python3.13/site-packages/pandas/tests/io/xml/test_xml_dtypes.py": 18293138335799308439, + "venv/lib/python3.13/site-packages/pygments/lexers/business.py": 10410439210806697214, + "venv/lib/python3.13/site-packages/pip/_internal/__init__.py": 7060345458485901709, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/unicode_comment.f90": 11326797716215117266, + "venv/bin/pygmentize": 2166491742035772877, + "venv/lib/python3.13/site-packages/pydantic/generics.py": 15019381413806459410, + "venv/lib/python3.13/site-packages/pandas/_libs/properties.pyi": 9268470215750269699, + "venv/lib/python3.13/site-packages/keyring/backend_complete.bash": 16589214602970214174, + "venv/lib/python3.13/site-packages/keyring/backends/fail.py": 5792496235026678021, + "venv/lib/python3.13/site-packages/dotenv/variables.py": 5438726379749803751, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_isetitem.py": 14895552405828068177, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/__init__.py": 16434403703599680307, + "venv/lib/python3.13/site-packages/pygments/lexers/maxima.py": 11824576541091274641, + "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/unevaluated": 11193150813314469394, + "venv/lib/python3.13/site-packages/pygments/lexers/smv.py": 8253688483040957894, + "venv/lib/python3.13/site-packages/pandas/_libs/reshape.pyi": 88721900806893992, + "frontend/build/_app/immutable/chunks/BG4NfqIk.js": 6096001408084116703, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/json.py": 14738429697319670035, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/_collections.py": 14307204206312829238, + "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_where.py": 14167991754625133668, + "venv/lib/python3.13/site-packages/pip/_vendor/distro/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/core/shared_docs.py": 2173578869755325502, + "frontend/build/_app/immutable/chunks/BoOsFBJ0.js": 11874060117929105318, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/interval/test_interval.py": 18040371224712437126, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/numerictypes.py": 5719374287454872555, + "venv/lib/python3.13/site-packages/numpy/_core/_ufunc_config.py": 7365943844063702766, + "venv/lib/python3.13/site-packages/numpy/_core/_internal.pyi": 6840742333427164920, + "venv/lib/python3.13/site-packages/gitdb/test/test_pack.py": 7518388297247535189, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/rec.pyi": 14615751247243515028, + "venv/lib/python3.13/site-packages/pandas/core/computation/expressions.py": 10684284531040203747, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_ipython_compat.py": 12632271159842988561, + "backend/src/core/middleware/trace.py": 13093835356377196397, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_fillna.py": 8802093795040069423, + "venv/lib/python3.13/site-packages/pip/_vendor/distlib/database.py": 7111764828004587758, + "venv/lib/python3.13/site-packages/pandas/tests/extension/base/ops.py": 13451323660386712332, + "venv/lib/python3.13/site-packages/greenlet/tests/_test_extension.c": 9318655518998644962, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_null_file.py": 6885565068723353414, + "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_distutils.pyi": 3595910367556664837, + "venv/lib/python3.13/site-packages/dotenv/ipython.py": 15904966766060247908, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_indexing_slow.py": 12558235638488427077, + "venv/lib/python3.13/site-packages/pip/_internal/operations/install/__init__.py": 10456333337205488584, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/connectionpool.py": 10453724680327835821, + "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/timeseries.py": 17641722582848932332, + "venv/lib/python3.13/site-packages/pandas/io/pytables.py": 17482934215513855928, + "venv/lib/python3.13/site-packages/pygments/lexers/pawn.py": 18127303119414402594, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_clip.py": 13498704233745189154, + "venv/lib/python3.13/site-packages/pandas/core/indexes/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pydantic/v1/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7592/__init__.py": 1398617034174236358, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ndarray_conversion.pyi": 11580106670226366710, + "venv/lib/python3.13/site-packages/pygments/styles/paraiso_dark.py": 3976779833379189837, + "frontend/src/routes/profile/__tests__/fixtures/profile.fixtures.js": 2726190101012864209, + "backend/src/services/dataset_review/orchestrator.py": 8780497744077644822, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/base.cpython-313-x86_64-linux-gnu.so": 8335798324308957127, + "venv/lib/python3.13/site-packages/httpcore/_sync/socks_proxy.py": 4418971149260853240, + "venv/lib/python3.13/site-packages/passlib/crypto/_blowfish/unrolled.py": 12651425412640834530, + "venv/lib/python3.13/site-packages/numpy/__config__.py": 15794735729525094396, + "venv/lib/python3.13/site-packages/apscheduler/triggers/base.py": 1170652622104554892, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/Levenshtein.py": 15426828792217499138, + "venv/lib/python3.13/site-packages/pandas/tests/libs/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pydantic/class_validators.py": 4643597082531287188, + "venv/lib/python3.13/site-packages/pip/_internal/models/scheme.py": 4101322315594430874, + "venv/lib/python3.13/site-packages/fastapi/_compat/main.py": 13016492818231995760, + "venv/lib/python3.13/site-packages/websockets/client.py": 5229500079651465772, + "venv/lib/python3.13/site-packages/fastapi/middleware/wsgi.py": 3706578020491442104, + "venv/lib/python3.13/site-packages/more_itertools/__init__.pyi": 16479506520351014608, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/ec_key.py": 5961540064444749833, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/util.py": 387985965709546512, + "venv/lib/python3.13/site-packages/pandas/core/reshape/merge.py": 300205528811693975, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/revocation.py": 5718403706971163960, + "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_parser.py": 8145921552236189367, + "venv/lib/python3.13/site-packages/pydantic/warnings.py": 5142352784799639092, + "venv/lib/python3.13/site-packages/pygments/lexers/arturo.py": 4565524340706235725, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_ndarray_backed.py": 10097812802469682233, + "venv/lib/python3.13/site-packages/numpy/_pyinstaller/hook-numpy.pyi": 14233146512272397376, + "frontend/src/lib/components/dataset-review/CompiledSQLPreview.svelte": 14788599185006992431, + "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/format": 12697928260201325593, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_series.py": 17126297747681689408, + "backend/src/plugins/translate/executor.py": 16483493819862607738, + "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/LICENSE": 6774760218010069963, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/response.py": 15004896908941411698, + "venv/lib/python3.13/site-packages/pandas/tests/window/test_rolling_skew_kurt.py": 15225601437354712351, + "backend/src/api/routes/__tests__/test_datasets.py": 14530822388357135497, + "venv/lib/python3.13/site-packages/numpy/lib/_type_check_impl.py": 15989335816452913951, + "venv/lib/python3.13/site-packages/numpy/core/umath.py": 4476812261188108155, + "venv/lib/python3.13/site-packages/httpx/_decoders.py": 14478643473006178492, + "venv/lib/python3.13/site-packages/starlette/routing.py": 16063812008141874150, + "venv/lib/python3.13/site-packages/pydantic/_internal/_model_construction.py": 694471028676746110, + "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/passlib/handlers/windows.py": 8969739861295277439, + "venv/lib/python3.13/site-packages/PIL/_tkinter_finder.py": 14045496501810535432, + "venv/lib/python3.13/site-packages/pygments/lexers/forth.py": 17623561228839319663, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/routines/subrout.pyf": 4660465266594480405, + "frontend/src/components/MappingTable.svelte": 3101497452073042168, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/x448.py": 3960540415600165213, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_indexing.py": 8943385096811168079, + "frontend/build/_app/immutable/chunks/CbSNjLmH.js": 12377182002440958587, + "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/models.py": 15928924478695638423, + "venv/lib/python3.13/site-packages/pip/_vendor/packaging/__init__.py": 96341051676048910, + "venv/lib/python3.13/site-packages/pyasn1/codec/ber/decoder.py": 12653470212935324322, + "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/sqlalchemy/engine/_py_processors.py": 16557117595879208702, + "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/wsproto_impl.py": 3072714633272661847, + "venv/lib/python3.13/site-packages/yaml/constructor.py": 8731384179016992045, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/pyodbc.py": 8175468565413744516, + "venv/lib/python3.13/site-packages/attr/validators.py": 4453080662115911998, + "venv/lib/python3.13/site-packages/jose/jws.py": 11592462993417182096, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/testing.pyi": 9317922890783549326, + "venv/lib/python3.13/site-packages/pandas/_libs/sparse.cpython-313-x86_64-linux-gnu.so": 2051484129454294720, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/ccalendar.pyi": 15789956857032062129, + "venv/lib/python3.13/site-packages/pandas/tests/libs/test_join.py": 5982692266872978444, + "venv/lib/python3.13/site-packages/pygments/styles/paraiso_light.py": 15941591873059208999, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_subclass.py": 12453252499544981915, + "frontend/src/lib/stores/__tests__/assistantChat.test.js": 11822882112255142537, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_pytables_missing.py": 12154582133989896069, + "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/groupby.py": 14661033005768429774, + "venv/lib/python3.13/site-packages/pydantic/_internal/_known_annotated_metadata.py": 9308620143218174987, + "venv/lib/python3.13/site-packages/pandas/_libs/join.cpython-313-x86_64-linux-gnu.so": 2947947484481830203, + "venv/lib/python3.13/site-packages/urllib3-2.6.2.dist-info/WHEEL": 7454950858448014158, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_halfyear.py": 9376272342364384767, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/abstract_interface/foo.f90": 14491312943942432024, + "venv/lib/python3.13/site-packages/pydantic_settings/sources/__init__.py": 7062045842767697645, + "venv/lib/python3.13/site-packages/numpy/random/_bounded_integers.pyi": 14150710436003340771, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/gh25337/use_data.f90": 14624074967635860696, + "venv/lib/python3.13/site-packages/starlette/websockets.py": 13834731343216764204, + "venv/lib/python3.13/site-packages/numpy/_core/_add_newdocs_scalars.py": 652332294655046106, + "venv/lib/python3.13/site-packages/pandas/core/array_algos/__init__.py": 11850945878149145990, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh22648.pyf": 15094859289098837494, + "venv/lib/python3.13/site-packages/pip/_vendor/idna/intranges.py": 12536174834761591006, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/events.py": 10224214051422678828, + "venv/lib/python3.13/site-packages/PIL/ContainerIO.py": 7551929914241379005, + "venv/lib/python3.13/site-packages/pygments/lexers/asm.py": 13861952972248758785, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_at.py": 1029744344133153888, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_hashtable.py": 2620207240930665390, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/period.pyi": 13110894861187422750, + "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/oauth1_session.py": 1911069558956893789, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_truncate.py": 9623613657871046837, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/mysqldb.py": 2138006249556140141, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_reductions.py": 3575617237516305456, + "frontend/src/components/tools/ConnectionList.svelte": 15981533028345710336, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh2848.f90": 5799106109999071412, + "venv/lib/python3.13/site-packages/pandas/tests/extension/decimal/test_decimal.py": 17811784255174057561, + "backend/src/api/routes/git/__init__.py": 9989336734947065016, + "venv/lib/python3.13/site-packages/httpcore/_backends/auto.py": 10488908050307887802, + "venv/lib/python3.13/site-packages/greenlet/greenlet_allocator.hpp": 11041111583319491309, + "venv/lib/python3.13/site-packages/pandas/core/dtypes/missing.py": 11241703105777668183, + "venv/lib/python3.13/site-packages/pygments/lexers/lilypond.py": 1088755646568511197, + "venv/lib/python3.13/site-packages/pandas/tests/test_expressions.py": 16378925536309828288, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_repeat.py": 18394463352314692642, + "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/LICENSE": 12064892310002036996, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/compiler.py": 13924519162400330589, + "venv/lib/python3.13/site-packages/_pytest/hookspec.py": 387790426108810884, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/LCSseq.pyi": 16372699564794732463, + "venv/lib/python3.13/site-packages/pip/_vendor/requests/auth.py": 912521029864094489, + "venv/lib/python3.13/site-packages/authlib/oauth2/base.py": 12948318231066662045, + "venv/lib/python3.13/site-packages/websockets/speedups.pyi": 10322382420215791091, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/DamerauLevenshtein_py.py": 1933257612725836484, + "venv/lib/python3.13/site-packages/pip/_internal/utils/filesystem.py": 7716285033598020316, + "venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/WHEEL": 7127684561765977531, + "venv/lib/python3.13/site-packages/dotenv/py.typed": 9796674040111366709, + "venv/lib/python3.13/site-packages/passlib/registry.py": 5050675058011850564, + "venv/lib/python3.13/site-packages/pandas/core/interchange/buffer.py": 12961802206383700922, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7009/revocation.py": 16178499278312777474, + "venv/lib/python3.13/site-packages/fastapi/security/oauth2.py": 1925394177931547776, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_index_as_string.py": 292438690259156869, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/attr/_make.py": 2348458829123990579, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py": 16386268386376675175, + "venv/lib/python3.13/site-packages/pandas/tests/extension/json/__init__.py": 7877061921210840955, + "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/RECORD": 7320381591791379627, + "venv/lib/python3.13/site-packages/pandas/io/_util.py": 13608922148814398500, + "venv/lib/python3.13/site-packages/rsa/transform.py": 12261738253972114335, + "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/resolver.py": 9931394693284776391, + "venv/lib/python3.13/site-packages/pip/_vendor/packaging/utils.py": 9959199071030996679, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/types.py": 12298292195929126306, + "venv/lib/python3.13/site-packages/_pytest/__init__.py": 3769333500910148571, + "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/content": 16257335642847993866, + "venv/lib/python3.13/site-packages/dateutil/utils.py": 7067026915090881998, + "venv/lib/python3.13/site-packages/uvicorn/supervisors/basereload.py": 14479857245734482609, + "venv/lib/python3.13/site-packages/PIL/FliImagePlugin.py": 13364963053197422923, + "venv/lib/python3.13/site-packages/rsa/core.py": 13203947234024924497, + "venv/lib/python3.13/site-packages/packaging/metadata.py": 9168255069163141470, + "venv/lib/python3.13/site-packages/numpy/lib/_arraysetops_impl.pyi": 3111521453255595221, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/authorization_server.py": 2491654903543600678, + "venv/lib/python3.13/site-packages/_pytest/mark/structures.py": 12237146603608917650, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/horizontal_shard.py": 17615732108308858890, + "venv/lib/python3.13/site-packages/authlib/integrations/flask_client/apps.py": 10758062668702044519, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_constructors.py": 11786151805350138436, + "frontend/src/lib/components/layout/__tests__/sidebarNavigation.test.js": 9823973527644599938, + "frontend/src/pages/Dashboard.svelte": 3653104499351855122, + "venv/lib/python3.13/site-packages/click/utils.py": 13475604420010022458, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_f2cmap.py": 5863341586534531594, + "venv/lib/python3.13/site-packages/anyio/_core/_fileio.py": 4507100568401692983, + "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/RECORD": 1689342214025776630, + "venv/lib/python3.13/site-packages/numpy/tests/test_public_api.py": 11741922758622705449, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_hist_box_by.py": 16197297231683144299, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/psycopg2cffi.py": 5997687240967250164, + "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/RECORD": 12598309574903741388, + "merge_spec.py": 5285945727297582371, + "backend/src/services/git/_url.py": 15729080796864187707, + "frontend/build/_app/immutable/nodes/25.Dz6lg2iG.js": 9988963929265574361, + "backend/alembic/README": 17625003422504608299, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_assign.py": 2647902466315482406, + "venv/lib/python3.13/site-packages/pandas/tests/config/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pygments/lexers/ooc.py": 14540210212631538007, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_umath_complex.py": 11732242536199439023, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/strptime.cpython-313-x86_64-linux-gnu.so": 12654188486128938170, + "venv/lib/python3.13/site-packages/httpx/_config.py": 8800538050293498928, + "venv/lib/python3.13/site-packages/numpy/random/__init__.pyi": 13833571330152615376, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_indexing.py": 17106010337164216722, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/reserved_words.py": 8022121780993497971, + "venv/bin/numpy-config": 17104619511899110252, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_copy.py": 11335108864615756235, + "backend/src/__init__.py": 11250920420388310655, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_reset_index.py": 14490875921264161445, + "venv/lib/python3.13/site-packages/passlib/exc.py": 15559705487889657091, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_functions.py": 16376319335326812580, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/polynomial_polybase.pyi": 3404315099794022355, + "venv/lib/python3.13/site-packages/greenlet/CObjects.cpp": 3454797518210223926, + "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/WHEEL": 1598805043198466373, + "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/_in_process/__init__.py": 9627328185578406121, + "venv/lib/python3.13/site-packages/numpy/matrixlib/defmatrix.py": 4940170059946018356, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/RECORD": 5169907629260560698, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_unstack.py": 11834917665446437163, + "venv/lib/python3.13/site-packages/starlette/_exception_handler.py": 9892172656847200124, + "venv/lib/python3.13/site-packages/PIL/PpmImagePlugin.py": 7107324729714470853, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_complex.py": 12963449957363121481, + "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/applicator": 6870991911243684132, + "venv/lib/python3.13/site-packages/authlib/consts.py": 14226604841596736870, + "venv/lib/python3.13/site-packages/numpy/random/_common.pxd": 3402284125943848851, + "venv/lib/python3.13/site-packages/requests/compat.py": 5836590172733661320, + "venv/lib/python3.13/site-packages/pydantic_settings/sources/base.py": 10200916670889920659, + "venv/lib/python3.13/site-packages/numpy/random/_examples/cffi/parse.py": 2427019397934437210, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_real.py": 5283415082530228716, + "venv/lib/python3.13/site-packages/pycparser/ply/lex.py": 3393278208465358140, + "venv/lib/python3.13/site-packages/pygments/lexers/mime.py": 7768464764849718825, + "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/WHEEL": 691462085217888236, + "venv/lib/python3.13/site-packages/pygments/styles/lilypond.py": 12486578704132023691, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_contains.py": 17630310725250553247, + "frontend/src/lib/components/reports/ReportCard.svelte": 15186215132458187779, + "venv/lib/python3.13/site-packages/pygments/formatters/img.py": 18230180171537565208, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/assumed_shape/foo_free.f90": 10939657740734987454, + "frontend/src/lib/components/translate/TranslationRunGlobalIndicator.svelte": 10137468959835535437, + "frontend/src/routes/migration/__tests__/migration_dashboard.ux.test.js": 17118608261683412409, + "venv/lib/python3.13/site-packages/pydantic/deprecated/copy_internals.py": 1245428320513062166, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/JaroWinkler.py": 1341849861184131135, + "venv/lib/python3.13/site-packages/dotenv/__init__.py": 15464030923609356017, + "venv/lib/python3.13/site-packages/numpy/lib/_version.py": 15294708923334674060, + "venv/lib/python3.13/site-packages/pandas/core/series.py": 11618272682977710696, + "venv/lib/python3.13/site-packages/pandas/io/formats/info.py": 215303194287834907, + "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/METADATA": 13428590545328703138, + "venv/lib/python3.13/site-packages/PIL/GifImagePlugin.py": 16073125611077200693, + "venv/lib/python3.13/site-packages/pygments/styles/__init__.py": 18383248976818885498, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/_dml_constructors.py": 4497038002189188311, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/npyio.pyi": 15811156298637131744, + "venv/lib/python3.13/site-packages/attrs/__init__.py": 9502968706258875910, + "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/METADATA": 3618776395694990076, + "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_infer_datetimelike.py": 17304541521108700317, + "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/WHEEL": 9131187629260560775, + "venv/lib/python3.13/site-packages/PIL/SunImagePlugin.py": 7661622930404688367, + "venv/lib/python3.13/site-packages/pygments/__main__.py": 13200500591994479045, + "venv/lib/python3.13/site-packages/pygments/lexers/bdd.py": 5389493859905397060, + "venv/lib/python3.13/site-packages/PIL/ImageFilter.py": 10974179993355630141, + "frontend/src/routes/translate/dictionaries/[id]/+page.svelte": 14484918248250087235, + "venv/lib/python3.13/site-packages/numpy/_utils/_inspect.py": 7029935879540617057, + "venv/lib/python3.13/site-packages/pandas/tests/base/test_conversion.py": 7507083194555424923, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/sqltypes.py": 2952996080192295188, + "venv/lib/python3.13/site-packages/pytest/py.typed": 15130871412783076140, + "venv/bin/pyrsa-priv2pub": 16766314338551408621, + "venv/bin/pytest": 2593802493707545818, + "frontend/build/_app/immutable/nodes/20.hRBN7DT6.js": 13368106004770721520, + "backend/src/models/dataset_review_pkg/_mapping_models.py": 6232602161916984422, + "venv/lib/python3.13/site-packages/numpy/testing/__init__.pyi": 8126257788928282891, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test__iotools.py": 6260912730310453037, + "venv/lib/python3.13/site-packages/pandas/io/formats/templates/latex.tpl": 8820045022551446255, + "venv/lib/python3.13/site-packages/pandas/tests/window/test_cython_aggregations.py": 10818895573637904764, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_kurt.py": 2898715045429898166, + "backend/alembic/versions/543d43d752b8_migrate_old_dictionary_entries_and_.py": 10988663686444687907, + "venv/lib/python3.13/site-packages/rsa/pem.py": 3118524021576082054, + "venv/lib/python3.13/site-packages/jsonschema/benchmarks/validator_creation.py": 2745563768861102999, + "venv/lib/python3.13/site-packages/numpy/random/tests/data/philox-testset-1.csv": 2202360898679162333, + "frontend/src/lib/components/dataset-review/SourceIntakePanel.svelte": 10994864579319870671, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_array.f90": 9711940829820746513, + "venv/lib/python3.13/site-packages/authlib/integrations/django_client/apps.py": 14151733532064278336, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7516/models.py": 5656065513234782067, + "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/__main__.py": 6480933938145689964, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_real.f90": 9097998998863007705, + "venv/lib/python3.13/site-packages/pandas/_libs/window/aggregations.pyi": 6072607880689125113, + "venv/lib/python3.13/site-packages/pandas/tests/extension/conftest.py": 16886862391161243448, + "venv/lib/python3.13/site-packages/sqlalchemy/connectors/asyncio.py": 4200928269459447593, + "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/WHEEL": 7414522633964952515, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_mem_policy.py": 13856626567322091253, + "venv/lib/python3.13/site-packages/numpy/version.py": 1497063540123613501, + "scripts/build_offline_docker_bundle.sh": 18334040481218597997, + "venv/lib/python3.13/site-packages/pydantic/plugin/_schema_validator.py": 857640644840976862, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/conftest.py": 12368472226536104037, + "venv/lib/python3.13/site-packages/anyio/abc/_tasks.py": 16839170934610571514, + "venv/lib/python3.13/site-packages/pandas/tests/apply/test_numba.py": 203614377324678234, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_info.py": 15151894356374015812, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/timedeltas/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_crackfortran.py": 10278720705326601943, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/__init__.py": 14522970260621605208, + "venv/lib/python3.13/site-packages/pandas/tests/resample/conftest.py": 1643522609234951699, + "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/collections.cpython-313-x86_64-linux-gnu.so": 6157288238855118017, + "venv/lib/python3.13/site-packages/_pytest/helpconfig.py": 3033477806668470951, + "venv/lib/python3.13/site-packages/sqlalchemy/engine/util.py": 1520899420719605380, + "venv/lib/python3.13/site-packages/dateutil/_common.py": 12492546559232079071, + "venv/lib/python3.13/site-packages/pip/_vendor/__init__.py": 11734104142988812647, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/scanner.py": 5640381644804445932, + "venv/lib/python3.13/site-packages/starlette/convertors.py": 17839747154274354605, + "venv/lib/python3.13/site-packages/numpy/core/_utils.py": 14108063453670701289, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/kind/foo.f90": 1367964042730902899, + "venv/lib/python3.13/site-packages/pandas/_config/display.py": 433650013567734821, + "venv/lib/python3.13/site-packages/PIL/ExifTags.py": 6869879826623916830, + "venv/lib/python3.13/site-packages/pycparser/yacctab.py": 18018314512916353707, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/use_modules.f90": 3913612933340746297, + "venv/lib/python3.13/site-packages/pip/_vendor/packaging/markers.py": 5247208668583898949, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/__init__.py": 15644105878811738516, + "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/WHEEL": 11630459739183915695, + "frontend/src/components/git/CommitHistory.svelte": 15861316872235672161, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/AB.inc": 10441778083831997423, + "venv/lib/python3.13/site-packages/_pytest/stepwise.py": 3527630676691417317, + "venv/lib/python3.13/site-packages/pygments/lexers/ul4.py": 9580182474451220952, + "backend/src/schemas/profile.py": 7072251247808762582, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/ddl.py": 5006132143435653867, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_multiindex.py": 13723677252432338937, + "backend/src/core/task_manager/task_logger.py": 12820629458199400734, + "backend/src/plugins/translate/__tests__/test_inline_correction.py": 3246602656771855554, + "backend/src/plugins/translate/plugin.py": 9225230324052126034, + "venv/lib/python3.13/site-packages/attrs/__init__.pyi": 14353885498883901855, + "venv/lib/python3.13/site-packages/numpy/core/_internal.py": 14816989375912210674, + "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_scrypt.py": 8106466515670064013, + "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/__init__.py": 7526309124863950484, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_convert_dtypes.py": 13612212066710266457, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_extint128.py": 11074657869101074458, + "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/RECORD": 12733654377842895588, + "frontend/src/lib/auth/store.ts": 14669655798912377598, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/console.py": 10217327186846649646, + "venv/lib/python3.13/site-packages/cryptography/__init__.py": 641702726372647770, + "venv/lib/python3.13/site-packages/click-8.3.1.dist-info/RECORD": 3649834117451110628, + "venv/lib/python3.13/site-packages/pandas/core/arrays/interval.py": 16281221279220043867, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_interval.py": 2911379732293827726, + "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/RECORD": 10036839994791510159, + "venv/lib/python3.13/site-packages/websockets/asyncio/messages.py": 6848925149930551457, + "venv/lib/python3.13/site-packages/numpy/_core/memmap.pyi": 14124415711399771715, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_validate_kwargs.py": 10173906126211473463, + "venv/lib/python3.13/site-packages/pip/_vendor/idna/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy.libs/libquadmath-96973f99-934c22de.so.0.0.0": 5098713761946118139, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/modules.pyi": 14176187662591164602, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_cte.py": 9274103293201050794, + "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/__init__.py": 12290228927283601067, + "venv/lib/python3.13/site-packages/pygments/lexers/felix.py": 2334148799642808111, + "venv/lib/python3.13/site-packages/passlib/crypto/_blowfish/base.py": 15872835330892203433, + "frontend/build/_app/immutable/nodes/13.Cuwx6oG8.js": 10896568729237690384, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_year.py": 17441853503700184299, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_invalid.py": 2762344062554575805, + "venv/lib/python3.13/site-packages/numpy/_core/__init__.py": 14951958843029076911, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_value_counts.py": 13270420637302622174, + "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_resolution.py": 18198858926948468112, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/string_/__init__.py": 15130871412783076140, + "backend/src/plugins/translate/scheduler.py": 1593554077252050680, + "venv/lib/python3.13/site-packages/passlib/hash.py": 5238710192614935875, + "venv/lib/python3.13/site-packages/pandas/io/formats/css.py": 11288129826285529457, + "venv/lib/python3.13/site-packages/PIL/ImageShow.py": 11437096951764124817, + "venv/lib/python3.13/site-packages/pandas/tests/extension/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_nditer.py": 8341339612899904236, + "venv/lib/python3.13/site-packages/numpy/_core/_methods.py": 16805668769357938792, + "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/licenses/LICENSE": 12688029424398428498, + "venv/lib/python3.13/site-packages/anyio/streams/stapled.py": 9733127303038397237, + "venv/lib/python3.13/site-packages/websockets/asyncio/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/array_constructors.py": 6727209833819502644, + "backend/src/api/routes/assistant/_admin_routes.py": 3380446401429936332, + "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/WHEEL": 6514509858522675228, + "venv/lib/python3.13/site-packages/_pytest/assertion/rewrite.py": 2425990712758915831, + "venv/lib/python3.13/site-packages/apscheduler/triggers/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_textreader.py": 388955620768371652, + "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_chebyshev.py": 8054411443686791426, + "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_delete.py": 3485374671877063217, + "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/aws.py": 1364297790170663941, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/padding.py": 13763154154862871596, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_character/foo77.f": 4046503346951676582, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/period/test_asfreq.py": 6162659555626011770, + "venv/lib/python3.13/site-packages/jsonschema/benchmarks/issue232.py": 6498198296113395367, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_all_methods.py": 18227706645906325527, + "venv/lib/python3.13/site-packages/pygments/formatters/irc.py": 2133711525226123259, + "venv/lib/python3.13/site-packages/pygments/__init__.py": 14493583771211110135, + "venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/INSTALLER": 17282701611721059870, + "frontend/src/lib/stores/translationRun.js": 1541511355007861201, + "frontend/src/lib/components/dataset-review/ExecutionMappingReview.svelte": 11412197655386056417, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/__ufunc_api.c": 11535375410441493281, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/__init__.py": 5118993772178969104, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_setops.py": 13440916133402971190, + "backend/src/core/__tests__/test_native_filters.py": 823253235973274872, + "backend/src/core/superset_client/_dashboards_filters.py": 11002883972618719697, + "venv/lib/python3.13/site-packages/pip/_internal/network/__init__.py": 1586148254475575526, + "venv/lib/python3.13/site-packages/pygments/lexers/slash.py": 8320676560518108343, + "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/authorization_server.py": 4427151727224472650, + "venv/lib/python3.13/site-packages/pydantic/_internal/_forward_ref.py": 10623110912945011703, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/test_holiday.py": 8541197358003711845, + "backend/tests/test_translate_scheduler_execution.py": 16687335504320865378, + "frontend/build/_app/immutable/entry/app.EqiC6C3A.js": 12263353332086817548, + "venv/lib/python3.13/site-packages/ecdsa/errors.py": 11755424742691057760, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh25286_bc.pyf": 10893958728966010450, + "venv/lib/python3.13/site-packages/PIL/ImageColor.py": 17058618058554970738, + "venv/lib/python3.13/site-packages/urllib3/connectionpool.py": 7493427857878469165, + "venv/lib/python3.13/site-packages/click/termui.py": 7022374827798605437, + "venv/lib/python3.13/site-packages/pandas/core/reshape/tile.py": 17137524194129840833, + "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/__init__.py": 15340047930888693984, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_unique.py": 16285418015531891530, + "venv/lib/python3.13/site-packages/fastapi/middleware/gzip.py": 436886407566263171, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/char.pyi": 1639810799219814643, + "venv/lib/python3.13/site-packages/pandas/core/methods/selectn.py": 13552176539021625776, + "venv/lib/python3.13/site-packages/git/refs/reference.py": 2038789918710608481, + "frontend/src/components/DashboardGrid.svelte": 5332611872674866671, + "frontend/src/lib/components/translate/BulkCorrectionSidebar.svelte": 5119156213531888283, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_riscv_unix.h": 8607317131295864391, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/DamerauLevenshtein.py": 17993169044119596860, + "venv/lib/python3.13/site-packages/starlette/middleware/base.py": 16850428285382256618, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/simple.py": 11050636051019777317, + "venv/lib/python3.13/site-packages/passlib/crypto/des.py": 14699826058580193499, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_get_numeric_data.py": 11747933921770969706, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/index_tricks.py": 10051261976498916957, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc64_linux.h": 4071314837793906998, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/palette.py": 17383863392192572184, + "venv/lib/python3.13/site-packages/apscheduler/executors/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pygments/lexers/_postgres_builtins.py": 2383906454995727700, + "venv/lib/python3.13/site-packages/typing_inspection/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/ecdsa/test_der.py": 7117444285097824495, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/jws_algs.py": 11920621906391796226, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_arrayprint.py": 13335063050941743734, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_read_errors.py": 4559483361564472117, + "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_writers.py": 103545128256076790, + "venv/lib/python3.13/site-packages/multipart/__init__.py": 6496114190873890851, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/dml.py": 5340326603935367534, + "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/request.py": 17642741955458391050, + "frontend/src/components/git/ConflictResolver.svelte": 12431368407090802392, + "frontend/build/_app/immutable/nodes/23.Cla0r9L2.js": 4312072173612601380, + "frontend/build/_app/immutable/chunks/DepzS_bZ.js": 2243340878436625890, + "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/INSTALLER": 17282701611721059870, + "backend/src/core/utils/__init__.py": 12454773556575864508, + "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/WHEEL": 16097436423493754389, + "frontend/src/lib/components/layout/__tests__/test_taskDrawer.svelte.js": 15288009749873977442, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/array_constructors.pyi": 4993066609272697419, + "venv/lib/python3.13/site-packages/starlette/endpoints.py": 3379755567024530053, + "venv/lib/python3.13/site-packages/numpy/polynomial/polynomial.py": 7658234162211356265, + "venv/lib/python3.13/site-packages/starlette/schemas.py": 697416731579555195, + "venv/lib/python3.13/site-packages/pandas/core/internals/blocks.py": 6448406236246476333, + "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_backend.py": 1472021608501071055, + "venv/lib/python3.13/site-packages/git/cmd.py": 8854786163152637148, + "venv/lib/python3.13/site-packages/passlib/handlers/digests.py": 18158237109145814857, + "venv/lib/python3.13/site-packages/pandas/tests/extension/json/array.py": 7437107031079833232, + "venv/lib/python3.13/site-packages/PIL/DdsImagePlugin.py": 10646832373516499548, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/conftest.py": 4124267277224879990, + "venv/lib/python3.13/site-packages/secretstorage/util.py": 1004887530903069622, + "venv/lib/python3.13/site-packages/passlib/handlers/scrypt.py": 10089372287597257402, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/compiler.py": 11662494978292401568, + "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/WHEEL": 8600534672961461758, + "venv/lib/python3.13/site-packages/anyio/pytest_plugin.py": 4165280709813718099, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/constants.pyi": 15633065380510755171, + "backend/src/core/migration/risk_assessor.py": 1061977005072298440, + "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/WHEEL": 7454950858448014158, + "venv/lib/python3.13/site-packages/pygments/lexers/elm.py": 14683437310498104916, + "backend/src/plugins/translate/__tests__/test_executor.py": 7200474786659302788, + "venv/lib/python3.13/site-packages/rpds/__init__.pyi": 12037474523494903587, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ndarray_misc.pyi": 7544619194032232861, + "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libssl-81ffa89e.so.3": 13913673119166658781, + "venv/lib/python3.13/site-packages/pip/_vendor/requests/hooks.py": 9888227370911151341, + "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/RECORD": 18294169019244826301, + "venv/lib/python3.13/site-packages/pandas/_libs/window/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/_utils/__init__.pyi": 13530522898409268883, + "venv/lib/python3.13/site-packages/pandas/tests/extension/test_arrow.py": 10068866425352207113, + "venv/lib/python3.13/site-packages/websockets/legacy/exceptions.py": 16025779645869134942, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/strings.pyi": 402863478592154500, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/elements.py": 11185011314498348980, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/__init__.py": 260774374497653876, + "venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/METADATA": 8128818962678047497, + "frontend/src/components/StartupEnvironmentWizard.svelte": 6947772062866928838, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/ec.pyi": 9835891299056543360, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/resource_owner_password_credentials.py": 9559295461619813890, + "venv/lib/python3.13/site-packages/numpy/lib/introspect.pyi": 12239924839764265507, + "venv/pyvenv.cfg": 2513607356761047446, + "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_tzconversion.py": 7205566353454584259, + "venv/lib/python3.13/site-packages/urllib3/util/url.py": 15992369651965016538, + "backend/src/services/__tests__/test_encryption_manager.py": 7097521778855634174, + "backend/test_app.db": 2486636812009447051, + "venv/lib/python3.13/site-packages/pillow.libs/libpng16-4a38ea05.so.16.53.0": 13136089038268964667, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_pivot.py": 334735766122314163, + "venv/lib/python3.13/site-packages/anyio/abc/_subprocesses.py": 4297459042599291531, + "venv/lib/python3.13/site-packages/pydantic/__init__.py": 11536052293866174672, + "venv/lib/python3.13/site-packages/pandas/tests/tools/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/iniconfig/_version.py": 8497474654470220170, + "venv/lib/python3.13/site-packages/pandas/io/formats/style_render.py": 13586834368514801953, + "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_dt_accessor.py": 2229616362327032253, + "venv/lib/python3.13/site-packages/pygments/lexers/procfile.py": 3860651022061090738, + "venv/lib/python3.13/site-packages/yaml/serializer.py": 1783761365703703558, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_equivalence.py": 17843623343419137458, + "venv/lib/python3.13/site-packages/pygments/lexers/ncl.py": 14838368780033177943, + "venv/lib/python3.13/site-packages/numpy/tests/test_lazyloading.py": 17465787495701737655, + "venv/lib/python3.13/site-packages/websockets/sync/messages.py": 15699091325918681038, + "venv/lib/python3.13/site-packages/numpy/lib/user_array.py": 14003456655595459585, + "venv/lib/python3.13/site-packages/pandas/tests/extension/base/interface.py": 3134071530627935964, + "venv/lib/python3.13/site-packages/pandas/tests/io/test_fsspec.py": 6936167344144998172, + "backend/tests/test_translate_scheduler.py": 14274816721941617887, + "backend/ss_tools_backend.egg-info/PKG-INFO": 15134841326777953914, + "venv/lib/python3.13/site-packages/cffi/error.py": 8147505969912539538, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm64_masm.asm": 16630507336149184509, + "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_take.py": 9847808489301498487, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_put.py": 8547660958963625817, + "venv/lib/python3.13/site-packages/numpy/_typing/_nested_sequence.py": 7827259347937485408, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/numpy_/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/cffi/_embedding.h": 9441285871823018603, + "venv/lib/python3.13/site-packages/numpy/_core/_dtype.pyi": 17662618580381221543, + "venv/lib/python3.13/site-packages/cffi/__init__.py": 13427266446746498548, + "venv/lib/python3.13/site-packages/jsonschema/benchmarks/__init__.py": 5863110456909134678, + "venv/lib/python3.13/site-packages/pip/_internal/build_env.py": 3614358934066127900, + "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/api.py": 13134394673408254097, + "venv/lib/python3.13/site-packages/numpy/_core/_string_helpers.py": 17192211156810267818, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_arraymethod.py": 14421188237635557797, + "venv/lib/python3.13/site-packages/numpy/random/_bounded_integers.cpython-313-x86_64-linux-gnu.so": 16604252871044637047, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/f90continuation.f90": 17056591497459381871, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_isin.py": 14387850595546682314, + "venv/lib/python3.13/site-packages/numpy/lib/_datasource.pyi": 5894423389796456573, + "venv/lib/python3.13/site-packages/numpy/lib/_twodim_base_impl.pyi": 15509415708991012734, + "venv/lib/python3.13/site-packages/pandas/tests/extension/base/reduce.py": 14976712507854054776, + "venv/lib/python3.13/site-packages/jeepney/tests/test_auth.py": 15125055415702968414, + "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_to_offset.py": 3929599794655343911, + "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_parsing.py": 2228959015420278458, + "venv/lib/python3.13/site-packages/pip/_vendor/tomli/_parser.py": 3540203683732744499, + "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/METADATA": 10220680536734745103, + "venv/lib/python3.13/site-packages/PIL/IcoImagePlugin.py": 14483964191652228364, + "venv/lib/python3.13/site-packages/PIL/SgiImagePlugin.py": 6916200065790425497, + "venv/lib/python3.13/site-packages/PIL/XVThumbImagePlugin.py": 7472134175570205454, + "venv/lib/python3.13/site-packages/pygments/lexers/diff.py": 5930189593946259160, + "venv/lib/python3.13/site-packages/numpy/f2py/diagnose.py": 503331864022631297, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/conversion.cpython-313-x86_64-linux-gnu.so": 9014806524727977333, + "venv/lib/python3.13/site-packages/packaging/pylock.py": 15346942039643310253, + "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/windows.py": 16452996247375488034, + "venv/lib/python3.13/site-packages/passlib/handlers/bcrypt.py": 8125664010268654055, + "venv/bin/jsonschema": 16516374846693491442, + "frontend/postcss.config.js": 5714274776976071678, + "frontend/build/_app/immutable/nodes/37.h0kspZQz.js": 2116024229457453594, + "venv/lib/python3.13/site-packages/fastapi/security/__init__.py": 1345944646061334046, + "frontend/build/_app/immutable/chunks/B3G5yh93.js": 9701033449616441331, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_freq_attr.py": 1720704043778272895, + "venv/lib/python3.13/site-packages/click/_compat.py": 14451519072991457993, + "venv/lib/python3.13/site-packages/passlib/tests/__main__.py": 16477180140297957650, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_slice.py": 9936085512921529417, + "venv/lib/python3.13/site-packages/pandas/_libs/hashtable.cpython-313-x86_64-linux-gnu.so": 16963890771704942465, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_concat.py": 16549010224568175202, + "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/licenses/LICENSE": 5563356551734678258, + "venv/lib/python3.13/site-packages/jeepney/bus_messages.py": 5871341372541525842, + "venv/lib/python3.13/site-packages/keyring/backends/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/schema.py": 5391655516870611151, + "frontend/build/_app/immutable/nodes/28.BMMMq5av.js": 1258679536261114563, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/regexopt.py": 16073437303824961930, + "venv/lib/python3.13/site-packages/numpy/_pyinstaller/__init__.pyi": 15130871412783076140, + "venv/lib/python3.13/site-packages/uvicorn/logging.py": 12858188863836778374, + "venv/lib/python3.13/site-packages/numpy/lib/_npyio_impl.py": 2215312866861772848, + "venv/lib/python3.13/site-packages/pydantic/main.py": 14086938579850319884, + "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_insert.py": 15536994417338770457, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_datetime.py": 13781712980921881470, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_update.py": 9098258267671647783, + "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/licenses/AUTHORS": 17022185907188244883, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/__init__.py": 8807410829260170597, + "frontend/build/_app/immutable/chunks/DsAODWVW.js": 17093454341120407063, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/attributes.py": 5068814626384132900, + "frontend/vitest.config.js": 142965001777137074, + "backend/src/plugins/migration.py": 16567640288127443175, + "backend/alembic/versions/b1c2d3e4f5a6_add_source_hash_to_translation_records.py": 4775534557742900399, + "venv/lib/python3.13/site-packages/pandas/io/excel/_base.py": 1251545894005373734, + "venv/lib/python3.13/site-packages/uvicorn/_compat.py": 2593000889619875759, + "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_strptime.py": 14328510310436552635, + "venv/lib/python3.13/site-packages/greenlet/tests/fail_initialstub_already_started.py": 5562030563802006923, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pip/_vendor/certifi/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/polynomial/legendre.py": 1731362089136926666, + "venv/lib/python3.13/site-packages/numpy/polynomial/__init__.py": 15558318749939680074, + "venv/lib/python3.13/site-packages/passlib/ext/django/__init__.py": 11713862539944289631, + "venv/lib/python3.13/site-packages/pandas/tests/test_common.py": 8987965560487646705, + "venv/lib/python3.13/site-packages/jose/utils.py": 1926138853970725083, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/base/test_unique.py": 3148372351781648868, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/OSA.py": 17817123894903120316, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/shape.pyi": 17197248408326188931, + "venv/lib/python3.13/site-packages/pandas/tests/resample/test_period_index.py": 6634414375581820058, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_iter.py": 9232021002336641851, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_freq_attr.py": 17290447066681837965, + "venv/lib/python3.13/site-packages/pandas/tests/frame/conftest.py": 15090201792072045503, + "venv/lib/python3.13/site-packages/pydantic/v1/error_wrappers.py": 5701679786078971939, + "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_dict_compat.py": 18196543090455290455, + "venv/lib/python3.13/site-packages/pandas/io/sas/sas7bdat.py": 17851617851457266799, + "venv/lib/python3.13/site-packages/starlette/concurrency.py": 9835859079437525910, + "venv/lib/python3.13/site-packages/pip/_vendor/idna/idnadata.py": 1169745920682458213, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_arraysetops.py": 10588903945244480732, + "venv/lib/python3.13/site-packages/pip/_vendor/requests/_internal_utils.py": 4091305333167213279, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_astype.py": 15768655715952923925, + "venv/lib/python3.13/site-packages/pandas/tests/io/json/conftest.py": 9673372914396625461, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm64_msvc.h": 14580207065003376324, + "venv/lib/python3.13/site-packages/pandas/tests/test_nanops.py": 8709105600366913011, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/named_types.py": 6099185243355915896, + "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/METADATA": 3448868793744358515, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/psycopg2.py": 1331438198531942242, + "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/resultproxy.pyx": 5760108632332714287, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc_macosx.h": 3653129798702716366, + "venv/lib/python3.13/site-packages/yaml/resolver.py": 6669674521776449098, + "venv/lib/python3.13/site-packages/idna-3.11.dist-info/RECORD": 11541505360973709787, + "venv/lib/python3.13/site-packages/jaraco/functools/__init__.pyi": 2872039192528394677, + "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/WHEEL": 16097436423493754389, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_complex/foo90.f90": 15981076495193915107, + "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/METADATA": 2053484635654179443, + "venv/lib/python3.13/site-packages/pandas/tests/strings/test_extract.py": 14547819021277949280, + "venv/lib/python3.13/site-packages/pygments/lexers/_luau_builtins.py": 13690910306072616818, + "venv/lib/python3.13/site-packages/pygments/lexers/parasail.py": 7758704230750989282, + "venv/lib/python3.13/site-packages/urllib3/util/retry.py": 17988032431204662756, + "venv/lib/python3.13/site-packages/pygments/lexers/rnc.py": 9747352274729854620, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/string/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/routines/subrout.f": 18215492757907465667, + "backend/src/core/database.py.bak": 14909628735913201532, + "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/connection.py": 15405047955974108860, + "venv/lib/python3.13/site-packages/pygments/lexers/textedit.py": 14872291021083255414, + "backend/src/plugins/llm_analysis/__init__.py": 9254812131558249924, + "venv/lib/python3.13/site-packages/pygments/lexers/rebol.py": 10460732731157940232, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/pubprivmod.f90": 8680230823849248800, + "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/signals.py": 13677199634497673845, + "venv/lib/python3.13/site-packages/passlib/tests/test_totp.py": 9150389741890748343, + "venv/lib/python3.13/site-packages/numpy/_core/_exceptions.pyi": 3661113433078225952, + "venv/lib/python3.13/site-packages/pygments/lexers/configs.py": 7712797939104760185, + "venv/lib/python3.13/site-packages/pip/_vendor/packaging/licenses/__init__.py": 2635182244050911910, + "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/core/base.py": 10262717073058743378, + "venv/lib/python3.13/site-packages/PIL/__init__.py": 10393984345353752724, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_concat.py": 4472503149811617440, + "venv/lib/python3.13/site-packages/cryptography/hazmat/decrepit/__init__.py": 63497920264089252, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_convert_dtypes.py": 5005259275646154894, + "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_xlrd.py": 9982457234958102003, + "venv/lib/python3.13/site-packages/pip/_internal/operations/build/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/PIL/FontFile.py": 112053841436523305, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_union_categoricals.py": 6843679254735807, + "venv/lib/python3.13/site-packages/pygments/lexers/c_like.py": 13004061780700827047, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/constants.pyi": 4415188581374004936, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/file_proxy.py": 17695135735211897444, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/nattype.cpython-313-x86_64-linux-gnu.so": 2311012065007769341, + "venv/lib/python3.13/site-packages/sqlalchemy/engine/__init__.py": 6327819603201859020, + "venv/lib/python3.13/site-packages/pygments/lexers/python.py": 8995519134978505744, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_highlight.py": 7573043358244876807, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/ssltransport.py": 8148652555908329980, + "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_printing.py": 1901396869745313303, + "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/METADATA": 10241403930811743893, + "frontend/src/lib/components/reports/__tests__/report_type_profiles.test.js": 498330292141991614, + "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth1/resource_protector.py": 14354891358060085360, + "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/wrapper.py": 14599195010683170123, + "venv/lib/python3.13/site-packages/pip/_vendor/distro/distro.py": 12494639376332486204, + "venv/lib/python3.13/site-packages/cryptography/hazmat/__init__.py": 6534110674636458866, + "venv/lib/python3.13/site-packages/dateutil/zoneinfo/rebuild.py": 1813298167468704155, + "venv/lib/python3.13/site-packages/packaging/utils.py": 3469957615920103670, + "frontend/build/_app/immutable/nodes/5.B73cStqs.js": 12655203259752489603, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_timestamp.py": 10308799534491190078, + "frontend/src/components/DynamicForm.svelte": 12658559315809907844, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/nditer.pyi": 2351219156711800159, + "frontend/public/vite.svg": 13568221685541582385, + "backend/src/services/clean_release/approval_service.py": 12912719831239691496, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_logical.py": 6242457515917145500, + "venv/lib/python3.13/site-packages/numpy/f2py/auxfuncs.py": 2234931733687557433, + "backend/src/services/dataset_review/repositories/session_repository.py": 4058785536575367912, + "frontend/build/_app/immutable/nodes/24.BP-Fp4AB.js": 2248231906051278481, + "venv/lib/python3.13/site-packages/annotated_types/__init__.py": 7367790549779882749, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/styles/__init__.py": 9482393721453335937, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/comparisons.py": 7327629888601690759, + "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/METADATA": 10707390829735099042, + "venv/lib/python3.13/site-packages/pip/_internal/req/req_dependency_group.py": 10505346210114745037, + "venv/lib/python3.13/site-packages/pip/_internal/metadata/base.py": 13444129650880426353, + "frontend/src/lib/components/dataset-review/__tests__/us3_execution_batch.ux.test.js": 13416996904332574966, + "venv/lib/python3.13/site-packages/pandas/tests/extension/array_with_attr/array.py": 13040461386712513615, + "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_struct_accessor.py": 6567451952835390075, + "venv/lib/python3.13/site-packages/attr/validators.pyi": 15579625896285277321, + "venv/lib/python3.13/site-packages/PIL/ImageMode.py": 2361901066832921091, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/_selectable_constructors.py": 84919308502240880, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/__init__.py": 9820770319106921495, + "backend/conftest.py": 16521922883434363388, + "venv/lib/python3.13/site-packages/websockets/datastructures.py": 5180442040351387281, + "venv/lib/python3.13/site-packages/pydantic/v1/validators.py": 1060954771151908883, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/test_constructors.py": 1697610790604400105, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_duplicated.py": 14676058112867601208, + "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/WHEEL": 16097436423493754389, + "frontend/src/routes/settings/__tests__/settings_page.ux.test.js": 8756428349518151160, + "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_delitem.py": 16538190861492829338, + "venv/lib/python3.13/site-packages/cryptography/x509/certificate_transparency.py": 11337143186866439208, + "venv/lib/python3.13/site-packages/numpy/random/tests/data/philox-testset-2.csv": 7063857529719738394, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_nlargest.py": 14518132768753249360, + "venv/lib/python3.13/site-packages/websockets/sync/client.py": 10892557975919033983, + "venv/lib/python3.13/site-packages/pillow.libs/libopenjp2-94e588ba.so.2.5.4": 2483101806045986252, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arccos.csv": 3026156288992132911, + "backend/test.db": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/_core/_methods.pyi": 9155045948490225716, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_sparc_sun_gcc.h": 2915128971664712180, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/formatters/_mapping.py": 13335227913146542481, + "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/dotenv/main.py": 7408889670575271484, + "venv/lib/python3.13/site-packages/pandas/_libs/json.pyi": 10989301892466547548, + "venv/lib/python3.13/site-packages/PIL/_binary.py": 14039167720582222043, + "backend/src/core/migration/__init__.py": 13075189211840127611, + "venv/lib/python3.13/site-packages/attrs/converters.py": 13109003765349201809, + "venv/lib/python3.13/site-packages/pandas/util/_test_decorators.py": 17930801441803090445, + "venv/lib/python3.13/site-packages/fastapi/applications.py": 4975013401500183420, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_ops.py": 3875181889032080505, + "venv/lib/python3.13/site-packages/authlib/integrations/base_client/async_app.py": 4329794049222609894, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/state_changes.py": 11425629729736599320, + "venv/lib/python3.13/site-packages/PIL/ImageGrab.py": 11114379915762058868, + "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/pydantic/v1/utils.py": 902648247561165429, + "venv/lib/python3.13/site-packages/pygments/lexers/ml.py": 7510453371068494792, + "venv/lib/python3.13/site-packages/packaging/_elffile.py": 9546225990833172494, + "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/providers.py": 7267821734584612032, + "backend/src/api/routes/migration.py": 6030566471113208264, + "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/RECORD": 9461427699726982537, + "venv/lib/python3.13/site-packages/pip/_internal/utils/compatibility_tags.py": 15862649917149158291, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arrayterator.pyi": 7439348655567232744, + "venv/lib/python3.13/site-packages/numpy/_core/einsumfunc.pyi": 4729765666018003634, + "frontend/src/routes/reports/llm/[taskId]/report_page.contract.test.js": 4825093389030464765, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_chaining_and_caching.py": 15814259766479305290, + "venv/lib/python3.13/site-packages/anyio/to_process.py": 16627578499791368365, + "venv/lib/python3.13/site-packages/rapidfuzz/fuzz_cpp.cpython-313-x86_64-linux-gnu.so": 14187094676876471848, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/ndarraytypes.h": 6765088137325865789, + "venv/lib/python3.13/site-packages/pandas/core/groupby/__init__.py": 3015263524218708013, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/foo_deps.f90": 14350239197565389508, + "venv/lib/python3.13/site-packages/sqlalchemy/engine/cursor.py": 8074527784886981710, + "venv/lib/python3.13/site-packages/git/objects/blob.py": 8972374723153211283, + "backend/src/core/superset_client/_datasets_preview_filters.py": 12835417730902013107, + "venv/lib/python3.13/site-packages/pip/_internal/operations/install/wheel.py": 3531093454660385247, + "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libsasl2-883649fd.so.3.0.0": 13306917506408577991, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/__init__.py": 14571251344510763303, + "venv/lib/python3.13/site-packages/pip/_vendor/distlib/metadata.py": 1362166613223529108, + "venv/lib/python3.13/site-packages/numpy/lib/format.py": 14971167445246135440, + "venv/lib/python3.13/site-packages/numpy/random/_bounded_integers.pxd": 9126772093305708921, + "venv/lib/python3.13/site-packages/requests/exceptions.py": 6474239743209354989, + "venv/lib/python3.13/site-packages/jeepney/tests/test_bus.py": 4260827599660763641, + "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/RECORD": 16342326945648353387, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_x64_masm.obj": 2884737706935637437, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/arrayprint.py": 5912583751693302370, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_timestamp_method.py": 11393911418463808195, + "venv/lib/python3.13/site-packages/apscheduler/executors/twisted.py": 2695602672085615762, + "venv/lib/python3.13/site-packages/pydantic/v1/typing.py": 13467331592583800299, + "venv/lib/python3.13/site-packages/pandas/compat/numpy/function.py": 18405870240333383757, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/dsa.pyi": 1065808244870331598, + "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/gcp.py": 12328409672947966867, + "venv/lib/python3.13/site-packages/numpy/lib/__init__.pyi": 1537495515469182226, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_setops.py": 5208912445718807372, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_where.py": 16584772339591698754, + "venv/lib/python3.13/site-packages/pandas/tests/strings/conftest.py": 12065119814157197510, + "venv/lib/python3.13/site-packages/sqlalchemy/engine/result.py": 12262298207886620908, + "venv/lib/python3.13/site-packages/PIL/PcxImagePlugin.py": 1691405132377495336, + "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/random/_generator.cpython-313-x86_64-linux-gnu.so": 15625019745021657670, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_function.py": 13492077564015386528, + "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_categorical.py": 12897027063618569795, + "venv/lib/python3.13/site-packages/pandas/io/formats/style.py": 13235403689320479165, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/common/block.f": 10727418304254548946, + "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_api.py": 16743710460729009914, + "venv/lib/python3.13/site-packages/secretstorage/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/anyio/_core/_typedattr.py": 17584691045493791349, + "scripts/gen_semantics.py": 11397714264377363083, + "venv/lib/python3.13/site-packages/jaraco/classes/ancestry.py": 11742194518360056470, + "venv/lib/python3.13/site-packages/git/objects/submodule/base.py": 10140490301897269395, + "venv/lib/python3.13/site-packages/urllib3/_request_methods.py": 13671055114247516883, + "venv/lib/python3.13/site-packages/uvicorn/supervisors/multiprocess.py": 10047012560534876149, + "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/licenses/LICENSE": 3868190977070717994, + "backend/src/plugins/translate/_utils.py": 4311334421388625700, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/lib_polynomial.pyi": 9134949577567498894, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_diff.py": 7420674239386436885, + "venv/lib/python3.13/site-packages/pydantic/json.py": 4109352930301629308, + "venv/lib/python3.13/site-packages/numpy/_core/overrides.pyi": 13121243505132110607, + "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_get.py": 10255752806860493777, + "venv/lib/python3.13/site-packages/authlib/oidc/discovery/well_known.py": 8259335680633926377, + "venv/lib/python3.13/site-packages/pip/_vendor/requests/utils.py": 3710235316419562274, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_records.py": 6252761812228230408, + "venv/lib/python3.13/site-packages/pandas/tests/apply/test_series_apply_relabeling.py": 3930092097678339743, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/psycopg.py": 8023549900603235601, + "backend/src/services/clean_release/preparation_service.py": 7557861288058237966, + "venv/lib/python3.13/site-packages/numpy/lib/_datasource.py": 18136853038949826147, + "venv/lib/python3.13/site-packages/numpy/_pytesttester.py": 17737911110576747508, + "venv/lib/python3.13/site-packages/pandas/core/indexes/category.py": 18192569199634406001, + "venv/lib/python3.13/site-packages/pandas/core/resample.py": 13814298871925341617, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_transpose.py": 17983160984979323393, + "venv/lib/python3.13/site-packages/attrs/filters.py": 6844006230924162452, + "venv/lib/python3.13/site-packages/pandas/tests/extension/base/missing.py": 14589973874359353799, + "frontend/src/lib/components/dataset-review/__tests__/source_intake_panel.ux.test.js": 13445861056598482363, + "backend/tests/scripts/test_clean_release_tui_v2.py": 16893299982170941753, + "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth1/__init__.py": 14481526616887213120, + "venv/lib/python3.13/site-packages/pydantic/validate_call_decorator.py": 11130572937843915026, + "frontend/src/routes/translate/[id]/+page.svelte": 2871210084962736100, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/control.py": 2034518223411945438, + "venv/lib/python3.13/site-packages/websockets/utils.py": 17624459810483092475, + "backend/src/api/routes/__tests__/test_git_api.py": 43259826036955162, + "venv/lib/python3.13/site-packages/pip/_internal/utils/virtualenv.py": 14416705841810221305, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_boxplot_method.py": 7635131059308651529, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_palettes.py": 13495896173068490516, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_timedelta.py": 7742506012012398830, + "venv/lib/python3.13/site-packages/httpcore/_utils.py": 3255581092836273826, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/dsa.py": 8079219938116542284, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalar_methods.py": 14881910898871057761, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_is_homogeneous_dtype.py": 15378147393056707851, + "backend/src/models/dataset_review_pkg/_filter_models.py": 8426742165406106645, + "venv/lib/python3.13/site-packages/urllib3/util/wait.py": 14629837381061032546, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/string/test_indexing.py": 2274965639578580723, + "venv/lib/python3.13/site-packages/numpy/ma/mrecords.pyi": 8945514863366384484, + "venv/lib/python3.13/site-packages/numpy/_core/tests/_natype.py": 12013743717306900860, + "venv/lib/python3.13/site-packages/dateutil/rrule.py": 398469817784230512, + "venv/lib/python3.13/site-packages/numpy/testing/_private/utils.py": 3646474165295296669, + "venv/lib/python3.13/site-packages/authlib/integrations/starlette_client/apps.py": 4219758952914498116, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/json.py": 4660603129768960095, + "venv/lib/python3.13/site-packages/yaml/__init__.py": 11044333164208875121, + "venv/lib/python3.13/site-packages/httpx/_transports/asgi.py": 12335675489870745729, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_dtypes.py": 6831042272921908068, + "venv/lib/python3.13/site-packages/httpcore/__init__.py": 5897259569277532401, + "venv/lib/python3.13/site-packages/jose/backends/ecdsa_backend.py": 2684176977865283060, + "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth1/authorization_server.py": 6858244712625056421, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7515/__init__.py": 2791238481813240414, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/_testing/compat.py": 10172779814048259850, + "venv/lib/python3.13/site-packages/pygments/styles/igor.py": 2291640843781128270, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_decimal.py": 3515468590005709183, + "venv/lib/python3.13/site-packages/pygments/lexers/comal.py": 769727871242464458, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/mod.py": 2054876501774773382, + "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/core.py": 14576109242055156193, + "venv/lib/python3.13/site-packages/PIL/MicImagePlugin.py": 13540523615822507963, + "venv/lib/python3.13/site-packages/_pytest/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/core/window/expanding.py": 14141093310397856286, + "venv/lib/python3.13/site-packages/pandas/api/typing/aliases.py": 11194270368147942988, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/git/index/base.py": 641556304637379636, + "venv/lib/python3.13/site-packages/pip/_internal/operations/build/build_tracker.py": 9389444024234384408, + "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/_pytest/raises.py": 8188402179490363767, + "venv/lib/python3.13/site-packages/numpy/_typing/_char_codes.py": 14162745886150625150, + "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/RECORD": 17545477863793260029, + "venv/lib/python3.13/site-packages/attr/_next_gen.py": 16353246941851015420, + "venv/lib/python3.13/site-packages/websockets/__main__.py": 11948055520555854616, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/algorithms.py": 17106903014205241774, + "venv/lib/python3.13/site-packages/pydantic/_internal/_fields.py": 2692892815545218335, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_semicolon_split.py": 8153770165829451525, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/vectorized.cpython-313-x86_64-linux-gnu.so": 5441755022198996487, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_join.py": 17508073052750406350, + "venv/lib/python3.13/site-packages/git/repo/base.py": 13975465345838683533, + "venv/lib/python3.13/site-packages/attr/__init__.pyi": 13203080513025719049, + "venv/lib/python3.13/site-packages/pygments/lexers/automation.py": 8021926838024836904, + "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/numpy/_core/_umath_tests.pyi": 4587511199710546030, + "venv/lib/python3.13/site-packages/websockets/sync/utils.py": 15135020989207191168, + "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/collections.pyx": 17138729833735744777, + "venv/bin/pyrsa-decrypt": 10929163076272054227, + "venv/bin/Activate.ps1": 1196103427939049710, + "frontend/src/lib/stores/__tests__/test_activity.js": 15599963775430388097, + "frontend/src/routes/settings/git/+page.svelte": 9547035239167234477, + "venv/lib/python3.13/site-packages/pip/_vendor/tomli_w/__init__.py": 12849371269359608058, + "venv/lib/python3.13/site-packages/pandas/core/indexes/extension.py": 7193879749426425951, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_duplicates.py": 9830936017197354309, + "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_get_value.py": 389530025760539462, + "venv/lib/python3.13/site-packages/pip/_internal/resolution/legacy/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_filter.py": 2388681477981649268, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/period/test_arithmetic.py": 13320788210970132239, + "venv/lib/python3.13/site-packages/pytest_asyncio/plugin.py": 13414541723622354359, + "backend/src/plugins/debug.py": 2035734953696955393, + "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libpq-9b38f5e3.so.5.17": 9680474575710585826, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/data_common.f": 5913807803369559749, + "venv/lib/python3.13/site-packages/numpy/_core/_add_newdocs.pyi": 9282436354926617898, + "venv/lib/python3.13/site-packages/numpy/testing/_private/extbuild.pyi": 18253950285509265097, + "venv/lib/python3.13/site-packages/numpy/f2py/cb_rules.py": 11397521081216402594, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_mem_overlap.py": 4202716587079637350, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_argsort.py": 7320661835159648143, + "frontend/build/_app/immutable/nodes/9.86weTBJx.js": 9420619046628747900, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_quantile.py": 11273403743157110261, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_partial_slicing.py": 15567512240469921599, + "venv/lib/python3.13/site-packages/pandas/io/formats/_color_data.py": 15614976586613738953, + "venv/lib/python3.13/site-packages/pandas/tests/io/test_html.py": 12040484325988635032, + "backend/src/core/cot_logger.py": 3113579786931231764, + "backend/src/api/routes/llm.py": 6474757426346697754, + "venv/lib/python3.13/site-packages/numpy/linalg/_umath_linalg.pyi": 7674087576653964854, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_setops.py": 14246225281428284850, + "venv/lib/python3.13/site-packages/PIL/_avif.pyi": 18222325750818585549, + "frontend/src/routes/settings/git/__tests__/git_settings_page.ux.test.js": 5334904955024018051, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/prompt.py": 9561640601516933380, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_describe.py": 362374422228593281, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7521/client.py": 17305914656270781911, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/lexer.py": 14400766876373764268, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_chunksize.py": 7107619871245389835, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_astype.py": 4854809596041987380, + "backend/src/core/superset_client/_charts.py": 8101226087578568224, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/hstore.py": 9700253004947691961, + "venv/lib/python3.13/site-packages/ecdsa/test_rw_lock.py": 1572802971060634697, + "frontend/build/_app/immutable/chunks/GHK41q1Y.js": 2219327255070861874, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_rename_axis.py": 12432900682994622455, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test__datasource.py": 1747755531265478106, + "venv/lib/python3.13/site-packages/pygments/lexers/vyper.py": 6477559246065994199, + "venv/lib/python3.13/site-packages/pandas/_libs/window/indexers.cpython-313-x86_64-linux-gnu.so": 9380059465932560412, + "venv/lib/python3.13/site-packages/numpy/_utils/_convertions.py": 12886275429547303345, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/__init__.py": 8558541715982163200, + "backend/src/api/routes/assistant/_llm_planner_intent.py": 10603216032586398176, + "venv/lib/python3.13/site-packages/pandas/tests/test_algos.py": 11860014896449369497, + "backend/src/api/routes/clean_release.py": 1984604735131504761, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/util.py": 4815334059917765852, + "venv/lib/python3.13/site-packages/websockets/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_partial.py": 15129217814262096441, + "venv/lib/python3.13/site-packages/ecdsa/_version.py": 17707102226558781833, + "venv/lib/python3.13/site-packages/pandas/tests/interchange/test_spec_conformance.py": 16448324304809345527, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_custom_business_hour.py": 14128508606361694814, + "venv/lib/python3.13/site-packages/PIL/QoiImagePlugin.py": 17663704273100331654, + "venv/lib/python3.13/site-packages/pygments/lexers/text.py": 10572727755736597715, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_interval_range.py": 9900908262700749861, + "backend/src/services/clean_release/mappers.py": 8684357784135236729, + "venv/lib/python3.13/site-packages/_pytest/nodes.py": 515939386237558331, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_datetimes.py": 7889573945417063183, + "venv/lib/python3.13/site-packages/pandas/tests/io/xml/test_to_xml.py": 8477770807916990981, + "venv/lib/python3.13/site-packages/pydantic/_internal/_typing_extra.py": 14843908493613991959, + "venv/lib/python3.13/site-packages/numpy/f2py/capi_maps.pyi": 10638891136586198429, + "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/core/arrays/__init__.py": 10460719978124302175, + "venv/lib/python3.13/site-packages/apscheduler/jobstores/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/period/test_period.py": 12593777226419608212, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_util.py": 6573034224727513309, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/state.py": 10500170103357297551, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_quarter.py": 11099677280196239755, + "venv/lib/python3.13/site-packages/numpy/exceptions.py": 10981418339663118022, + "venv/lib/python3.13/site-packages/uvicorn/lifespan/off.py": 16254524872582859561, + "backend/src/services/clean_release/facade.py": 11231787492455424065, + "venv/lib/python3.13/site-packages/PIL/ImageFont.py": 15621336334706847865, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/indexable.py": 4131796922597075758, + "venv/lib/python3.13/site-packages/requests/adapters.py": 17161109043243436200, + "venv/lib/python3.13/site-packages/apscheduler/triggers/date.py": 9545774812177853725, + "venv/lib/python3.13/site-packages/numpy/random/_examples/cython/meson.build": 17468163147765825687, + "venv/lib/python3.13/site-packages/greenlet/tests/test_generator.py": 14156412320760444199, + "venv/lib/python3.13/site-packages/numpy/_pytesttester.pyi": 5750506937526308405, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_reindex_like.py": 1407890639206728014, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/cells.py": 8299309127027168194, + "venv/lib/python3.13/site-packages/git/index/__init__.py": 7874728461616959441, + "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/dtypes/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/_pytest/setuponly.py": 10959102379908419762, + "backend/src/plugins/translate/__tests__/test_preview.py": 12246698485015379020, + "venv/lib/python3.13/site-packages/pygments/lexers/clean.py": 17772169928835025327, + "venv/lib/python3.13/site-packages/pip/_internal/commands/__init__.py": 3795218871212151351, + "venv/lib/python3.13/site-packages/requests/models.py": 9104898985870652256, + "venv/lib/python3.13/site-packages/git/refs/symbolic.py": 14996822770181935589, + "venv/lib/python3.13/site-packages/PIL/ImageDraw2.py": 13610162107593278891, + "venv/lib/python3.13/site-packages/pyasn1/type/__init__.py": 15728752901274520502, + "venv/lib/python3.13/site-packages/jsonschema/tests/fuzz_validate.py": 2328585939822059352, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/lib_utils.py": 4612923732868929770, + "venv/lib/python3.13/site-packages/pandas/tests/base/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/anyio/_core/_subprocesses.py": 7271614043537119143, + "venv/lib/python3.13/site-packages/anyio/_backends/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/urllib3/util/ssltransport.py": 1175688460659745788, + "venv/lib/python3.13/site-packages/urllib3/util/util.py": 12490259045660543460, + "venv/lib/python3.13/site-packages/pygments/styles/material.py": 14325514369696961874, + "venv/lib/python3.13/site-packages/pydantic/_internal/_docs_extraction.py": 5210114991139191634, + "venv/lib/python3.13/site-packages/pygments/lexers/_scheme_builtins.py": 5722444920479775453, + "frontend/src/routes/admin/users/+page.svelte": 18167787254767604761, + "frontend/build/_app/immutable/chunks/CKGT5ge7.js": 12663886993086252818, + "venv/lib/python3.13/site-packages/numpy/random/_generator.pyi": 17167649524261942483, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_print.py": 598821365691498702, + "venv/lib/python3.13/site-packages/uvicorn/loops/uvloop.py": 5385425357504191161, + "venv/lib/python3.13/site-packages/rapidfuzz/utils_py.py": 12341806772632276946, + "venv/lib/python3.13/site-packages/pandas/io/formats/csvs.py": 17223598248259691292, + "venv/bin/pip3.13": 13861749540792881808, + "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/response.py": 353446217435156470, + "venv/lib/python3.13/site-packages/pandas/compat/_optional.py": 12714208019736797073, + "venv/lib/python3.13/site-packages/numpy/ma/tests/test_regression.py": 12593643817685777170, + "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/WHEEL": 14929202952940710322, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_interp_fillna.py": 5530041283991655415, + "docker/frontend.Dockerfile": 9514032629617942525, + "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/METADATA": 1266134223155266488, + "venv/bin/dotenv": 953953349803507198, + "backend/src/core/superset_client/_datasets.py": 4813403545392307482, + "venv/lib/python3.13/site-packages/bcrypt/__init__.py": 11415155211917181362, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_packbits.py": 7592956764084658562, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_indexing.py": 16291207621268530224, + "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/LICENSE": 16510279186416777136, + "backend/src/plugins/git_plugin.py": 12799126783361308681, + "venv/lib/python3.13/site-packages/jeepney/__init__.py": 1063800617763464773, + "venv/lib/python3.13/site-packages/gitdb/db/ref.py": 1176701624460337371, + "venv/lib/python3.13/site-packages/pydantic/decorator.py": 6984214881365537811, + "venv/lib/python3.13/site-packages/_pytest/_argcomplete.py": 3586514420674089892, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/lib_version.py": 10384171076976071398, + "venv/lib/python3.13/site-packages/secretstorage/exceptions.py": 16701299261122689924, + "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libgssapi_krb5-497db0c6.so.2.2": 6199424505696679197, + "venv/lib/python3.13/site-packages/pygments/lexers/testing.py": 17148598391210353576, + "venv/lib/python3.13/site-packages/passlib/ext/django/models.py": 12386223748379294996, + "venv/lib/python3.13/site-packages/jsonschema/benchmarks/unused_registry.py": 10153622516112471812, + "venv/lib/python3.13/site-packages/httpx/_multipart.py": 2181282475656908730, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/diagnose.py": 17275977405061138181, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_export_format.py": 17862222951776199694, + "venv/lib/python3.13/site-packages/greenlet/tests/leakcheck.py": 10179165748538820557, + "venv/lib/python3.13/site-packages/pandas/tests/frame/test_iteration.py": 2118501258411211851, + "venv/lib/python3.13/site-packages/packaging/_structures.py": 13086687542872305890, + "venv/lib/python3.13/site-packages/jsonschema/_utils.py": 14237077105384631097, + "backend/src/api/routes/assistant/_dataset_review_dispatch.py": 10108558091463171824, + "backend/src/api/routes/assistant/_resolvers.py": 1139669723103531814, + "venv/lib/python3.13/site-packages/pandas/core/ops/common.py": 17314999825118928100, + "venv/lib/python3.13/site-packages/dateutil/tz/_factories.py": 7538654189286887518, + "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/licenses/AUTHORS": 3558407083075395848, + "venv/lib/python3.13/site-packages/sqlalchemy/pool/base.py": 16951268065271931235, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_index.py": 12015738970771703312, + "venv/lib/python3.13/site-packages/jsonschema/__main__.py": 18136546137047911521, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7662/__init__.py": 17454177076687312424, + "venv/lib/python3.13/site-packages/pip/_internal/cli/main.py": 9304034369762028739, + "backend/tests/core/test_mapping_service.py": 6888870177029085220, + "venv/lib/python3.13/site-packages/pandas/io/excel/_util.py": 6664989864423807444, + "frontend/src/lib/components/reports/__tests__/report_detail.integration.test.js": 4193615240297330385, + "venv/lib/python3.13/site-packages/referencing/exceptions.py": 2535322334430110414, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/mypy.ini": 4763385838822685881, + "frontend/build/_app/immutable/nodes/26.BpHj-_gK.js": 12667509163112762275, + "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/zip-safe": 15240312484046875203, + "venv/lib/python3.13/site-packages/authlib/common/errors.py": 16082974228565515177, + "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/ecdsa/eddsa.py": 15966858338456571506, + "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/METADATA": 3044554568188160018, + "backend/src/services/__tests__/test_health_service.py": 5498183976797488518, + "venv/lib/python3.13/site-packages/jeepney/io/blocking.py": 4699555965372200059, + "venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/METADATA": 14158024963562115116, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/dml.py": 6567627855667533645, + "frontend/build/_app/immutable/assets/AssistantChatPanel.D4L5jlt0.css": 10724144138366384732, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/plugin/pytestplugin.py": 1591034895268415944, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_dot.py": 16876560325283070437, + "frontend/static/favicon.svg": 6451919037497541980, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_datetime.py": 7862725028865965163, + "venv/lib/python3.13/site-packages/pycparser/c_parser.py": 3954138286651284327, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_3kcompat.h": 5377305123299457337, + "venv/lib/python3.13/site-packages/pandas/core/array_algos/transforms.py": 3773159138960141434, + "venv/lib/python3.13/site-packages/numpy/random/tests/test_generator_mt19937_regressions.py": 8981142329261965538, + "venv/lib/python3.13/site-packages/anyio/functools.py": 4300781896135050327, + "venv/lib/python3.13/site-packages/greenlet/greenlet_msvc_compat.hpp": 12504008513945919250, + "venv/lib/python3.13/site-packages/jeepney/tests/test_fds.py": 6257376331171761928, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_array_utils.py": 14682148205379122638, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_matmul.py": 16169282225324014901, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_csv.py": 6678500392137188521, + "venv/lib/python3.13/site-packages/pandas/_typing.py": 17795648994662434211, + "venv/lib/python3.13/site-packages/cffi/_cffi_include.h": 13094899814611950155, + "venv/lib/python3.13/site-packages/iniconfig/__init__.py": 12623265899068631092, + "venv/lib/python3.13/site-packages/greenlet/tests/fail_switch_three_greenlets.py": 10923534235697247269, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7592/endpoint.py": 18260428408051728802, + "venv/lib/python3.13/site-packages/pandas/tests/test_optional_dependency.py": 7930709646653025355, + "venv/lib/python3.13/site-packages/numpy/f2py/symbolic.py": 16854377502491291093, + "venv/lib/python3.13/site-packages/itsdangerous/__init__.py": 6969210114978365656, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_numpy_compat.py": 9112925138440787555, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_asfreq.py": 12721047184483392773, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_parse_dates.py": 7597935994945336408, + "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_readlines.py": 15928258358116399067, + "venv/lib/python3.13/site-packages/pandas/io/sas/__init__.py": 8095743504390517992, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/plugin.py": 16042078006552521613, + "venv/lib/python3.13/site-packages/PIL/_version.py": 3025206805667405876, + "backend/tests/test_dashboards_api.py": 2278794209397518464, + "frontend/build/_app/immutable/chunks/DSTrsXYC.js": 7992933864369085731, + "venv/lib/python3.13/site-packages/pandas/tests/frame/test_block_internals.py": 17935662848672401507, + "venv/lib/python3.13/site-packages/pydantic/_internal/_repr.py": 1758478941817868344, + "venv/lib/python3.13/site-packages/cryptography/hazmat/decrepit/ciphers/algorithms.py": 2375452080667815941, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_file_handling.py": 732772718210067599, + "frontend/build/_app/immutable/nodes/35.ClWaxdrE.js": 18139182329852451741, + "venv/lib/python3.13/site-packages/_pytest/legacypath.py": 7512065138259788426, + "venv/lib/python3.13/site-packages/pydantic/deprecated/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/base/test_transpose.py": 1686867045869336370, + "venv/lib/python3.13/site-packages/pip/_vendor/msgpack/ext.py": 15699809032725838985, + "venv/lib/python3.13/site-packages/cryptography/utils.py": 18088508841978595788, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_integer.f90": 8308927438994838783, + "frontend/build/_app/immutable/nodes/4.CzF7b7T3.js": 5413823557660901896, + "venv/lib/python3.13/site-packages/passlib/handlers/roundup.py": 3844280972451753019, + "venv/lib/python3.13/site-packages/pygments/lexers/graphviz.py": 15677908982985025500, + "venv/lib/python3.13/site-packages/numpy/lib/recfunctions.pyi": 10487441680587530350, + "venv/lib/python3.13/site-packages/_pytest/junitxml.py": 5871715626272366062, + "venv/lib/python3.13/site-packages/cffi/lock.py": 13507686939203117974, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_astype.py": 4975959187621745360, + "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_dtypes.py": 13065857166166716628, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/filter.py": 16846063190466267618, + "venv/lib/python3.13/site-packages/pandas/io/json/__init__.py": 12333505155070172626, + "venv/lib/python3.13/site-packages/packaging/licenses/_spdx.py": 16440031845441362300, + "backend/src/models/auth.py.bak": 7050478675360007060, + "venv/lib/python3.13/site-packages/_pytest/pytester_assertions.py": 1899505062406979663, + "venv/lib/python3.13/site-packages/pydantic/v1/generics.py": 1150594223414883339, + "venv/lib/python3.13/site-packages/starlette/_utils.py": 8384087194580626069, + "venv/lib/python3.13/site-packages/httpcore/_sync/interfaces.py": 1532245423878428608, + "venv/lib/python3.13/site-packages/pandas/_libs/window/indexers.pyi": 9911899303567570646, + "backend/src/core/auth/config.py": 8065625913451826937, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/nditer.py": 10038360623032425884, + "venv/lib/python3.13/site-packages/pygments/lexers/actionscript.py": 8829560731160428621, + "venv/lib/python3.13/site-packages/referencing/typing.py": 8296636464219681747, + "venv/lib/python3.13/site-packages/rapidfuzz/_common_py.py": 15410157970973169427, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/char.pyi": 13143560686049627445, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_date_range.py": 16128552513324017349, + "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/provider.py": 16463243654123731993, + "venv/lib/python3.13/site-packages/numpy/lib/_version.pyi": 10804755840730584157, + "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_missing.py": 1963705411068820866, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/exc.py": 1448374203226983757, + "backend/src/models/__tests__/test_report_models.py": 14916807060334836854, + "venv/lib/python3.13/site-packages/pip/_internal/models/installation_report.py": 14534544543677907640, + "venv/lib/python3.13/site-packages/keyring/testing/util.py": 11195868112805409554, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/sphinxext.py": 2403717774564798878, + "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/licenses/LICENSE.rst": 5960743202700406649, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/ndarrayobject.h": 7320510589635636690, + "venv/lib/python3.13/site-packages/numpy/_core/lib/npy-pkg-config/npymath.ini": 1071371630695963467, + "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/util.cpython-313-x86_64-linux-gnu.so": 12473903676666680134, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_dialect.py": 4700488504252803159, + "venv/lib/python3.13/site-packages/greenlet/TStackState.cpp": 16720079760074325527, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_indexing.py": 546024765756472196, + "venv/lib/python3.13/site-packages/jose/backends/__init__.py": 16581763658239070112, + "venv/lib/python3.13/site-packages/numpy/ctypeslib/_ctypeslib.py": 12636954896699095212, + "venv/lib/python3.13/site-packages/git/refs/__init__.py": 16246686106073400519, + "venv/lib/python3.13/site-packages/pydantic/deprecated/tools.py": 16466182352694741629, + "venv/lib/python3.13/site-packages/greenlet/slp_platformselect.h": 10428201768098464386, + "venv/lib/python3.13/site-packages/numpy/ma/testutils.pyi": 3899348061346041413, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/test_constructors.py": 9478848417896027917, + "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/INSTALLER": 17282701611721059870, + "backend/src/plugins/llm_analysis/__tests__/test_service.py": 9850768293526486431, + "venv/lib/python3.13/site-packages/pandas/tests/tslibs/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pygments/formatters/terminal256.py": 11473927781167132440, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/pkcs7.pyi": 2777456956260371820, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_nep50_promotions.py": 6318578947214302182, + "venv/lib/python3.13/site-packages/pandas/core/ops/dispatch.py": 7041711677358147534, + "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_array_ops.py": 6709502157317299163, + "venv/lib/python3.13/site-packages/pip/_internal/self_outdated_check.py": 991029278889407558, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/baked.py": 6911138208603240867, + "frontend/src/lib/components/reports/ReportsList.svelte": 15460090587871611258, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/aead.pyi": 13061638961405460334, + "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/cache.py": 3177663126928467950, + "venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/RECORD": 17594742868855466393, + "venv/lib/python3.13/site-packages/psycopg2/tz.py": 9966680685796585198, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/index_tricks.pyi": 6035507586990711471, + "venv/lib/python3.13/site-packages/pandas/tests/api/test_api.py": 13385690673368400635, + "venv/lib/python3.13/site-packages/uvicorn/middleware/message_logger.py": 14825516604555033580, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/bitwise_ops.pyi": 751490187478960891, + "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/METADATA": 3474626408138844944, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_info.py": 10615285239043745712, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_partial_slicing.py": 16219611534574666182, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_reduction.py": 1049551473665255648, + "venv/lib/python3.13/site-packages/sqlalchemy/pool/__init__.py": 4337679908168515343, + "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/WHEEL": 16097436423493754389, + "backend/src/api/routes/__init__.py": 9441391336360835840, + "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/RECORD": 6187512110158566509, + "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_delitem.py": 14336697139511118920, + "backend/src/services/clean_release/__tests__/test_compliance_orchestrator.py": 6332087444349093252, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/_numpyconfig.h": 18150055639397773687, + "venv/lib/python3.13/site-packages/pygments/lexers/hdl.py": 6772823608124143123, + "venv/lib/python3.13/site-packages/pygments/lexers/bqn.py": 11823648528816858738, + "venv/lib/python3.13/site-packages/git/objects/submodule/util.py": 8621897576747443758, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timedeltas.pyi": 3783371827926657291, + "venv/lib/python3.13/site-packages/numpy/random/mtrand.cpython-313-x86_64-linux-gnu.so": 16146459667121787202, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/isocintrin/isoCtests.f90": 6208802899442270399, + "venv/lib/python3.13/site-packages/rapidfuzz/__pyinstaller/__init__.py": 1229691061011958769, + "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/_toml_compat.py": 10196543528439925412, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/__init__.py": 293004106962245584, + "venv/lib/python3.13/site-packages/pyasn1/type/useful.py": 10313387611927801339, + "venv/lib/python3.13/site-packages/numpy/lib/_shape_base_impl.py": 16539612003028676816, + "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/licenses/COPYING": 15270149301471737292, + "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/_implementation.py": 12245524932757110911, + "venv/lib/python3.13/site-packages/cryptography/x509/ocsp.py": 17973800752927680404, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-log10.csv": 13441294827017400897, + "venv/lib/python3.13/site-packages/pandas/tests/generic/test_generic.py": 1297407268239966429, + "venv/lib/python3.13/site-packages/pycparser/ply/yacc.py": 4218889705926129841, + "venv/lib/python3.13/site-packages/jeepney/tests/test_bus_messages.py": 4323093138307306385, + "venv/lib/python3.13/site-packages/pip/_internal/metadata/importlib/_dists.py": 16746363359320577809, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_defchararray.py": 15135904718007443306, + "venv/lib/python3.13/site-packages/pygments/lexers/dotnet.py": 17970884907837213099, + "frontend/src/lib/components/translate/CorrectionCell.svelte": 11242772726843637793, + "venv/lib/python3.13/site-packages/_pytest/outcomes.py": 12782895027812738142, + "venv/lib/python3.13/site-packages/pandas/io/parsers/__init__.py": 11752833703934347122, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/coercions.py": 5112358449376598662, + "backend/src/core/task_manager/__init__.py": 15991802770215124472, + "venv/lib/python3.13/site-packages/passlib/handlers/sha2_crypt.py": 8171587560325812664, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_resolution.py": 9651416588266430520, + "venv/lib/python3.13/site-packages/numpy/core/defchararray.py": 11371045148957547088, + "venv/lib/python3.13/site-packages/pip/_internal/cli/base_command.py": 10660882478126415399, + "backend/src/services/clean_release/__tests__/test_preparation_service.py": 4958420988131940633, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_sorted.py": 1899608688401238388, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_update_delete.py": 1317337950621091021, + "venv/lib/python3.13/site-packages/pandas/_libs/join.pyi": 369262334342439364, + "venv/lib/python3.13/site-packages/pygments/formatters/bbcode.py": 8614391937525677922, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/schema.py": 8358664670620586363, + "frontend/src/components/llm/__tests__/provider_config.integration.test.js": 12605115626277870995, + "venv/lib/python3.13/site-packages/pandas/tests/computation/test_compat.py": 11655000938111420543, + "frontend/build/_app/immutable/nodes/32.BQVcp1Fc.js": 17523113223503452911, + "venv/lib/python3.13/site-packages/greenlet/_greenlet.cpython-313-x86_64-linux-gnu.so": 6036818030377883416, + "venv/lib/python3.13/site-packages/authlib/integrations/django_client/integration.py": 13610682193839598457, + "venv/lib/python3.13/site-packages/_pytest/faulthandler.py": 13329320306353718649, + "venv/lib/python3.13/site-packages/pandas/_libs/hashtable.pyi": 15034917167424979097, + "backend/src/services/clean_release/repositories/artifact_repository.py": 9040122866024534865, + "venv/lib/python3.13/site-packages/pygments/cmdline.py": 15628499088643246809, + "frontend/src/components/Toast.svelte": 340258331315696736, + "venv/lib/python3.13/site-packages/pygments/lexers/matlab.py": 1880915927722177654, + "venv/lib/python3.13/site-packages/numpy/f2py/func2subr.py": 338595621218646492, + "venv/lib/python3.13/site-packages/numpy/polynomial/_polytypes.pyi": 7528777458251688517, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_setops.py": 8622608042929141013, + "venv/lib/python3.13/site-packages/requests/utils.py": 17045260098091371478, + "frontend/src/routes/admin/settings/llm/+page.svelte": 8015678318492837753, + "frontend/build/_app/immutable/nodes/29.BgDRJ3OZ.js": 14521731666892374966, + "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/json.py": 15373167408891671190, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/filepost.py": 16698380375728063923, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh18335.f90": 1126438609189294255, + "frontend/src/components/Footer.svelte": 17748559656923032, + "backend/src/services/clean_release/repositories/policy_repository.py": 10990781278715170404, + "venv/lib/python3.13/site-packages/jsonschema/protocols.py": 847332300543820834, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_csv.py": 571991535656576735, + "venv/lib/python3.13/site-packages/_pytest/_code/source.py": 9488112979192923739, + "venv/lib/python3.13/site-packages/websockets/auth.py": 499195617702591757, + "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_masked_matrix.py": 1444179242134203344, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_timedeltas.py": 4118671843063545221, + "backend/src/services/clean_release/dto.py": 11031410734734770552, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/scalars.pyi": 17683675356659300769, + "venv/lib/python3.13/site-packages/more_itertools/__init__.py": 9858612105173082060, + "venv/lib/python3.13/site-packages/websockets/asyncio/async_timeout.py": 7267209982032642028, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/__init__.py": 13841777369501476946, + "venv/lib/python3.13/site-packages/passlib/context.py": 10362592407593745107, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_append.py": 17016125916761365423, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/Prefix_py.py": 17041764258638228993, + "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_openssl.py": 10446441599800965961, + "venv/lib/python3.13/site-packages/numpy/ma/tests/test_mrecords.py": 15952147778503828707, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_longdouble.py": 9337218715436213122, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_reduction.py": 2671872764983553906, + "backend/src/api/routes/assistant/_dispatch.py": 3811422882986895565, + "venv/lib/python3.13/site-packages/_pytest/_io/__init__.py": 1510478951261938348, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/frequencies/test_freq_code.py": 13758353172962109140, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/wait.py": 6196757964348666082, + "venv/lib/python3.13/site-packages/pycparser/ply/__init__.py": 5040371336745852622, + "backend/src/services/profile_service.py": 10016788771873430731, + "venv/lib/python3.13/site-packages/numpy/f2py/__init__.pyi": 3566887042414273892, + "venv/lib/python3.13/site-packages/pygments/lexers/textfmts.py": 17438453283146671997, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/constant_time.py": 2499026008403328245, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_both.f90": 13943066317159236257, + "venv/lib/python3.13/site-packages/fastapi/_compat/v2.py": 15078491685917047095, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_casting_floatingpoint_errors.py": 4301355720042319835, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/requests.py": 1102963893193914979, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/offsets.pyi": 13173581775000480811, + "venv/lib/python3.13/site-packages/pandas/core/dtypes/cast.py": 342228968652072052, + "venv/lib/python3.13/site-packages/numpy/core/getlimits.py": 14257687540182552408, + "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/licenses/LICENSE": 16499431172938528491, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/_initialize_cpp.cpython-313-x86_64-linux-gnu.so": 7490281502544276964, + "venv/lib/python3.13/site-packages/numpy/_core/multiarray.py": 4484782354376574355, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_apply.py": 11248068903302454630, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_twodim_base.py": 17623133613018058380, + "venv/lib/python3.13/site-packages/psycopg2/pool.py": 8855184580138330938, + "venv/lib/python3.13/site-packages/pip/_vendor/tomli/py.typed": 9796674040111366709, + "venv/lib/python3.13/site-packages/numpy/f2py/rules.py": 9322914583460630877, + "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/packaging/__init__.py": 5479277484104486860, + "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_ssl_constants.py": 14834514243239777933, + "venv/lib/python3.13/site-packages/numpy/random/_examples/numba/extending.py": 16515485226251040454, + "venv/lib/python3.13/site-packages/numpy/ma/LICENSE": 6723325434476453127, + "venv/lib/python3.13/site-packages/websockets/extensions/permessage_deflate.py": 12957105912018691390, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_groupby_shift_diff.py": 1210657479716368827, + "venv/lib/python3.13/site-packages/passlib/tests/test_apps.py": 10454136535890937237, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/type_api.py": 10299750173867399533, + "venv/lib/python3.13/site-packages/pycparser/lextab.py": 16045770806700381661, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/Hamming.pyi": 4432290176776357346, + "venv/lib/python3.13/site-packages/cffi/parse_c_type.h": 9889309594462820068, + "venv/lib/python3.13/site-packages/pandas/_libs/algos.cpython-313-x86_64-linux-gnu.so": 15706331654215762588, + "venv/lib/python3.13/site-packages/yaml/events.py": 745772917931702910, + "venv/lib/python3.13/site-packages/numpy/tests/test_reloading.py": 17532116685329953400, + "venv/lib/python3.13/site-packages/charset_normalizer/__init__.py": 12412600648990392633, + "backend/src/core/utils/superset_context_extractor/_parsing.py": 17093712504833649098, + "venv/lib/python3.13/site-packages/pandas/core/groupby/generic.py": 4857114071347950833, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/usecols/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_timedeltaindex.py": 2359681317403710563, + "venv/lib/python3.13/site-packages/pandas/core/reshape/api.py": 16364136812252343076, + "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/core": 10616484054735611337, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/exceptions.py": 7518613450390473990, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh24008.f": 3872245077994936272, + "venv/lib/python3.13/site-packages/fastapi/concurrency.py": 17937688838625807004, + "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/sum_.py": 7062070517544958546, + "venv/lib/python3.13/site-packages/rsa/common.py": 10921682819204792805, + "venv/lib/python3.13/site-packages/bcrypt/_bcrypt.abi3.so": 8691731321358529264, + "venv/lib/python3.13/site-packages/numpy/_configtool.pyi": 9670892208858157218, + "venv/lib/python3.13/site-packages/pandas/core/array_algos/take.py": 3170415198452493008, + "venv/lib/python3.13/site-packages/pandas/tests/computation/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/window/test_base_indexer.py": 3129123098288498633, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_astype.py": 15275720655739710249, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_interval_pyarrow.py": 3849382723890414899, + "venv/lib/python3.13/site-packages/numpy/random/tests/data/generator_pcg64_np121.pkl.gz": 4708588000144933291, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/types.py": 16795741817129898714, + "venv/lib/python3.13/site-packages/PIL/FtexImagePlugin.py": 8196606399875185931, + "venv/lib/python3.13/site-packages/yaml/reader.py": 9873075843010693205, + "venv/lib/python3.13/site-packages/PIL/GribStubImagePlugin.py": 14954946414134984896, + "venv/lib/python3.13/site-packages/httpcore/_models.py": 2501866419898326733, + "frontend/build/_app/immutable/chunks/BIIQCMQD.js": 10069504695005052902, + "backend/src/api/routes/translate/_router.py": 4164547666727936398, + "backend/src/plugins/storage/__init__.py": 5046554941488079204, + "venv/lib/python3.13/site-packages/_pytest/config/argparsing.py": 11156052029258891503, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/_initialize.py": 15511055314565873928, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/_serialization.py": 2011519400081029270, + "venv/lib/python3.13/site-packages/numpy/lib/_nanfunctions_impl.pyi": 12566839271245057531, + "venv/lib/python3.13/site-packages/passlib/handlers/argon2.py": 835074952952017434, + "venv/lib/python3.13/site-packages/starlette/formparsers.py": 9019779181100355515, + "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_list_accessor.py": 8613662386779664039, + "venv/lib/python3.13/site-packages/sqlalchemy/connectors/__init__.py": 17194870661869873083, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_common.h": 14732581790650403546, + "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_indexing.py": 14461606056665485421, + "venv/lib/python3.13/site-packages/pip/_vendor/requests/certs.py": 13366788049827102313, + "venv/lib/python3.13/site-packages/numpy/tests/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_pydatetime.py": 16228315407662560992, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_skiprows.py": 8764515842253490735, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_explode.py": 16195468192763502449, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_data_list.py": 1131520422778420758, + "venv/lib/python3.13/site-packages/pandas/io/excel/_calamine.py": 13354427767660487637, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_routines.py": 4860173574365060471, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/screen.py": 6933591906297023845, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/strategy_options.py": 16342048970907383117, + "venv/lib/python3.13/site-packages/fastapi/dependencies/utils.py": 7687214523082385505, + "venv/lib/python3.13/site-packages/numpy/random/tests/data/mt19937-testset-1.csv": 16349400027062875699, + "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/filewrapper.py": 17786759398959482432, + "venv/lib/python3.13/site-packages/pydantic/validators.py": 8292819706488319845, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/authorization_code.py": 4958605540994687737, + "venv/lib/python3.13/site-packages/_pytest/pathlib.py": 9719734558816066453, + "venv/lib/python3.13/site-packages/numpy/f2py/_isocbind.py": 15031197044862908440, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/assumed_shape/foo_mod.f90": 5765181406654284736, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/operators.py": 5584982192355398255, + "venv/lib/python3.13/site-packages/pygments/lexers/data.py": 9365024327689738663, + "frontend/src/routes/dashboards/+page.svelte": 7340914202224737248, + "backend/src/services/clean_release/manifest_builder.py": 17216832960644499305, + "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_liboffsets.py": 14705822637347212540, + "venv/lib/python3.13/site-packages/pip/_internal/commands/show.py": 11839987586497822300, + "venv/lib/python3.13/site-packages/pip/_internal/utils/subprocess.py": 3095012838116670328, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_stringdtype.py": 8381476847196129074, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_dtype.py": 5336980126536664360, + "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/RECORD": 11604408378998955169, + "venv/lib/python3.13/site-packages/pandas/tests/series/test_constructors.py": 6515602441449955627, + "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/errors.py": 12935154705443176852, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_missing.py": 6224750552277937853, + "venv/lib/python3.13/site-packages/itsdangerous/encoding.py": 205863946173486958, + "venv/lib/python3.13/site-packages/pydantic/deprecated/parse.py": 819235411736647763, + "venv/lib/python3.13/site-packages/greenlet/TGreenletGlobals.cpp": 17400526028982558937, + "frontend/src/routes/settings/connections/+page.svelte": 276661107137418305, + "venv/lib/python3.13/site-packages/greenlet/tests/test_contextvars.py": 6077482318964702132, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7515/models.py": 17356033861792227817, + "venv/lib/python3.13/site-packages/referencing/retrieval.py": 11921179805977833120, + "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/resource_protector.py": 3563910821279222695, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/theme.py": 14225878259183479398, + "venv/lib/python3.13/site-packages/idna/core.py": 7725813731640753267, + "venv/lib/python3.13/site-packages/passlib/handlers/django.py": 66638338316838351, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_cov_corr.py": 8117511855230249212, + "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_manylinux.py": 12272275001961360101, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/engines.py": 10876954465293959720, + "frontend/build/_app/immutable/nodes/0.Dy6ixPTE.js": 12881323989915888235, + "venv/lib/python3.13/site-packages/numpy/lib/_user_array_impl.pyi": 7171810177801103765, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/aioodbc.py": 12704729841432715246, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/ansi.py": 948249091929588017, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_getlimits.py": 118041882543413669, + "venv/lib/python3.13/site-packages/pip/_internal/resolution/legacy/resolver.py": 2492962412506082234, + "frontend/build/_app/immutable/chunks/DSaq_U9T.js": 18007300971386663499, + "venv/lib/python3.13/site-packages/pandas/tests/reductions/test_reductions.py": 11624188672428941494, + "backend/src/api/routes/dashboards/_listing_routes.py": 1750634467656242702, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/plugin/plugin_base.py": 2880434680251108786, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7519/__init__.py": 16532856661318424631, + "venv/lib/python3.13/site-packages/python_multipart/exceptions.py": 5971058243218049183, + "venv/lib/python3.13/site-packages/pandas/io/parsers/base_parser.py": 15148258424429418380, + "venv/lib/python3.13/site-packages/idna/uts46data.py": 5698404064763638591, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/evaluator.py": 6348022789899831255, + "venv/lib/python3.13/site-packages/starlette/status.py": 16192064443996706569, + "venv/lib/python3.13/site-packages/sqlalchemy/engine/interfaces.py": 4890958419958257958, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc64_aix.h": 8706347224105630468, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/comparisons.pyi": 4158883009780474220, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ndarray_assignability.pyi": 1718610984396277997, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/_typing.py": 17598638528781632158, + "venv/lib/python3.13/site-packages/git/remote.py": 1694919255653049944, + "venv/lib/python3.13/site-packages/jsonschema/tests/test_deprecations.py": 16367195310156359251, + "venv/lib/python3.13/site-packages/smmap/mman.py": 9091562788592406032, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/events.py": 7576713358952064464, + "venv/lib/python3.13/site-packages/jaraco/context/__init__.py": 10975097417056278427, + "venv/lib/python3.13/site-packages/pandas/util/version/__init__.py": 3844072588696074141, + "venv/lib/python3.13/site-packages/pycparser/ast_transforms.py": 9032453625977464506, + "venv/lib/python3.13/site-packages/jsonschema/tests/test_exceptions.py": 15290185665769490169, + "venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/RECORD": 173225030102092319, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7636/__init__.py": 913610541217778747, + "venv/lib/python3.13/site-packages/numpy/_core/__init__.pyi": 2783897020308040960, + "venv/lib/python3.13/site-packages/keyring/compat/properties.py": 1562771115138037410, + "venv/lib/python3.13/site-packages/pluggy/_hooks.py": 6941854999025808196, + "venv/lib/python3.13/site-packages/pip/_internal/operations/check.py": 16650663913976953800, + "venv/lib/python3.13/site-packages/_pytest/tmpdir.py": 10834220332037364219, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_datetimelike.py": 10294379314868108649, + "venv/lib/python3.13/site-packages/numpy/lib/_stride_tricks_impl.py": 5260748170237305627, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_arithmetic.py": 13304014482504911016, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_formats.py": 12299393760307251036, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_deprecate.py": 16723865897349422996, + "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/licenses/COPYING": 14459782230785388765, + "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/adapter.py": 5908944827805063108, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/websockets/legacy/server.py": 5390090919193784186, + "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_timedeltas.py": 1175883320586860493, + "venv/lib/python3.13/site-packages/fastapi/security/open_id_connect_url.py": 3502444317759870079, + "venv/lib/python3.13/site-packages/keyring/errors.py": 4587094338672775040, + "venv/lib/python3.13/site-packages/PIL/ImagePath.py": 18323293175183057101, + "venv/lib/python3.13/site-packages/PIL/FpxImagePlugin.py": 18245056799205041866, + "venv/lib/python3.13/site-packages/httpcore/_async/http_proxy.py": 13364803556177997526, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/decl_api.py": 5287018911951723034, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_repeat.py": 11360772447747837958, + "venv/lib/python3.13/site-packages/fastapi/security/api_key.py": 6965937678104291169, + "venv/lib/python3.13/site-packages/pip/_internal/vcs/subversion.py": 7423946096970870727, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/nditer.pyi": 33523064068376750, + "venv/lib/python3.13/site-packages/numpy/polynomial/chebyshev.pyi": 5269136485429780038, + "venv/lib/python3.13/site-packages/pandas/core/computation/eval.py": 3176226283265954028, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/io/clipboard/__init__.py": 3656451154829206939, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/ext.py": 8361831054662096695, + "venv/lib/python3.13/site-packages/pygments/styles/staroffice.py": 11694998942433220413, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/__main__.py": 111505188798650285, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_2_complexcompat.h": 5001035774408914877, + "venv/lib/python3.13/site-packages/jsonschema/benchmarks/nested_schemas.py": 4114645644496880787, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test__exceptions.py": 12099001631178696189, + "venv/lib/python3.13/site-packages/pandas/_libs/writers.cpython-313-x86_64-linux-gnu.so": 6878855127769203372, + "venv/lib/python3.13/site-packages/sqlalchemy/engine/mock.py": 14010776046610111182, + "venv/lib/python3.13/site-packages/pip/_vendor/packaging/tags.py": 254599446317461188, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_indexing.py": 1926721846569184112, + "venv/lib/python3.13/site-packages/pip/_vendor/pkg_resources/__init__.py": 1677532855362260338, + "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/licenses/LICENSE": 5669644120528099197, + "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pydantic/_internal/_namespace_utils.py": 5237766366340181382, + "venv/lib/python3.13/site-packages/pygments/styles/algol.py": 3040373291664740876, + "venv/lib/python3.13/site-packages/numpy/core/records.py": 12604652690721760437, + "venv/lib/python3.13/site-packages/numpy/f2py/cb_rules.pyi": 12275242654430570028, + "venv/bin/pyrsa-sign": 15564653706771700451, + "venv/lib/python3.13/site-packages/pygments/styles/solarized.py": 11231143047572616298, + "frontend/src/lib/components/assistant/__tests__/assistant_clarification.integration.test.js": 12258270009984504212, + "frontend/src/lib/components/reports/__tests__/reports_list.ux.test.js": 16252194679528846126, + "frontend/src/lib/components/reports/__tests__/fixtures/reports.fixtures.js": 10647302793388244094, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/numerictypes.pyi": 15565573472138344755, + "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/REQUESTED": 15130871412783076140, + "frontend/src/routes/translate/+page.svelte": 11304227812217935067, + "frontend/src/app.css": 3020720639702954139, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/timeout.py": 1807228452024740476, + "backend/src/plugins/translate/__tests__/test_token_budget.py": 9060506557524997011, + "backend/tests/test_smoke_app.py": 7819901244710945164, + "backend/alembic/versions/8dd0a93af539_drop_deprecated_source_language_column_.py": 3574830605384611294, + "venv/lib/python3.13/site-packages/annotated_types/test_cases.py": 5123395674810472016, + "backend/tests/core/test_migration_engine.py": 7419155921858935534, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/warnings.py": 2552021607611112605, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/entities.py": 8001287806688585081, + "frontend/src/lib/components/assistant/__tests__/assistant_first_message.integration.test.js": 16494645867501045726, + "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/cython/setup.py": 17086801293303202021, + "venv/lib/python3.13/site-packages/httpcore/_async/socks_proxy.py": 9026788710898138090, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_timestamp.py": 12253372102602993034, + "venv/lib/python3.13/site-packages/pydantic/types.py": 785880062468926292, + "venv/lib/python3.13/site-packages/idna/__init__.py": 6489437464172324468, + "venv/lib/python3.13/site-packages/authlib/deprecate.py": 3563885283090710443, + "venv/lib/python3.13/site-packages/authlib/oauth1/client.py": 7314311571224771, + "venv/lib/python3.13/site-packages/_pytest/assertion/util.py": 16957445183087315124, + "venv/lib/python3.13/site-packages/pandas/api/types/__init__.py": 3995030354191071797, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/pg8000.py": 6580512354643849828, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/progress.py": 5951745251426856398, + "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/authlib/oauth2/auth.py": 8455258275234626534, + "venv/lib/python3.13/site-packages/pip/_internal/utils/deprecation.py": 7435269308988385470, + "venv/lib/python3.13/site-packages/git/refs/remote.py": 4391983355222612205, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/spinner.py": 5564789578696016201, + "venv/lib/python3.13/site-packages/pycparser/plyparser.py": 5251740466238035035, + "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py2-objarr.npy": 9694707264403109829, + "venv/lib/python3.13/site-packages/pandas/core/util/hashing.py": 13106575357604888913, + "venv/lib/python3.13/site-packages/dateutil/__init__.py": 17666544837260663800, + "backend/src/core/superset_client/_datasets_preview.py": 16476837380317508068, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/exclusions.py": 15852672500377116297, + "venv/lib/python3.13/site-packages/httpcore/_sync/http11.py": 5947339024588907032, + "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/METADATA": 5045041742469375466, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/keys.pyi": 1846673463183660140, + "venv/lib/python3.13/site-packages/pygments/styles/lovelace.py": 15082819162722685616, + "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/applicator": 6616723520993329538, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7591/claims.py": 11853156183819186599, + "venv/lib/python3.13/site-packages/h11/_connection.py": 6971907312737339559, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/token.py": 11655733747403312358, + "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/WHEEL": 12146818530001975731, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_loc.py": 2127584756555503873, + "venv/lib/python3.13/site-packages/rsa/pkcs1.py": 2576732594642491910, + "venv/lib/python3.13/site-packages/greenlet/tests/_test_extension_cpp.cpp": 4590574206187223887, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_non_compound.f90": 8048650253889213460, + "venv/lib/python3.13/site-packages/numpy/__config__.pyi": 1422114139050700402, + "venv/lib/python3.13/site-packages/ecdsa/rfc6979.py": 11564966030899162026, + "venv/lib/python3.13/site-packages/cryptography/hazmat/_oid.py": 755042927629281577, + "venv/lib/python3.13/site-packages/idna/compat.py": 9758194415584776667, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_append.py": 13152738905565588661, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_astype.py": 16700461036658228009, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/dynamic.py": 15220116196072524330, + "backend/src/api/routes/git/_repo_routes.py": 7367823490321383813, + "venv/lib/python3.13/site-packages/pandas/_libs/hashing.cpython-313-x86_64-linux-gnu.so": 16124435225170610034, + "venv/lib/python3.13/site-packages/httpcore/_exceptions.py": 6716590711697088732, + "backend/src/models/git.py": 6898938895423263836, + "venv/lib/python3.13/site-packages/numpy/f2py/common_rules.pyi": 2104100025130695295, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/ma/extras.pyi": 15292036493781556342, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ufunc_config.pyi": 2005481648919369399, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/box.py": 14303526978791498662, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/Indel_py.py": 9112851333217812996, + "venv/lib/python3.13/site-packages/pandas/plotting/_misc.py": 10202078355301731720, + "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/hybrid.py": 14287665090144592501, + "venv/lib/python3.13/site-packages/pandas/compat/numpy/__init__.py": 1037113402100731082, + "venv/lib/python3.13/site-packages/pygments/scanner.py": 5640381644804445932, + "venv/lib/python3.13/site-packages/numpy/fft/_pocketfft.pyi": 1521384724035973688, + "venv/lib/python3.13/site-packages/numpy/linalg/tests/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/rsa/asn1.py": 3861968161559322784, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_tz_convert.py": 13349243029437881949, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_setops.py": 16240008859650640717, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_categorical.py": 8844412630511751140, + "venv/lib/python3.13/site-packages/numpy/core/shape_base.py": 17925759824894973734, + "venv/lib/python3.13/site-packages/PIL/FitsImagePlugin.py": 618556384932056120, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/terminal_theme.py": 13727399800263579809, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/type_check.pyi": 9177256991985898824, + "venv/lib/python3.13/site-packages/pandas/core/sparse/__init__.py": 15130871412783076140, + "backend/src/core/plugin_loader.py": 245217431000027879, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/key_set.py": 8485970749081951741, + "venv/lib/python3.13/site-packages/apscheduler/schedulers/gevent.py": 4811840397266785551, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_periodindex.py": 13430003945574795792, + "venv/lib/python3.13/site-packages/greenlet/TThreadStateCreator.hpp": 9887867766190459665, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_constructors.py": 9767900500541600486, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/shape_base.pyi": 10291383658131961346, + "venv/lib/python3.13/site-packages/anyio/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/PIL/ImagePalette.py": 9227837918026991107, + "venv/lib/python3.13/site-packages/PIL/ImageSequence.py": 16459886231802763032, + "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/misc.py": 6571241778569465264, + "frontend/src/lib/components/assistant/AssistantClarificationCard.svelte": 15872391111837089374, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_tolist.py": 8343058000369672317, + "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_function.py": 7048185308307653546, + "venv/lib/python3.13/site-packages/apscheduler/schedulers/tornado.py": 6491136785917169991, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/unitofwork.py": 3177255974394221645, + "venv/lib/python3.13/site-packages/pip/_internal/commands/cache.py": 1892313355296776523, + "frontend/build/_app/immutable/chunks/BAz4bHMQ.js": 13333198678504989936, + "venv/lib/python3.13/site-packages/jeepney/io/tests/conftest.py": 13381752264278264218, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/assertion.py": 5287436128235488464, + "venv/lib/python3.13/site-packages/numpy/_core/_rational_tests.cpython-313-x86_64-linux-gnu.so": 13475521165331256711, + "venv/lib/python3.13/site-packages/ecdsa/test_sha3.py": 12459459298663975730, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/claims.py": 14794441479740527265, + "venv/lib/python3.13/site-packages/pip/_internal/commands/completion.py": 4435231315212798769, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7516/__init__.py": 11121941644106061453, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_histograms.py": 47631283818191049, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_indexing.py": 9988098331562906950, + "venv/lib/python3.13/site-packages/PIL/_imagingmorph.pyi": 18222325750818585549, + "venv/lib/python3.13/site-packages/pygments/lexers/yang.py": 7409365668425173823, + "venv/lib/python3.13/site-packages/PIL/JpegPresets.py": 12342262642420923471, + "venv/lib/python3.13/site-packages/six.py": 948867418687428421, + "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py3-objarr.npy": 17303060773267383537, + "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/licenses/LICENSE.APACHE": 11041304845352917971, + "venv/lib/python3.13/site-packages/greenlet/greenlet.h": 16216120538647882082, + "venv/lib/python3.13/site-packages/dotenv/version.py": 13508433229287636267, + "venv/lib/python3.13/site-packages/attr/filters.pyi": 13942974755090135724, + "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/astype_copy.pkl": 4470155972891419163, + "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/_impl.py": 16610770935842519289, + "venv/lib/python3.13/site-packages/pandas/core/interchange/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/fastapi/dependencies/models.py": 8626894872248212015, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/__main__.py": 487896753130729554, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_categorical.py": 18254320571347851153, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/conftest.py": 16571782049241458769, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/test_reductions.py": 8258332365408303156, + "venv/lib/python3.13/site-packages/numpy/polynomial/hermite_e.py": 3654583356259850174, + "venv/lib/python3.13/site-packages/pandas/tests/window/test_rolling.py": 18221459425751198218, + "venv/lib/python3.13/site-packages/pandas/core/dtypes/common.py": 10996276696597806957, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/strings.pyi": 15361498560917514616, + "venv/lib/python3.13/site-packages/psycopg2/errorcodes.py": 6711830404954314463, + "venv/lib/python3.13/site-packages/keyring/backends/null.py": 12740996416911604870, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/datonly.f90": 10495925225338237742, + "venv/lib/python3.13/site-packages/greenlet/tests/fail_cpp_exception.py": 11851283355840567373, + "venv/lib/python3.13/site-packages/websockets/legacy/auth.py": 16685128086396181286, + "venv/lib/python3.13/site-packages/keyring/cli.py": 10996746519742056101, + "venv/lib/python3.13/site-packages/pluggy/_callers.py": 1042673447718196223, + "venv/lib/python3.13/site-packages/pillow.libs/libzstd-761a17b6.so.1.5.7": 17875236748140157032, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_dict_of_blocks.py": 11646835537993064324, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge.py": 11366935134260232329, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_store.py": 1500300322083708794, + "venv/lib/python3.13/site-packages/yaml/error.py": 5626374410579058436, + "venv/lib/python3.13/site-packages/yaml/parser.py": 18021832376874455801, + "venv/lib/python3.13/site-packages/starlette/__init__.py": 3252794766897205870, + "frontend/src/routes/datasets/review/__tests__/dataset_review_entry.ux.test.js": 5439236328736424365, + "venv/lib/python3.13/site-packages/pandas/_libs/tslib.cpython-313-x86_64-linux-gnu.so": 10742615805788605480, + "venv/lib/python3.13/site-packages/git/__init__.py": 15867730798565725003, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_tz_localize.py": 18409231586451494605, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_data.py": 2397937327057341, + "venv/lib/python3.13/site-packages/pydantic/_internal/_validate_call.py": 4078236486720616395, + "venv/lib/python3.13/site-packages/httpx/_models.py": 6516278895118988231, + "venv/lib/python3.13/site-packages/jose/backends/_asn1.py": 14123487576864105793, + "backend/src/services/reports/normalizer.py": 11408466232944555336, + "venv/lib/python3.13/site-packages/jsonschema_specifications/__init__.py": 5732822354953774657, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_converters.py": 8869440774594127419, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/session.py": 5126234270435358377, + "venv/lib/python3.13/site-packages/keyring/__init__.py": 991260689223167957, + "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_legendre.py": 18266595775500927868, + "venv/lib/python3.13/site-packages/pip/_vendor/distlib/manifest.py": 16998683210177680416, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh25286.pyf": 14358606965464506398, + "venv/lib/python3.13/site-packages/pandas/_config/config.py": 1494288055210911451, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_round.py": 1299086932398824299, + "venv/lib/python3.13/site-packages/pydantic/v1/types.py": 10761779263335288559, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/numerictypes.pyi": 15443101937711720707, + "venv/lib/python3.13/site-packages/numpy/f2py/_isocbind.pyi": 5786150108623563787, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/conftest.py": 3691712173202219606, + "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/zip-safe": 15240312484046875203, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_reindex.py": 15794750188594767026, + "venv/lib/python3.13/site-packages/pip/_internal/commands/help.py": 4175797322922912326, + "venv/lib/python3.13/site-packages/pip/_internal/locations/base.py": 7966628150470073365, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_numeric.py": 9383693732009547935, + "venv/lib/python3.13/site-packages/pydantic/datetime_parse.py": 196119761382305574, + "venv/lib/python3.13/site-packages/pandas/tests/window/test_apply.py": 7511915990531229598, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_compare.py": 3079569478684646491, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/styles/_mapping.py": 11752660241391232497, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_is_unique.py": 3989602816674881215, + "venv/lib/python3.13/site-packages/urllib3-2.6.2.dist-info/RECORD": 15194367076254806710, + "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/METADATA": 6557531107125553027, + "venv/lib/python3.13/site-packages/packaging/_tokenizer.py": 7442392076059866359, + "frontend/src/components/backups/BackupManager.svelte": 15722995371746548624, + "backend/src/api/routes/__tests__/test_git_status_route.py": 6306531435114264696, + "venv/lib/python3.13/site-packages/pip/_internal/utils/entrypoints.py": 11268059714209889385, + "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/LICENSE": 2032205056284080825, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_indexers.py": 6773751569163287047, + "backend/src/plugins/search.py": 888817404897740233, + "venv/lib/python3.13/site-packages/pygments/lexers/_scilab_builtins.py": 17453812809700086888, + "frontend/src/routes/profile/__tests__/profile-preferences.integration.test.js": 6561454515118560091, + "venv/lib/python3.13/site-packages/pandas/tests/strings/test_cat.py": 15988884721768567895, + "venv/lib/python3.13/site-packages/pygments/formatters/_mapping.py": 13335227913146542481, + "logs/app.log.1": 15453131390328548426, + "venv/lib/python3.13/site-packages/pandas/tests/series/test_subclass.py": 13490541871827928531, + "venv/lib/python3.13/site-packages/keyring/testing/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/anyio/_core/_eventloop.py": 6853955946028131785, + "venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/numpy/_typing/_dtype_like.py": 1598511035344858524, + "venv/lib/python3.13/site-packages/anyio/_backends/_trio.py": 4764555436057754985, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/padding.py": 11244071766694094554, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/shape.pyi": 2188930129299348535, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_assumed_shape.py": 18361009188431483164, + "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_object.py": 9215781825358309147, + "venv/lib/python3.13/site-packages/fastapi/testclient.py": 2606236077497278662, + "venv/lib/python3.13/site-packages/_pytest/doctest.py": 6126919596776592278, + "venv/lib/python3.13/site-packages/pydantic/_internal/_mock_val_ser.py": 12265320534388472158, + "venv/lib/python3.13/site-packages/numpy/_core/multiarray.pyi": 3494871767602648807, + "venv/lib/python3.13/site-packages/authlib/integrations/sqla_oauth2/functions.py": 14107377669163193871, + "venv/lib/python3.13/site-packages/pandas/io/sql.py": 12592024569011796790, + "venv/lib/python3.13/site-packages/yaml/nodes.py": 3463622922914760653, + "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/WHEEL": 7454950858448014158, + "venv/lib/python3.13/site-packages/anyio/_core/_signals.py": 1204322949639513552, + "venv/lib/python3.13/site-packages/pygments/formatters/__init__.py": 8009871891954370829, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/dtypes/test_empty.py": 6845813091876023610, + "frontend/src/routes/dashboards/[id]/+page.svelte": 1225758611896418118, + "frontend/src/routes/settings/+page.svelte": 3103346197225933395, + "venv/lib/python3.13/site-packages/authlib/jose/drafts/_jwe_enc_cryptography.py": 4383854709657749855, + "venv/lib/python3.13/site-packages/numpy/ma/tests/test_subclassing.py": 17318983445227658412, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/bitwise_ops.py": 14350609278188982939, + "venv/lib/python3.13/site-packages/cffi/_cffi_errors.h": 1479575326813300292, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_fillna.py": 13675584998644907265, + "venv/lib/python3.13/site-packages/charset_normalizer/utils.py": 11724147997933584095, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_map.py": 10769974470610467636, + "venv/lib/python3.13/site-packages/pandas/tests/strings/test_string_array.py": 8260883866404398980, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_replace.py": 15992095120302643273, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_iterator.py": 13869355993837330406, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_stack.py": 5316826578695144945, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_index_tricks.py": 4676293127859087991, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pygments/lexers/lisp.py": 11872331622183590758, + "frontend/src/lib/components/health/HealthMatrix.svelte": 16085178486788467644, + "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_distutils.py": 1948707545068786, + "frontend/src/routes/+layout.svelte": 2748734957389681795, + "backend/src/core/__init__.py": 8673978627093182792, + "backend/src/models/mapping.py": 9358348320550260098, + "venv/lib/python3.13/site-packages/git/repo/fun.py": 9019364012746153312, + "venv/lib/python3.13/site-packages/pandas/_libs/algos.pyi": 22405377601029952, + "venv/lib/python3.13/site-packages/charset_normalizer/md.cpython-313-x86_64-linux-gnu.so": 1835299664481804968, + "venv/lib/python3.13/site-packages/apscheduler/schedulers/base.py": 17992335652981439676, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/gh26920/two_mods_with_no_public_entities.f90": 12296500845667555672, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_reflection.py": 10520778598547003532, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_pickle.py": 3419420815386925630, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/PIL/PcdImagePlugin.py": 922809545463280224, + "venv/lib/python3.13/site-packages/numpy/ma/testutils.py": 9355402483340137461, + "venv/lib/python3.13/site-packages/more_itertools/recipes.pyi": 16788810745659802820, + "venv/lib/python3.13/site-packages/pygments/lexers/haskell.py": 8011341851439354724, + "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_can_hold_element.py": 5406431247116557833, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/mixed/foo.f": 5690596225005490325, + "venv/lib/python3.13/site-packages/jaraco/functools/__init__.py": 15334412919279565528, + "venv/lib/python3.13/site-packages/numpy/linalg/_umath_linalg.cpython-313-x86_64-linux-gnu.so": 17652852308919396403, + "venv/lib/python3.13/site-packages/charset_normalizer/version.py": 9948878594498587774, + "venv/lib/python3.13/site-packages/pandas/core/config_init.py": 16537122488227845090, + "venv/lib/python3.13/site-packages/pygments/lexers/pointless.py": 17552020039609007881, + "frontend/src/routes/login/+page.svelte": 4542360917085342323, + "backend/src/services/clean_release/repositories/approval_repository.py": 15069637305272665109, + "venv/lib/python3.13/site-packages/numpy/core/numeric.py": 17025007229779320230, + "venv/lib/python3.13/site-packages/cffi/pkgconfig.py": 16057517851163939571, + "venv/lib/python3.13/site-packages/numpy/_pyinstaller/tests/__init__.py": 13331622784664204066, + "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/WHEEL": 16097436423493754389, + "venv/lib/python3.13/site-packages/pandas/tests/resample/test_base.py": 15292769510056833117, + "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_ccalendar.py": 8819357623337533489, + "venv/lib/python3.13/site-packages/pygments/lexers/eiffel.py": 8964563077187051946, + "venv/lib/python3.13/site-packages/pandas/io/formats/html.py": 11849941990375030601, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/modeline.py": 6194365452131561478, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh25211.f": 1486878017876900890, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_pickle.py": 4216445955812104014, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_modules.py": 16835987029123241300, + "venv/bin/activate": 14735074000123383125, + "venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/METADATA": 732041908491732594, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_interval.py": 8549680643865283913, + "venv/lib/python3.13/site-packages/pygments/lexers/nimrod.py": 8457135214131458774, + "venv/lib/python3.13/site-packages/tzlocal/windows_tz.py": 11696765495002954868, + "venv/lib/python3.13/site-packages/jsonschema/tests/__init__.py": 15130871412783076140, + "backend/src/models/dataset_review_pkg/_semantic_models.py": 15376906129805121935, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/live.py": 8586058300967410643, + "venv/lib/python3.13/site-packages/python_multipart/multipart.py": 5677735019292537174, + "backend/src/plugins/translate/__init__.py": 12400577052797809611, + "frontend/build/_app/immutable/nodes/33.BUdbGEpr.js": 7904426271120174786, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/_elements_constructors.py": 9279447066034364952, + "venv/lib/python3.13/site-packages/tzlocal/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/starlette/middleware/httpsredirect.py": 16837082808103815044, + "venv/lib/python3.13/site-packages/pip/_vendor/requests/status_codes.py": 17005213506461710202, + "venv/lib/python3.13/site-packages/pip/_vendor/distlib/__init__.py": 15735839022111230173, + "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/abstract.py": 14216912708889351810, + "venv/lib/python3.13/site-packages/numpy/lib/npyio.py": 6782361985454523908, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_callback.py": 1689177048527329209, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/_public_dtype_api_table.h": 8933016749764021181, + "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/__init__.py": 11283047029180207588, + "venv/lib/python3.13/site-packages/pandas/core/computation/check.py": 16048939716341154196, + "venv/lib/python3.13/site-packages/pip/_vendor/idna/uts46data.py": 1867240043777383728, + "venv/lib/python3.13/site-packages/jeepney/io/tests/utils.py": 10346859893683522113, + "venv/lib/python3.13/site-packages/authlib/common/encoding.py": 52296066492753953, + "venv/lib/python3.13/site-packages/pillow.libs/libbrotlidec-b57ddf63.so.1.2.0": 10032590058372320813, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/recarray_from_file.fits": 15116318600514274152, + "venv/lib/python3.13/site-packages/pandas/tests/frame/test_api.py": 5813060676255093777, + "venv/lib/python3.13/site-packages/pandas/tests/extension/base/constructors.py": 7587476800569414769, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_algos.py": 5356470832688354593, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/json.py": 15085143436056608404, + "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/cython/meson.build": 9642189398934130247, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/base.py": 16891437410462671317, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7519/claims.py": 12645788445743898136, + "frontend/build/_app/immutable/nodes/8.xxEF6bTJ.js": 5561886302919578979, + "venv/lib/python3.13/site-packages/pygments/formatters/svg.py": 11686316844190214147, + "backend/src/plugins/translate/__tests__/__init__.py": 2490542523242946173, + "venv/lib/python3.13/site-packages/pandas/core/indexes/period.py": 1181348384346239378, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/fields.pyi": 15420142722808118826, + "venv/lib/python3.13/site-packages/iniconfig/exceptions.py": 16501270224069836264, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_melt.py": 15663807247682146566, + "venv/lib/python3.13/site-packages/pip/_internal/utils/filetypes.py": 4415340223268174913, + "venv/lib/python3.13/site-packages/greenlet/tests/test_leaks.py": 1219835696230215605, + "venv/lib/python3.13/site-packages/greenlet/tests/test_gc.py": 6383305344377882524, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_operators.py": 12686786829906210592, + "venv/lib/python3.13/site-packages/pip/_internal/pyproject.py": 6155748929233245415, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/loading.py": 3460142472461437916, + "venv/bin/keyring": 1488968652276547659, + "backend/src/services/llm_prompt_templates.py": 5706065356933042518, + "venv/lib/python3.13/site-packages/numpy/lib/__init__.py": 12211229657513986410, + "venv/lib/python3.13/site-packages/pydantic/_internal/_decorators.py": 9928398334052202841, + "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_numeric.py": 9417128508433693658, + "venv/lib/python3.13/site-packages/numpy/_expired_attrs_2_0.py": 8786558894094307341, + "venv/lib/python3.13/site-packages/gitdb/test/test_stream.py": 18159319442241857857, + "venv/lib/python3.13/site-packages/pandas/tseries/frequencies.py": 2262381949755250516, + "backend/src/scripts/seed_superset_load_test.py": 14952302154142898180, + "frontend/build/_app/immutable/chunks/CTFFznDe.js": 8010860292122799172, + "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/authlib/oidc/core/userinfo.py": 17201158389976619872, + "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/licenses/LICENSE": 4274653168153720331, + "venv/lib/python3.13/site-packages/keyring/credentials.py": 14515496037842724455, + "venv/lib/python3.13/site-packages/pyasn1/codec/cer/encoder.py": 3261739474564948330, + "venv/lib/python3.13/site-packages/httpx/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_fillna.py": 7244491410004453166, + "frontend/src/lib/components/layout/__tests__/test_breadcrumbs.svelte.js": 1250794495161202602, + "backend/src/services/clean_release/compliance_execution_service.py": 3379474749353250488, + "venv/lib/python3.13/site-packages/pygments/styles/trac.py": 13968346768164381833, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_round.py": 9358309072340573675, + "venv/lib/python3.13/site-packages/pyasn1/codec/__init__.py": 15728752901274520502, + "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pydantic/utils.py": 1533455264689378477, + "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pip/_internal/operations/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libkrb5support-d0bcff84.so.0.1": 16819924515291719993, + "venv/lib/python3.13/site-packages/pygments/lexers/_mapping.py": 12987629396101138833, + "venv/lib/python3.13/site-packages/httpcore/_sync/connection_pool.py": 8159971229245441880, + "venv/lib/python3.13/site-packages/jsonschema/tests/test_jsonschema_test_suite.py": 12733761462141495972, + "venv/lib/python3.13/site-packages/gitdb/exc.py": 13975852664048821278, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arraysetops.pyi": 1782641795267171928, + "venv/lib/python3.13/site-packages/authlib/jose/rfc8037/jws_eddsa.py": 833927568269372333, + "venv/lib/python3.13/site-packages/_pytest/_py/path.py": 8464061867075119556, + "venv/lib/python3.13/site-packages/click/__init__.py": 9261629899056870564, + "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_interaction.py": 12216477658994324787, + "venv/lib/python3.13/site-packages/passlib/handlers/sha1_crypt.py": 5752556581809938954, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_reindex.py": 12459492712890114705, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_grouping.py": 5994909693214299971, + "venv/lib/python3.13/site-packages/fastapi/background.py": 16533963020573865222, + "venv/lib/python3.13/site-packages/numpy/random/bit_generator.pxd": 14261507718442469988, + "venv/lib/python3.13/site-packages/pandas/core/arrays/period.py": 11560984428402318984, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/twodim_base.pyi": 3773329770170248877, + "venv/lib/python3.13/site-packages/pandas/tests/window/moments/test_moments_consistency_ewm.py": 12153690217678546798, + "venv/lib/python3.13/site-packages/websockets/version.py": 5853118844880112885, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/memmap.pyi": 15629663272474054909, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_combine_concat.py": 3201068805128232483, + "venv/lib/python3.13/site-packages/sqlalchemy/engine/characteristics.py": 2916810597149066609, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/_psycopg_common.py": 4111797647365870137, + "frontend/src/lib/components/dataset-review/ValidationFindingsPanel.svelte": 2403276296409515448, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/test_calendar.py": 12313641252472031631, + "backend/src/core/utils/async_network.py": 2763204398131017281, + "venv/lib/python3.13/site-packages/fastapi/security/utils.py": 2616633862993539558, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_recfunctions.py": 16014503284544747867, + "frontend/src/routes/reports/+page.svelte": 7370192460972346131, + "backend/src/core/logger.py": 2069537382060633888, + "venv/lib/python3.13/site-packages/numpy/lib/_histograms_impl.pyi": 6534825471013879522, + "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/factory.py": 3042005457138956499, + "venv/lib/python3.13/site-packages/numpy/_core/_asarray.pyi": 3940937389249665490, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_pipe.py": 7400355977900310233, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/engine.py": 2652248727360250985, + "venv/lib/python3.13/site-packages/websockets/sync/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/psycopg2_binary.libs/liblber-1c9097e2.so.2.0.200": 2651879839738900594, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/f77fixedform.f95": 10898637805043867370, + "venv/lib/python3.13/site-packages/numpy/_core/_multiarray_umath.cpython-313-x86_64-linux-gnu.so": 2888939866336522308, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/cx_oracle.py": 10093932131797570986, + "venv/lib/python3.13/site-packages/PIL/ImtImagePlugin.py": 17599267755504817169, + "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_where.py": 3272402211717453881, + "venv/lib/python3.13/site-packages/greenlet/tests/test_greenlet.py": 10727595500186011102, + "venv/lib/python3.13/site-packages/numpy/core/fromnumeric.py": 2136433423902202138, + "venv/lib/python3.13/site-packages/pygments/formatters/rtf.py": 5850574956253747036, + "venv/lib/python3.13/site-packages/pygments/lexers/gsql.py": 15294109558028161389, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_values.py": 8372572954663628844, + "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_getitem.py": 18202683049446557047, + "venv/lib/python3.13/site-packages/pydantic/_internal/_internal_dataclass.py": 13206778611516171760, + "venv/lib/python3.13/site-packages/yaml/loader.py": 18284689412149643959, + "venv/lib/python3.13/site-packages/packaging/_manylinux.py": 8268418900652790584, + "venv/lib/python3.13/site-packages/packaging/licenses/__init__.py": 15879493360260891293, + "frontend/src/routes/translate/dictionaries/+page.svelte": 11204836397236633754, + "frontend/build/_app/immutable/chunks/C9KBnq-A.js": 13706048316691531557, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_mixed.py": 3476101699679108025, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh26681.f90": 1515497186927052106, + "venv/lib/python3.13/site-packages/attr/_cmp.pyi": 14443711863388606665, + "venv/lib/python3.13/site-packages/pip/_internal/commands/index.py": 16715578868094112894, + "venv/lib/python3.13/site-packages/pip/_internal/cli/command_context.py": 9426036980437931533, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_datetimeindex.py": 14816894350435545024, + "venv/lib/python3.13/site-packages/starlette/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pip/_internal/resolution/base.py": 10514193453447954780, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/repr.py": 839417422880281122, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_drop.py": 11341278355685583133, + "venv/lib/python3.13/site-packages/pip/_internal/cli/main_parser.py": 7942770969280622910, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/formatter.py": 16499277113779414101, + "venv/lib/python3.13/site-packages/sqlalchemy/exc.py": 6372950288664776625, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/fixtures/base.py": 10205051944814316388, + "venv/lib/python3.13/site-packages/referencing/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/panel.py": 17832701246248000383, + "venv/lib/python3.13/site-packages/PIL/Hdf5StubImagePlugin.py": 15654153796225833950, + "venv/lib/python3.13/site-packages/pandas/core/window/ewm.py": 12143982379243011357, + "venv/lib/python3.13/site-packages/pandas/core/ops/__init__.py": 4049432353810047365, + "venv/lib/python3.13/site-packages/pygments/styles/perldoc.py": 4857683935715743356, + "venv/lib/python3.13/site-packages/pygments/styles/dracula.py": 12379322008538174078, + "venv/lib/python3.13/site-packages/pygments/lexers/jslt.py": 11805394130669644345, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/cli/hiworld.f90": 6321872653169140461, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_argparse.py": 11111699418217357084, + "venv/lib/python3.13/site-packages/pandas/_libs/ops.pyi": 1192312467209548763, + "venv/lib/python3.13/site-packages/numpy/_core/printoptions.pyi": 16758392990920041462, + "frontend/src/app.html": 10207534912546549080, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_offsets_properties.py": 2340780879864207500, + "frontend/src/lib/Counter.svelte": 4002153662176313030, + "frontend/build/_app/immutable/chunks/B19Q4MUf.js": 8384959676363720729, + "venv/lib/python3.13/site-packages/pandas/tests/io/test_pickle.py": 2910383574326146698, + "backend/src/services/clean_release/__init__.py": 18311663871116449547, + "venv/lib/python3.13/site-packages/anyio/streams/tls.py": 4191898645554875562, + "backend/alembic/script.py.mako": 7041141123739810216, + "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_django.py": 8455054295577203929, + "venv/lib/python3.13/site-packages/PIL/TarIO.py": 13651401276968618561, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_latex.py": 15077617224435782028, + "venv/lib/python3.13/site-packages/passlib/tests/test_crypto_digest.py": 7988469818593853943, + "venv/lib/python3.13/site-packages/git/objects/util.py": 691018806932355307, + "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/meta-data": 9599129816090399315, + "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_ordered.py": 13827016781743929164, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_util.py": 16024147572807865219, + "frontend/build/_app/immutable/chunks/D7OGuSC7.js": 3496948723181364522, + "venv/lib/python3.13/site-packages/numpy/f2py/cfuncs.py": 10803011906582324302, + "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/__init__.py": 12793458753561114666, + "venv/lib/python3.13/site-packages/pydantic_core/core_schema.py": 8106298745123589494, + "venv/lib/python3.13/site-packages/sqlalchemy/engine/strategies.py": 14007486769065345085, + "venv/lib/python3.13/site-packages/pandas/tests/extension/base/setitem.py": 9552868454186447925, + "venv/lib/python3.13/site-packages/pip/_internal/operations/build/metadata.py": 2021612995853910808, + "venv/lib/python3.13/site-packages/_pytest/subtests.py": 14573790885130724739, + "venv/lib/python3.13/site-packages/numpy/lib/_ufunclike_impl.pyi": 9854069702366900663, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_isna.py": 18394053826166267096, + "venv/lib/python3.13/site-packages/pygments/lexers/_lua_builtins.py": 12653747099659257203, + "venv/lib/python3.13/site-packages/passlib/utils/decor.py": 21351391767102899, + "venv/lib/python3.13/site-packages/passlib/tests/sample1.cfg": 9597283806285213340, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/common_with_division.f": 13517753924061311074, + "venv/lib/python3.13/site-packages/passlib/crypto/__init__.py": 16409196868630049365, + "venv/lib/python3.13/site-packages/sqlalchemy/util/langhelpers.py": 1246582552828542841, + "venv/lib/python3.13/site-packages/pip/_internal/commands/search.py": 8292218231992728142, + "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/LICENSE": 16174281248426886206, + "venv/lib/python3.13/site-packages/passlib/totp.py": 14590474309565233318, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_to_timestamp.py": 17572983799929378095, + "venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/WHEEL": 8954358347596196608, + "venv/lib/python3.13/site-packages/gitdb/test/test_base.py": 16305779366785148795, + "venv/lib/python3.13/site-packages/jsonschema/tests/test_utils.py": 8668650648802195016, + "venv/lib/python3.13/site-packages/pydantic/experimental/arguments_schema.py": 8644805798814234457, + "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/content": 12465123883296161860, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/lib_function_base.pyi": 10972502518588022706, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_ops.py": 14420421526781215500, + "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/WHEEL": 8600534672961461758, + "venv/lib/python3.13/site-packages/pandas/tests/extension/array_with_attr/__init__.py": 15991623390785635773, + "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/fetch.py": 13937019222549208796, + "venv/lib/python3.13/site-packages/jsonschema/tests/typing/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pip/_internal/utils/unpacking.py": 106471890743211548, + "venv/lib/python3.13/site-packages/passlib/handlers/__init__.py": 3424087230285514388, + "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/methods/test_as_unit.py": 4283520188709399244, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/OSA.pyi": 2700568594438441246, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_to_dict.py": 16252265723192124609, + "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/licenses/numpy/_core/src/common/pythoncapi-compat/COPYING": 3474104874623144155, + "frontend/build/_app/immutable/chunks/DcQow1yy.js": 691404182357373926, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/base.py": 16052592982063844259, + "frontend/build/_app/immutable/assets/0.DN6ByAb-.css": 6256222992586029103, + "venv/lib/python3.13/site-packages/pygments/lexers/praat.py": 54226477748516386, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/base.py": 6348888156686452825, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/Postfix_py.py": 6653895521961110080, + "venv/lib/python3.13/site-packages/anyio/_core/_contextmanagers.py": 1258491775823080427, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_frozen.py": 3484963987053884566, + "venv/lib/python3.13/site-packages/pydantic/v1/mypy.py": 17076910404409672245, + "venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/REQUESTED": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arcsin.csv": 1665171675551692225, + "venv/lib/python3.13/site-packages/pydantic/schema.py": 83238111330132033, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_pickle.py": 8705060420848529055, + "venv/lib/python3.13/site-packages/pygments/lexers/x10.py": 6167378515780115912, + "venv/lib/python3.13/site-packages/_pytest/stash.py": 14430252294763173610, + "venv/lib/python3.13/site-packages/pandas/tests/test_multilevel.py": 10500316376521962061, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/_py_util.py": 12836989066113400538, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/discovery.py": 12479996594187326798, + "frontend/src/routes/dashboards/[id]/components/DashboardTaskHistory.svelte": 8800115118935646769, + "venv/lib/python3.13/site-packages/pandas/core/methods/describe.py": 17006836623161521092, + "backend/logs/app.log.4": 11598841362861329809, + "venv/lib/python3.13/site-packages/passlib/handlers/ldap_digests.py": 8658529184965699766, + "venv/lib/python3.13/site-packages/pandas/_libs/ops.cpython-313-x86_64-linux-gnu.so": 10490009128553397250, + "venv/lib/python3.13/site-packages/pygments/lexers/functional.py": 15896849233007178031, + "venv/lib/python3.13/site-packages/pandas/compat/pyarrow.py": 13693379998785127538, + "backend/src/api/routes/dashboards/_projection.py": 1559143255780155174, + "backend/src/services/clean_release/__tests__/test_manifest_builder.py": 9320699981861675127, + "backend/src/services/git/__init__.py": 14011752637167919253, + "backend/src/plugins/llm_analysis/__tests__/test_client_headers.py": 5527172390260032966, + "venv/lib/python3.13/site-packages/pydantic/_internal/_schema_gather.py": 3634138701088855517, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/emath.pyi": 3718540478840842664, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_to_csv.py": 10737444103906389448, + "frontend/src/lib/components/assistant/__tests__/assistant_confirmation.integration.test.js": 12582020574293031526, + "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_npy_units.py": 8966226962799105383, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_repeat.py": 9155935990114743583, + "venv/lib/python3.13/site-packages/jsonschema/benchmarks/useless_applicator_schemas.py": 8395157526634674143, + "frontend/src/lib/components/dataset-review/__tests__/us2_semantic_workspace.ux.test.js": 3550956860258259058, + "venv/lib/python3.13/site-packages/ecdsa/test_pyecdsa.py": 14542286382742044648, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_inspect.py": 10573558345297891848, + "venv/lib/python3.13/site-packages/apscheduler/executors/asyncio.py": 2230610508870117058, + "backend/src/api/routes/profile.py": 16065196073183170065, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/nattype.pyi": 1830368009811266890, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arrayprint.pyi": 2053388407376896377, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_head_tail.py": 1906121476322841736, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/object/__init__.py": 15130871412783076140, + "frontend/build/_app/immutable/nodes/27.BcmdCO7Q.js": 17863709917454568143, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/pkcs12.pyi": 7801211423226951223, + "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/METADATA": 5628172948035858892, + "frontend/build/index.html": 12181298379271754142, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/json.py": 6429651405841289922, + "venv/lib/python3.13/site-packages/numpy/matlib.pyi": 8017902013455539981, + "venv/lib/python3.13/site-packages/passlib/handlers/postgres.py": 14162382430051693313, + "venv/lib/python3.13/site-packages/httpcore/_trace.py": 9576253018891841832, + "venv/lib/python3.13/site-packages/rsa/randnum.py": 13958355153634534526, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_size.py": 12449835577388069407, + "venv/lib/python3.13/site-packages/bcrypt/__about__.py": 11196369962175692786, + "backend/tests/services/clean_release/test_approval_service.py": 8359796700245201345, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_intervalindex.py": 5053113227747333759, + "venv/lib/python3.13/site-packages/pandas/tests/extension/base/base.py": 14908084548919567658, + "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/version.py": 14723293207188512766, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/ec.py": 8864112842559211971, + "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/METADATA": 9586902338916246692, + "venv/lib/python3.13/site-packages/pip/_vendor/pygments/plugin.py": 18006138132596504101, + "venv/lib/python3.13/site-packages/pip/__init__.py": 9449893869469432503, + "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/resolution.py": 5132658725516243311, + "venv/lib/python3.13/site-packages/pip/_internal/metadata/__init__.py": 8924316361489544973, + "venv/lib/python3.13/site-packages/pydantic/v1/json.py": 16596969681914729251, + "venv/lib/python3.13/site-packages/urllib3/poolmanager.py": 15431313180245757657, + "backend/src/core/superset_client/_base.py": 17832258524611728315, + "venv/lib/python3.13/site-packages/_pytest/pastebin.py": 13946273207624603063, + "venv/lib/python3.13/site-packages/smmap/buf.py": 18231775424238352734, + "venv/lib/python3.13/site-packages/numpy/matrixlib/__init__.pyi": 1942236362568669510, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_copy_deprecation.py": 16045426957636349035, + "venv/lib/python3.13/site-packages/numpy/_array_api_info.py": 9709101823494959741, + "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_find_common_type.py": 9581516171321396333, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/emoji.py": 9166774203918731896, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_drop.py": 15751236355035730554, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_is_monotonic.py": 4626065848596214108, + "venv/lib/python3.13/site-packages/sqlalchemy/future/engine.py": 4639404437703898767, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_select.py": 17823338162428379468, + "venv/lib/python3.13/site-packages/pygments/lexers/perl.py": 17014528337020572681, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm32_ios.h": 6751259472945638998, + "venv/lib/python3.13/site-packages/numpy/polynomial/polynomial.pyi": 9935587108964614958, + "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/zip-safe": 15240312484046875203, + "backend/src/api/routes/git/_merge_routes.py": 2019590524299108754, + "backend/src/api/routes/translate/_run_list_routes.py": 18118346695557887371, + "venv/lib/python3.13/site-packages/uvicorn/protocols/http/h11_impl.py": 1419719055394402145, + "venv/lib/python3.13/site-packages/pip/_vendor/packaging/specifiers.py": 12284901056355482991, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/usecols/test_strings.py": 7379299916213794543, + "backend/src/core/logger/__tests__/test_logger.py": 4188397720199242180, + "venv/lib/python3.13/site-packages/pygments/styles/_mapping.py": 11752660241391232497, + "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/METADATA": 6656194161182818439, + "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_array.py": 12514884344165043136, + "backend/src/services/clean_release/__tests__/test_report_builder.py": 17265459530244848426, + "frontend/src/lib/components/translate/TranslationMetricsDashboard.svelte": 10832255927386244176, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/libs/test_libalgos.py": 13934861984871432400, + "backend/src/models/__init__.py": 13280325675752905975, + "frontend/src/routes/tools/mapper/+page.svelte": 11954517841045690204, + "frontend/src/lib/api.js": 12667793754050845906, + "venv/lib/python3.13/site-packages/keyring/backends/macOS/__init__.py": 1010937986753403630, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/mariadb.py": 3109042476851791996, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/associationproxy.py": 7421910137064160936, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_function_base.py": 16624804022675533740, + "venv/lib/python3.13/site-packages/numpy/lib/_stride_tricks_impl.pyi": 9243829615414967057, + "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/immutabledict.pxd": 13413785818999584986, + "venv/lib/python3.13/site-packages/pip/_internal/req/req_file.py": 5180401483285462901, + "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/auto.py": 12818217385551437286, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py": 10843527833285941674, + "venv/lib/python3.13/site-packages/pandas/tests/strings/test_get_dummies.py": 14871264482622327003, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/relationships.py": 8401569216905291119, + "venv/lib/python3.13/site-packages/numpy/lib/_ufunclike_impl.py": 12251264586530536622, + "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_setitem.py": 10389770446834773837, + "venv/lib/python3.13/site-packages/sqlalchemy/util/tool_support.py": 4926732415520779988, + "venv/lib/python3.13/site-packages/anyio/_core/_asyncio_selector_thread.py": 1760597191437520000, + "venv/lib/python3.13/site-packages/_pytest/mark/expression.py": 1821437025841201912, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/string_/test_string.py": 3834067244989779682, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/progress_bar.py": 15595912766961891283, + "venv/lib/python3.13/site-packages/pydantic/color.py": 1007422551673129827, + "venv/lib/python3.13/site-packages/numpy/random/tests/data/mt19937-testset-2.csv": 14641856424618845798, + "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/websockets_impl.py": 15673691977157706075, + "venv/lib/python3.13/site-packages/websockets/asyncio/client.py": 5694225754072131767, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_insert.py": 17383986803728810587, + "venv/lib/python3.13/site-packages/pygments/lexers/roboconf.py": 1335271183806115470, + "backend/src/core/utils/superset_context_extractor/_filters.py": 281666313889333545, + "venv/lib/python3.13/site-packages/_pytest/_version.py": 4890545974654141536, + "venv/lib/python3.13/site-packages/pydantic/v1/schema.py": 10008526732895436361, + "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_retain_attributes.py": 16210262356844956764, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/oct_key.py": 11504245602045724, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_sorting.py": 8944017570338511677, + "frontend/src/assets/svelte.svg": 13872699371039797074, + "venv/lib/python3.13/site-packages/numpy/random/_mt19937.pyi": 15904463104068500379, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_reindex_like.py": 13803156447991282315, + "venv/lib/python3.13/site-packages/pip/_internal/req/__init__.py": 12266077985828139928, + "docker/nginx.conf": 16884137323072604795, + "venv/lib/python3.13/site-packages/pandas/core/arrays/integer.py": 7775055011080964709, + "venv/lib/python3.13/site-packages/pydantic/v1/errors.py": 11245135449608452720, + "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/licenses/COPYING": 14459782230785388765, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/test_cython.py": 2933400021016349431, + "venv/lib/python3.13/site-packages/pandas/tests/generic/test_frame.py": 9378623452601244234, + "venv/lib/python3.13/site-packages/pip/_vendor/requests/compat.py": 5871636909854554063, + "venv/lib/python3.13/site-packages/pandas/io/formats/templates/string.tpl": 15796203549130590784, + "venv/lib/python3.13/site-packages/pandas/tests/extension/decimal/array.py": 1919242530821725197, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/cache_key.py": 11118819065204404106, + "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/WHEEL": 16097436423493754389, + "venv/lib/python3.13/site-packages/numpy/lib/_arraysetops_impl.py": 5583478355093966990, + "venv/lib/python3.13/site-packages/pandas/tests/extension/date/__init__.py": 16789767433439616593, + "venv/lib/python3.13/site-packages/jeepney/io/common.py": 15160647397460834508, + "venv/lib/python3.13/site-packages/PIL/ImageStat.py": 18442709639217312689, + "frontend/src/services/adminService.js": 6375990585512014277, + "backend/src/plugins/translate/dictionary.py": 5036394504674042587, + "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_odswriter.py": 5134385709728943904, + "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_style.py": 14810883299259169406, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/PIL/TiffTags.py": 8688883943071546469, + "frontend/build/_app/immutable/chunks/CUbMcWr2.js": 11521095389159805757, + "venv/lib/python3.13/site-packages/numpy/lib/_function_base_impl.py": 14034239842770171660, + "venv/lib/python3.13/site-packages/pandas/tests/io/xml/conftest.py": 17514079438846557943, + "frontend/src/routes/dashboards/__tests__/dashboard-profile-override.integration.test.js": 15198772446275187033, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/frequencies/test_inference.py": 5741637509343419942, + "backend/src/core/utils/superset_context_extractor/_templates.py": 6790136732701012567, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/period.cpython-313-x86_64-linux-gnu.so": 14468234464367691795, + "venv/lib/python3.13/site-packages/PIL/_webp.pyi": 18222325750818585549, + "venv/lib/python3.13/site-packages/rapidfuzz/fuzz_py.py": 6428078990080243608, + "venv/lib/python3.13/site-packages/jsonschema/_typing.py": 13152346021901861822, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/__init__.py": 371829636800613137, + "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/RECORD": 18314788057673509075, + "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/__init__.py": 8880435562116660648, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_asof.py": 15792528637923603240, + "venv/lib/python3.13/site-packages/pydantic/_internal/_config.py": 12760390602912369447, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/pymssql.py": 6650008663791598065, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_period.py": 10309599277099605395, + "venv/lib/python3.13/site-packages/pandas/tests/test_take.py": 17628004130770326677, + "venv/lib/python3.13/site-packages/pygments/lexers/tnt.py": 4657130609241407766, + "venv/lib/python3.13/site-packages/pandas/core/array_algos/masked_accumulations.py": 11428556645065711062, + "venv/lib/python3.13/site-packages/greenlet/tests/test_tracing.py": 10227316489696807112, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/object/test_indexing.py": 1947969642791009285, + "venv/lib/python3.13/site-packages/PIL/XbmImagePlugin.py": 12256750478268246137, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ufunclike.py": 12077553320554633586, + "venv/lib/python3.13/site-packages/_pytest/timing.py": 14080119171718125986, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/client_credentials.py": 256154392957334831, + "venv/lib/python3.13/site-packages/numpy/polynomial/legendre.pyi": 2029639875417260268, + "venv/lib/python3.13/site-packages/jsonschema/_types.py": 9250091433305395923, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/errors.py": 14634768861119075506, + "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/_pip_wrapper.py": 2516476609539242190, + "venv/lib/python3.13/site-packages/pandas/tests/window/conftest.py": 10673264126684571493, + "venv/lib/python3.13/site-packages/pygments/lexers/_qlik_builtins.py": 1728058904137960444, + "venv/lib/python3.13/site-packages/dateutil/tzwin.py": 5149446703746204349, + "frontend/src/routes/dashboards/[id]/components/DashboardLinkedResources.svelte": 8279080994517688482, + "backend/src/dependencies.py": 9481683691730170837, + "venv/lib/python3.13/site-packages/websockets/asyncio/compatibility.py": 9716993942839407921, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/style.py": 10665998898253460114, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_warnings.py": 13071210233876253749, + "venv/lib/python3.13/site-packages/PIL/PsdImagePlugin.py": 4347581352716313298, + "venv/lib/python3.13/site-packages/pandas/_testing/_io.py": 14264259716673715185, + "venv/bin/uvicorn": 3776670267111625708, + "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/WHEEL": 5160964596297665692, + "venv/lib/python3.13/site-packages/numpy/polynomial/_polybase.py": 893743087939984792, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_dialect.py": 6294522482440261756, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_function.py": 14142346897145169685, + "venv/lib/python3.13/site-packages/charset_normalizer/constant.py": 3070316197495651997, + "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/authorization_server.py": 17967809814827547139, + "venv/lib/python3.13/site-packages/numpy/_core/einsumfunc.py": 11393954913234866059, + "frontend/build/_app/immutable/nodes/31.BSHS4QPz.js": 2044128076272545863, + "backend/src/core/ws_log_handler.py": 7507069843556560249, + "venv/lib/python3.13/site-packages/keyring/backends/chainer.py": 12526770797516553385, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_dtypes.py": 481191723198819568, + "venv/lib/python3.13/site-packages/smmap/test/test_tutorial.py": 16309370344201290582, + "frontend/src/routes/git/+page.svelte": 14169430923974356254, + "venv/lib/python3.13/site-packages/pandas/core/dtypes/concat.py": 14737724508458849795, + "venv/lib/python3.13/site-packages/pandas/tests/series/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/METADATA": 7214286447912789067, + "backend/src/api/routes/__tests__/test_connections_routes.py": 18044815559820610056, + "venv/lib/python3.13/site-packages/starlette/middleware/sessions.py": 11719848399661632707, + "venv/lib/python3.13/site-packages/pygments/lexers/lean.py": 14518351619544450286, + "venv/lib/python3.13/site-packages/greenlet/tests/fail_slp_switch.py": 16490710972475154509, + "frontend/src/components/tools/ConnectionForm.svelte": 4060811448046342875, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/poolmanager.py": 5071697837617938064, + "venv/lib/python3.13/site-packages/websockets/legacy/handshake.py": 376095144657994920, + "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pygments/styles/native.py": 4559566444883341527, + "venv/lib/python3.13/site-packages/anyio/streams/buffered.py": 8916188172110578587, + "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/emscripten_fetch_worker.js": 10530710876604536879, + "venv/lib/python3.13/site-packages/uvicorn/lifespan/on.py": 2866195356090164296, + "venv/lib/python3.13/site-packages/pygments/lexers/_stan_builtins.py": 1961875544235948177, + "venv/lib/python3.13/site-packages/_pytest/_io/terminalwriter.py": 16852767249156780980, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_astype.py": 6578539240745332772, + "venv/lib/python3.13/site-packages/greenlet/TMainGreenlet.cpp": 9489520001674089404, + "venv/lib/python3.13/site-packages/websockets/imports.py": 1995356703044158461, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_values.py": 430620320423334461, + "venv/lib/python3.13/site-packages/pycparser/c_ast.py": 5942107079119742, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/type_check.pyi": 1599910480066368464, + "frontend/src/lib/components/reports/__tests__/reports_filter_performance.test.js": 10583581505638859039, + "venv/lib/python3.13/site-packages/passlib/tests/test_context.py": 15195609282700801214, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_lexsort.py": 10394832796613968484, + "venv/lib/python3.13/site-packages/numpy/random/tests/data/pcg64dxsm-testset-1.csv": 9129730764673472086, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ctypeslib.pyi": 8623725566434725526, + "venv/lib/python3.13/site-packages/pandas/tests/generic/test_duplicate_labels.py": 10663105616336167414, + "venv/lib/python3.13/site-packages/httpx/_transports/mock.py": 13564349939188292363, + "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/jwe_algs.py": 2479791018067637690, + "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/numpy/testing/print_coercion_tables.pyi": 3814281717779245045, + "venv/lib/python3.13/site-packages/passlib/utils/binary.py": 13123975436674239306, + "venv/lib/python3.13/site-packages/pandas/tests/extension/base/getitem.py": 556339939822508169, + "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_xlsxwriter.py": 8445547874832015203, + "venv/lib/python3.13/site-packages/PIL/EpsImagePlugin.py": 1824020964179364491, + "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/licenses/LICENSE": 1126906383149772681, + "venv/lib/python3.13/site-packages/numpy/polynomial/_polybase.pyi": 15864712173815045309, + "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/RECORD": 7914594107698271488, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/scalar_string.f90": 15018631706178918578, + "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/LICENSE": 6989336036499641077, + "frontend/build/_app/immutable/nodes/12.B-jKzEjW.js": 7311098820038156560, + "venv/lib/python3.13/site-packages/PIL/TgaImagePlugin.py": 9208942494595222259, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_tz_localize.py": 13699016868476153393, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/ciphers.pyi": 18143251582901996072, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/tzconversion.cpython-313-x86_64-linux-gnu.so": 15960606468596245469, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_cython.py": 14695721638531081573, + "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_timedelta64.py": 16821719402662529276, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_copy.py": 12902342280706372953, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_arithmetic.py": 976970179757115407, + "venv/lib/python3.13/site-packages/pygments/lexers/graphics.py": 13783143864729682444, + "venv/lib/python3.13/site-packages/pip/_internal/exceptions.py": 2252826732781519645, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/JaroWinkler.pyi": 9003794318682878317, + "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/limited_api1.c": 8494977275215578998, + "venv/lib/python3.13/site-packages/certifi/py.typed": 15130871412783076140, + "frontend/src/lib/components/ui/MultiSelect.svelte": 13967450784969599105, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/device_code.py": 6712610002227849281, + "backend/src/core/utils/superset_context_extractor/__init__.py": 1074191108198498747, + "backend/src/core/utils/superset_compilation_adapter.py": 4974836712746468095, + "backend/src/services/clean_release/audit_service.py": 9534298777117548502, + "backend/src/plugins/translate/orchestrator.py": 1317097146823609899, + "venv/lib/python3.13/site-packages/pygments/lexers/elpi.py": 5736689911777977822, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_unary.py": 7128845965976836334, + "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_endian.h": 2761502363895204652, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/string/test_astype.py": 10171766562093740708, + "venv/lib/python3.13/site-packages/pandas/tests/window/test_timeseries_window.py": 1973365560758236222, + "venv/lib/python3.13/site-packages/pygments/lexers/sophia.py": 15971500155124949058, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/token.py": 4747545058753492487, + "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_meson.py": 5735043585893007971, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_searchsorted.py": 11161416745923343741, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/_initialize.pyi": 6616985736007157309, + "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/hkdf.py": 8539232219382152238, + "venv/lib/python3.13/site-packages/sqlalchemy/event/base.py": 18238453132776154057, + "venv/lib/python3.13/site-packages/ecdsa/keys.py": 10281170640484982154, + "venv/lib/python3.13/site-packages/cffi/setuptools_ext.py": 30796527302561458, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_fileno.py": 15541504502174047167, + "venv/lib/python3.13/site-packages/pydantic_settings/version.py": 17263591404988984480, + "venv/lib/python3.13/site-packages/websockets/legacy/client.py": 4032878587330592478, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/lib_utils.pyi": 12312677132342982866, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/token.py": 4161760290367932793, + "venv/lib/python3.13/site-packages/pandas/core/sample.py": 11913688303879867963, + "venv/lib/python3.13/site-packages/pandas/core/indexes/multi.py": 9115751979327393200, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_formats.py": 5259100336852479395, + "venv/lib/python3.13/site-packages/jeepney-0.9.0.dist-info/RECORD": 7810411361439269754, + "venv/lib/python3.13/site-packages/urllib3/util/__init__.py": 2848870790459558599, + "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/INSTALLER": 17282701611721059870, + "frontend/build/_app/immutable/chunks/CSKg3QTJ.js": 13514833655854300178, + "venv/lib/python3.13/site-packages/requests/api.py": 12339139862411341381, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_month.py": 14597470286884431085, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_dtype.py": 12210524152630532747, + "venv/lib/python3.13/site-packages/sqlalchemy/types.py": 15819795572817819102, + "venv/lib/python3.13/site-packages/apscheduler/schedulers/qt.py": 12828696264909048448, + "venv/lib/python3.13/site-packages/numpy/f2py/capi_maps.py": 2490579175967301457, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_array_interface.py": 13648006002292914247, + "venv/lib/python3.13/site-packages/pandas/tests/io/test_sql.py": 3901697517087276687, + "venv/lib/python3.13/site-packages/pygments/formatters/terminal.py": 14380579279194052030, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/metrics_cpp_avx2.cpython-313-x86_64-linux-gnu.so": 2991745295485163924, + "backend/src/api/routes/__tests__/test_clean_release_v2_release_api.py": 14275839608126658275, + "backend/src/api/routes/git/_deps.py": 12613530531412985767, + "venv/lib/python3.13/site-packages/pip/__pip-runner__.py": 1138979712722199296, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/data_multiplier.f": 13432803601367981068, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_real/foo77.f": 16156304612888138777, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7591/endpoint.py": 13389763148720370546, + "venv/lib/python3.13/site-packages/h11/_receivebuffer.py": 4631433251046338381, + "venv/lib/python3.13/site-packages/pydantic/v1/datetime_parse.py": 10467114625921924095, + "venv/lib/python3.13/site-packages/pygments/lexers/javascript.py": 16869490851285457857, + "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_period.py": 6255181868181182780, + "venv/lib/python3.13/site-packages/rsa/cli.py": 1753949198467694190, + "venv/lib/python3.13/site-packages/pydantic/deprecated/class_validators.py": 2200511838255373813, + "venv/lib/python3.13/site-packages/pandas/tests/interchange/test_impl.py": 12056958946481531279, + "venv/lib/python3.13/site-packages/PIL/IptcImagePlugin.py": 14329453455296600824, + "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/httpcore/_async/__init__.py": 491192949420297153, + "venv/lib/python3.13/site-packages/_pytest/assertion/__init__.py": 16392348866405910618, + "venv/lib/python3.13/site-packages/urllib3/connection.py": 12761371748350595804, + "venv/lib/python3.13/site-packages/pydantic/v1/fields.py": 3948219773415054006, + "venv/lib/python3.13/site-packages/uvicorn/config.py": 17317823506849880916, + "venv/lib/python3.13/site-packages/pygments/lexers/objective.py": 10966124906622044512, + "venv/lib/python3.13/site-packages/pandas/api/indexers/__init__.py": 17431573013142626187, + "venv/lib/python3.13/site-packages/uvicorn/loops/asyncio.py": 16496916527760969173, + "venv/lib/python3.13/site-packages/click-8.3.1.dist-info/METADATA": 3188324716322823755, + "venv/lib/python3.13/site-packages/authlib/oidc/registration/__init__.py": 9448552677419908109, + "venv/lib/python3.13/site-packages/pycparser/ply/cpp.py": 1665654017894222868, + "backend/src/services/clean_release/enums.py": 7365670144442292671, + "backend/src/plugins/llm_analysis/plugin.py": 13563674795958736723, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_setops.py": 15365064654930699428, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_overlaps.py": 2328652590379935311, + "venv/lib/python3.13/site-packages/attr/exceptions.py": 11532465891810816417, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_map.py": 1115471561925426082, + "venv/lib/python3.13/site-packages/authlib/oidc/core/util.py": 5364455058429522633, + "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/RECORD": 7363618870628306370, + "venv/lib/python3.13/site-packages/pygments/lexers/erlang.py": 11757064262773184741, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/metrics_cpp.cpython-313-x86_64-linux-gnu.so": 10263790384087091349, + "backend/src/plugins/translate/preview.py": 2758655275240027217, + "frontend/build/_app/immutable/nodes/21.C3rNhw8s.js": 13514883473846080135, + "backend/tests/services/clean_release/test_compliance_task_integration.py": 682622548217611215, + "venv/lib/python3.13/site-packages/cffi/backend_ctypes.py": 2042566833861899211, + "frontend/src/routes/+page.ts": 11160596731849880920, + "backend/tests/test_translate_scheduler_guard.py": 13396608843530344156, + "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/dtypes.cpython-313-x86_64-linux-gnu.so": 657138415665704488, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_indexing.py": 11572911419313573163, + "venv/lib/python3.13/site-packages/pygments/lexers/_css_builtins.py": 17478340487186531268, + "venv/bin/pyrsa-verify": 6762739642629904442, + "backend/src/core/middleware/__init__.py": 13917394130915533209, + "venv/lib/python3.13/site-packages/idna/package_data.py": 6583909243002417298, + "venv/lib/python3.13/site-packages/pygments/lexers/smalltalk.py": 6113431347120223592, + "venv/lib/python3.13/site-packages/pygments/lexers/scdoc.py": 8481749542463754279, + "venv/lib/python3.13/site-packages/cryptography/hazmat/backends/openssl/backend.py": 9072112660082423691, + "venv/lib/python3.13/site-packages/numpy/lib/_array_utils_impl.py": 14446508217220482719, + "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/zip-safe": 15240312484046875203, + "venv/lib/python3.13/site-packages/referencing/__init__.py": 10093824711214801917, + "venv/lib/python3.13/site-packages/pandas/core/arrays/string_.py": 14865733321317939478, + "venv/lib/python3.13/site-packages/pandas/core/arraylike.py": 11439602957100017713, + "venv/lib/python3.13/site-packages/pycparser/ply/ctokens.py": 1599952198962458730, + "frontend/build/_app/immutable/chunks/DXB0WcN8.js": 6620985551681767720, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_day.py": 6371851881186970754, + "venv/lib/python3.13/site-packages/pygments/lexers/algebra.py": 9651893228421050246, + "venv/lib/python3.13/site-packages/anyio/abc/_testing.py": 16484863782452886547, + "venv/lib/python3.13/site-packages/pygments/lexers/modeling.py": 15714077241620129689, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_constructors.py": 12628643543371952431, + "venv/lib/python3.13/site-packages/pandas/_libs/indexing.pyi": 90995502095752726, + "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/WHEEL": 16097436423493754389, + "venv/lib/python3.13/site-packages/idna/codec.py": 4260241549062101779, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_names.py": 10037208029090713121, + "frontend/build/_app/immutable/nodes/14.Dgx5ZI_m.js": 3914755165925651833, + "venv/lib/python3.13/site-packages/gitdb/db/loose.py": 17467413653016810702, + "venv/lib/python3.13/site-packages/pydantic/version.py": 3699343596421001359, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_index_as_string.py": 13421551616136437100, + "venv/lib/python3.13/site-packages/fastapi/security/base.py": 15674297568104917749, + "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_backend.pyi": 13083543811193933305, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_iloc.py": 16160558158155038350, + "venv/lib/python3.13/site-packages/pygments/lexers/xorg.py": 14591144191879110061, + "backend/src/api/routes/dataset_review_pkg/_dependencies.py": 15939232213193276681, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/styled.py": 8726407298858811635, + "venv/lib/python3.13/site-packages/numpy/random/tests/test_extending.py": 10202091354750153497, + "venv/lib/python3.13/site-packages/PIL/_typing.py": 17407980360703360848, + "venv/lib/python3.13/site-packages/pandas/core/arrays/string_arrow.py": 16997970607998635570, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_numpy_array_equal.py": 2089426719574307767, + "venv/lib/python3.13/site-packages/git/db.py": 6680123567509774609, + "backend/src/api/routes/__tests__/test_clean_release_api.py": 11565478953155085157, + "venv/lib/python3.13/site-packages/authlib/jose/drafts/_jwe_algorithms.py": 15219408648894515493, + "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/processors.pyx": 7085380878820747579, + "venv/lib/python3.13/site-packages/pandas/io/formats/templates/html_style.tpl": 3352086677417301397, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/__init__.py": 3969805865048730851, + "venv/lib/python3.13/site-packages/yaml/_yaml.cpython-313-x86_64-linux-gnu.so": 16990140871649227895, + "frontend/src/lib/components/translate/__tests__/test_bulk_replace_modal.svelte.js": 6802604718120565742, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/incfile.f90": 4348588746493647387, + "venv/lib/python3.13/site-packages/pygments/util.py": 4815334059917765852, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_quarter.py": 6795026338946382805, + "venv/lib/python3.13/site-packages/pydantic_settings/main.py": 17272314000918984790, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/assumed_shape/precision.f90": 5518911932373565642, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_to_numpy.py": 9663734591667845940, + "venv/lib/python3.13/site-packages/pygments/lexers/yara.py": 17510792615476493957, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/_orm_types.py": 5508682532707462217, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/Jaro.pyi": 3145980717589050713, + "venv/lib/python3.13/site-packages/pygments/regexopt.py": 16073437303824961930, + "venv/lib/python3.13/site-packages/referencing/tests/test_jsonschema.py": 9815500901482570619, + "venv/lib/python3.13/site-packages/sqlalchemy/sql/default_comparator.py": 47118577003622736, + "venv/lib/python3.13/site-packages/pandas/tests/resample/test_time_grouper.py": 3203729024111501071, + "venv/lib/python3.13/site-packages/_pytest/config/compat.py": 13175516717549204627, + "venv/lib/python3.13/site-packages/pygments/lexers/r.py": 14263133575134645005, + "frontend/src/lib/components/translate/TranslationRunProgress.svelte": 16740229145769290247, + "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/__init__.py": 1437580234680265326, + "venv/lib/python3.13/site-packages/apscheduler/job.py": 1858376671986108667, + "venv/lib/python3.13/site-packages/psycopg2/_json.py": 9729420372294281405, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_core_functionalities.py": 10449747865888948579, + "venv/lib/python3.13/site-packages/h11/_headers.py": 7592730288271984585, + "venv/lib/python3.13/site-packages/gitdb/test/__init__.py": 18393574323937353933, + "venv/lib/python3.13/site-packages/_pytest/logging.py": 10972553724755511468, + "frontend/src/routes/datasets/review/[id]/+page.svelte": 2388350237937943327, + "venv/lib/python3.13/site-packages/h11/_util.py": 9362339074207904329, + "venv/lib/python3.13/site-packages/numpy/_core/_operand_flag_tests.cpython-313-x86_64-linux-gnu.so": 12296711931541109624, + "venv/lib/python3.13/site-packages/PIL/GdImageFile.py": 16875784236394545058, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9207/parameter.py": 2793853093222900337, + "venv/lib/python3.13/site-packages/pandas/tests/frame/test_npfuncs.py": 6132674295193898715, + "frontend/src/lib/api/datasetReview.js": 3023829599261929428, + "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/numpy/core/arrayprint.py": 9652368112174245943, + "venv/lib/python3.13/site-packages/pandas/core/dtypes/base.py": 3628510830969664111, + "venv/lib/python3.13/site-packages/rsa/py.typed": 11041940105507257053, + "venv/lib/python3.13/site-packages/httpx/_exceptions.py": 18399489130669465891, + "backend/src/core/__tests__/test_config_manager_compat.py": 656412918792001580, + "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_style.py": 10405592363651914796, + "venv/lib/python3.13/site-packages/pygments/lexers/kuin.py": 2818054539831699366, + "venv/lib/python3.13/site-packages/pygments/lexers/ecl.py": 12886695201994337568, + "venv/lib/python3.13/site-packages/pandas/_libs/sas.pyi": 873957906443703977, + "venv/lib/python3.13/site-packages/pydantic/errors.py": 3506829204186508192, + "venv/lib/python3.13/site-packages/pluggy/_result.py": 16790448391766505769, + "venv/lib/python3.13/site-packages/pygments/lexers/dylan.py": 16246299896150112270, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/test_numba.py": 1548992314517942530, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/timedeltas/test_constructors.py": 17219764538851313252, + "venv/lib/python3.13/site-packages/pip/_internal/utils/_log.py": 13011536737418204268, + "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/pymysql.py": 12923876736367229454, + "frontend/build/_app/immutable/assets/9.tn0RQdqM.css": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/azure.py": 13529763490186254462, + "venv/lib/python3.13/site-packages/jaraco/functools/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/requests/status_codes.py": 17005213506461710202, + "venv/lib/python3.13/site-packages/pip/_internal/commands/inspect.py": 1401259241736437656, + "venv/lib/python3.13/site-packages/pandas/tests/series/test_validate.py": 2133732492454460539, + "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/nested_secrets.py": 15691917061715429369, + "venv/lib/python3.13/site-packages/greenlet/greenlet_slp_switch.hpp": 1694714764745718414, + "backend/src/services/dataset_review/semantic_resolver.py": 8447496149691924829, + "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_mask.py": 9654897363729130542, + "venv/lib/python3.13/site-packages/pip/_vendor/requests/models.py": 17870758731501836303, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_indexing.py": 5063545640498065297, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/auth.py": 13542332344403032059, + "venv/lib/python3.13/site-packages/anyio/_backends/_asyncio.py": 10265081145401348863, + "venv/lib/python3.13/site-packages/pandas/core/nanops.py": 18291534943985310005, + "venv/lib/python3.13/site-packages/pygments/styles/vs.py": 4188729978573652106, + "backend/src/api/routes/assistant/_llm_planner.py": 17830859532452456684, + "backend/src/api/routes/git/_environment_routes.py": 1034235394475003092, + "backend/tests/conftest.py": 14115149798000023183, + "venv/lib/python3.13/site-packages/idna/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/core/array_algos/replace.py": 1708865864686705833, + "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_groupby.py": 2738671407653333726, + "venv/lib/python3.13/site-packages/gitdb/test/test_example.py": 3039934065817753241, + "venv/lib/python3.13/site-packages/pyasn1/type/base.py": 6801504886392649787, + "venv/lib/python3.13/site-packages/tzlocal/__init__.py": 11017072814026497364, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/Postfix.py": 4440659352851541547, + "venv/lib/python3.13/site-packages/numpy/matrixlib/defmatrix.pyi": 17903213294220335051, + "venv/lib/python3.13/site-packages/pydantic/_internal/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_unique.py": 6234921572794573905, + "venv/lib/python3.13/site-packages/pandas/_libs/lib.cpython-313-x86_64-linux-gnu.so": 6452315003728497116, + "venv/lib/python3.13/site-packages/sqlalchemy/engine/default.py": 7906029092844029127, + "venv/lib/python3.13/site-packages/pygments/lexers/templates.py": 16267123844830647955, + "frontend/src/lib/components/layout/Sidebar.svelte": 15884718235284801177, + "venv/lib/python3.13/site-packages/pandas/io/html.py": 2727247063231114153, + "frontend/src/routes/settings/+page.ts": 3719008513710037840, + "backend/src/api/routes/__tests__/test_clean_release_v2_api.py": 13464989331176891726, + "venv/lib/python3.13/site-packages/itsdangerous/timed.py": 12571102606719555007, + "venv/lib/python3.13/site-packages/pandas/core/indexes/accessors.py": 14394872772838047912, + "backend/src/services/clean_release/stages/no_external_endpoints.py": 11041035366569218866, + "venv/lib/python3.13/site-packages/pandas/core/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/rapidfuzz/utils.pyi": 7400725037332728015, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_loadtxt.py": 17562784940619942447, + "venv/lib/python3.13/site-packages/pygments/styles/stata_dark.py": 324072437809944751, + "backend/src/api/routes/assistant/_dataset_review.py": 14508672919199309579, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_partial.py": 3151286293440416036, + "venv/lib/python3.13/site-packages/pandas/core/strings/object_array.py": 17631047188839635539, + "venv/lib/python3.13/site-packages/sqlalchemy/ext/instrumentation.py": 14882045449667214075, + "venv/lib/python3.13/site-packages/pip/_internal/locations/_sysconfig.py": 4773855595767526182, + "backend/src/plugins/mapper.py": 1970475023222782681, + "venv/lib/python3.13/site-packages/numpy/linalg/tests/test_linalg.py": 2939739913218718132, + "venv/lib/python3.13/site-packages/numpy/polynomial/hermite_e.pyi": 13068936038543812082, + "venv/lib/python3.13/site-packages/pandas/_libs/internals.pyi": 11662356720550765508, + "venv/lib/python3.13/site-packages/pandas/conftest.py": 747626550806435763, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/frequencies/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/test_astype.py": 1961831758405941258, + "venv/lib/python3.13/site-packages/PIL/MpegImagePlugin.py": 7726254767528154514, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/timedeltas/test_reductions.py": 14432782234851468060, + "backend/src/services/clean_release/stages/data_purity.py": 775548350590498835, + "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/format-annotation": 4826455560768665215, + "venv/lib/python3.13/site-packages/websockets/extensions/base.py": 2457233337788783873, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/__init__.py": 8093984834068317399, + "venv/lib/python3.13/site-packages/pandas/core/indexes/timedeltas.py": 13653393430363556843, + "venv/lib/python3.13/site-packages/pandas/util/_print_versions.py": 15326663505771588740, + "venv/lib/python3.13/site-packages/pandas/tests/construction/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/attr/__init__.py": 14436902698244718082, + "venv/lib/python3.13/site-packages/cffi/api.py": 5325821560978502135, + "backend/src/models/llm.py": 14295626272101666880, + "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pygments/lexers/email.py": 4355246279485460399, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_astype.py": 4023134352880775277, + "venv/lib/python3.13/site-packages/pillow.libs/libxcb-64009ff3.so.1.1.0": 7322566017497612912, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_index_col.py": 17604191644943383567, + "venv/lib/python3.13/site-packages/numpy/f2py/src/fortranobject.h": 5980733638838895780, + "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/reporters.py": 10760889726586439724, + "venv/lib/python3.13/site-packages/greenlet/platform/switch_x86_unix.h": 13709837360414450184, + "venv/lib/python3.13/site-packages/gitdb/utils/encoding.py": 1668793658272579497, + "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/numpy/testing/_private/extbuild.py": 4984721349618127021, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ndarray_misc.py": 8706265665356094801, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_casting_unittests.py": 18157503533859249155, + "venv/lib/python3.13/site-packages/passlib/handlers/oracle.py": 12959175637015399815, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_join.py": 1697622393195784944, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_value_counts.py": 15633881149834196174, + "venv/lib/python3.13/site-packages/pandas/tests/strings/test_split_partition.py": 2715491071550545667, + "venv/lib/python3.13/site-packages/jsonschema_specifications/_core.py": 14812112544772987164, + "venv/lib/python3.13/site-packages/pandas/core/internals/concat.py": 12151675567885981464, + "venv/lib/python3.13/site-packages/pip/_internal/locations/__init__.py": 8147012724727395488, + "venv/lib/python3.13/site-packages/uvicorn/py.typed": 15240312484046875203, + "venv/lib/python3.13/site-packages/numpy/fft/_helper.pyi": 9546918341939102632, + "venv/lib/python3.13/site-packages/pip/_vendor/packaging/licenses/_spdx.py": 17182188548503720124, + "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_xs.py": 1897144171324167738, + "venv/lib/python3.13/site-packages/typing_inspection/introspection.py": 13916695705179237047, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/numpy_/test_numpy.py": 9825804096508014886, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/stride_tricks.pyi": 5844806555773292985, + "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_bcrypt.py": 11146468670439284889, + "venv/lib/python3.13/site-packages/more_itertools/recipes.py": 5254043689078173976, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_npfuncs.py": 8238385897366878558, + "venv/lib/python3.13/site-packages/pygments/lexers/freefem.py": 9851243865301700231, + "venv/lib/python3.13/site-packages/pygments/lexers/rdf.py": 14488319292387226505, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py": 6067836157632573182, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_asfreq.py": 2701081989348180239, + "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_dtypes.py": 7550022036887594386, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/segment.py": 2555584120510872966, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_interval_array_equal.py": 15654625365223535344, + "backend/src/services/llm_provider.py": 9619956052011769991, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_ops.py": 16346030307660048773, + "venv/lib/python3.13/site-packages/numpy/core/numerictypes.py": 5776941405348611027, + "venv/lib/python3.13/site-packages/pip/_internal/network/lazy_wheel.py": 12936988990566680659, + "venv/lib/python3.13/site-packages/pandas/core/indexes/datetimes.py": 14331984919364185787, + "backend/src/api/routes/__tests__/test_reports_api.py": 17714266401048048508, + "backend/src/core/migration/archive_parser.py": 8828677257278703059, + "venv/lib/python3.13/site-packages/attr/_version_info.pyi": 7141309436445210354, + "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/WHEEL": 16784970174376303810, + "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/_lint_dependency_groups.py": 2609365889369107154, + "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/WHEEL": 2357997949040430835, + "venv/lib/python3.13/site-packages/numpy/_pyinstaller/tests/test_pyinstaller.py": 9430762168079129025, + "venv/lib/python3.13/site-packages/numpy/lib/tests/test_type_check.py": 3935091606923106753, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_isocalendar.py": 5704842983090753914, + "venv/lib/python3.13/site-packages/PIL/CurImagePlugin.py": 17697303205012181529, + "venv/lib/python3.13/site-packages/PIL/PcfFontFile.py": 8867692961463798279, + "backend/src/plugins/llm_analysis/models.py": 10099813950073320264, + "venv/lib/python3.13/site-packages/ecdsa/numbertheory.py": 13538480862642502330, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/token_endpoint.py": 6118770923176099889, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_iat.py": 3570464615146398178, + "venv/lib/python3.13/site-packages/pandas/tests/series/test_ufunc.py": 669019702416198889, + "venv/lib/python3.13/site-packages/git/objects/tag.py": 7954808535585493300, + "venv/lib/python3.13/site-packages/pip/_internal/metadata/importlib/_envs.py": 5657151394155576509, + "venv/lib/python3.13/site-packages/charset_normalizer/api.py": 9172704759115759638, + "venv/lib/python3.13/site-packages/passlib/tests/test_handlers.py": 4940305787631493030, + "venv/lib/python3.13/site-packages/_pytest/_py/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/io/json/_table_schema.py": 3103776773020058805, + "backend/src/services/clean_release/stages/manifest_consistency.py": 1270636316397468243, + "venv/lib/python3.13/site-packages/numpy/_core/tests/test_indexerrors.py": 4434868847540549873, + "venv/lib/python3.13/site-packages/pandas/tests/copy_view/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8414/__init__.py": 4781700006554860887, + "venv/lib/python3.13/site-packages/numpy/random/_examples/cython/extending.pyx": 756189645898997788, + "venv/lib/python3.13/site-packages/iniconfig/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/passlib/handlers/scram.py": 12281469744083867450, + "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/hist.py": 10928173425078493095, + "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/errors.py": 16711622442922413520, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ndarray_shape_manipulation.pyi": 3533739482029983817, + "venv/lib/python3.13/site-packages/pandas/io/parsers/c_parser_wrapper.py": 5841064965672872661, + "venv/lib/python3.13/site-packages/websockets/streams.py": 15786581670248099415, + "venv/lib/python3.13/site-packages/certifi/cacert.pem": 14727832973577663826, + "venv/lib/python3.13/site-packages/h11/__init__.py": 222801976520197308, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_constructors.py": 11065058462752831997, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/usecols/test_usecols_basic.py": 16382444980424010514, + "venv/lib/python3.13/site-packages/sqlalchemy/testing/fixtures/mypy.py": 823265492261272631, + "backend/src/core/task_manager/models.py": 749015551222331342, + "backend/src/api/routes/dashboards/_helpers.py": 16683849709430404975, + "venv/lib/python3.13/site-packages/sqlalchemy/orm/exc.py": 3242780937124999391, + "venv/lib/python3.13/site-packages/pandas/core/apply.py": 17080038932032802984, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_reorder_levels.py": 10996225584998355824, + "venv/lib/python3.13/site-packages/pandas/core/arrays/base.py": 664515424699746697, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_quantile.py": 17110581927381599978, + "venv/lib/python3.13/site-packages/numpy/_expired_attrs_2_0.pyi": 1424133074692438241, + "venv/lib/python3.13/site-packages/PIL/MspImagePlugin.py": 3034490726971829439, + "venv/lib/python3.13/site-packages/fastapi/params.py": 14263655860695381481, + "venv/lib/python3.13/site-packages/_pytest/freeze_support.py": 494952714451267295, + "venv/lib/python3.13/site-packages/httpx/_client.py": 1063593889704982038, + "venv/lib/python3.13/site-packages/numpy/f2py/_src_pyf.pyi": 8916922961301555974, + "venv/lib/python3.13/site-packages/keyring/util/platform_.py": 16978095707950463638, + "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/format-assertion": 2607512361823362698, + "venv/lib/python3.13/site-packages/pygments/lexers/fift.py": 7537570342576781911, + "frontend/src/services/storageService.js": 14408290095426695791, + "frontend/src/lib/stores/taskDrawer.js": 6659505033581293370, + "frontend/build/_app/immutable/nodes/10.qO4l_hfq.js": 8054490978078371224, + "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/RECORD": 10552906886624188222, + "venv/lib/python3.13/site-packages/passlib/win32.py": 5311393450489898748, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/ssl_.py": 644667973700652263, + "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_bool.py": 433342705586552936, + "backend/src/services/resource_service.py": 4718644821742397530, + "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/LICENSE": 8177430849046795595, + "venv/lib/python3.13/site-packages/numpy/_core/function_base.pyi": 8343632640078378312, + "venv/lib/python3.13/site-packages/pandas/api/extensions/__init__.py": 882327406374020760, + "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/criterion.py": 2042509334195547606, + "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_compression.py": 8061288329598682752, + "venv/lib/python3.13/site-packages/pydantic/parse.py": 13750341403702794392, + "venv/lib/python3.13/site-packages/numpy/fft/tests/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/apply/common.py": 1113935558495455492, + "venv/lib/python3.13/site-packages/numpy/_core/umath.py": 6132761780113682667, + "venv/lib/python3.13/site-packages/pygments/lexers/parsers.py": 12372594608244797844, + "backend/src/models/clean_release.py": 6080208142954589647, + "venv/lib/python3.13/site-packages/pandas/_testing/_hypothesis.py": 12298650110193262367, + "venv/lib/python3.13/site-packages/numpy/testing/_private/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/extension/base/casting.py": 12226803454582253097, + "venv/lib/python3.13/site-packages/pandas/core/computation/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/INSTALLER": 17282701611721059870, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_groupby_subclass.py": 5540948578269213810, + "venv/lib/python3.13/site-packages/pandas/core/indexing.py": 15507869313676722071, + "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/METADATA": 7727489762869155085, + "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_pandas.py": 10894229569442891394, + "frontend/build/_app/immutable/chunks/CH5SIC62.js": 11262658403146762189, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_scalar_compat.py": 1306236983392218709, + "backend/src/api/routes/__tests__/test_profile_api.py": 1724401885939803766, + "backend/logs/app.log.3": 366149754645105088, + "venv/lib/python3.13/site-packages/numpy/_array_api_info.pyi": 13283968924732680159, + "dist/docker/postgres.v1.0.0-rc2-docker.tar": 5933711120559789473, + "venv/lib/python3.13/site-packages/pygments/lexers/stata.py": 7249891970174867363, + "backend/src/api/routes/translate/_schedule_routes.py": 18180097500694105300, + "venv/lib/python3.13/site-packages/numpy/tests/test_numpy_version.py": 849232015288488204, + "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_interval.py": 2613503970235591726, + "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/connection.py": 5582413226288987808, + "venv/lib/python3.13/site-packages/pandas/tests/window/test_pairwise.py": 2673370322448160842, + "venv/lib/python3.13/site-packages/idna-3.11.dist-info/WHEEL": 8600534672961461758, + "venv/lib/python3.13/site-packages/numpy/__init__.py": 2331213407497901634, + "venv/lib/python3.13/site-packages/PIL/ImageMath.py": 7395449734007598797, + "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_getitem.py": 8414677531950073373, + "venv/lib/python3.13/site-packages/passlib/crypto/_blowfish/__init__.py": 3521833849634327520, + "venv/bin/pip": 13861749540792881808, + "backend/src/core/task_manager/cleanup.py": 8316318318890394605, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/color_triplet.py": 17264298271771184, + "venv/lib/python3.13/site-packages/fastapi/encoders.py": 1914192268055730299, + "venv/lib/python3.13/site-packages/pygments/lexers/installers.py": 5083244110640899732, + "venv/lib/python3.13/site-packages/pandas/_libs/ops_dispatch.pyi": 16176428602589420913, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_quoted_character.py": 2316632434571797367, + "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/kdf.pyi": 1626154870044880426, + "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/licenses/LICENSE": 17675192170670564526, + "venv/lib/python3.13/site-packages/authlib/jose/rfc8037/__init__.py": 8705044848308260480, + "venv/lib/python3.13/site-packages/passlib/tests/__init__.py": 16543763165305017760, + "venv/lib/python3.13/site-packages/rapidfuzz/distance/LCSseq.py": 13853220736499979380, + "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/implicit.py": 7379110378465568776, + "venv/lib/python3.13/site-packages/numpy/core/_dtype.py": 2806449741844148191, + "venv/lib/python3.13/site-packages/typing_extensions.py": 8402965285733247527, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/data_with_comments.f": 3980077223827767077, + "venv/lib/python3.13/site-packages/jsonschema/tests/test_cli.py": 3173259257428855556, + "venv/lib/python3.13/site-packages/apscheduler/jobstores/etcd.py": 4078354986605069279, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_indexing.py": 7181087459615188551, + "venv/lib/python3.13/site-packages/fastapi/security/http.py": 8465565118555441408, + "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_is_monotonic.py": 12899848089975919515, + "venv/lib/python3.13/site-packages/sqlalchemy/engine/processors.py": 4817637175145012571, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/color.py": 15062855556511243610, + "venv/lib/python3.13/site-packages/anyio/_core/_streams.py": 6436461519284884601, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/highlighter.py": 10615901258492570740, + "venv/lib/python3.13/site-packages/_pytest/_io/wcwidth.py": 13515196388826152383, + "venv/lib/python3.13/site-packages/click/exceptions.py": 9734955259447933725, + "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/wrapper.py": 4633931060151989960, + "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/WHEEL": 15858869568085970864, + "venv/lib/python3.13/site-packages/uvicorn/main.py": 5843333502356171120, + "venv/lib/python3.13/site-packages/pygments/lexers/verifpal.py": 9190813166686923928, + "venv/lib/python3.13/site-packages/jeepney/auth.py": 10565040329507087892, + "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/WHEEL": 2357997949040430835, + "frontend/src/lib/components/layout/__tests__/test_sidebar.svelte.js": 1424894894434906249, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_log_render.py": 18076931145915444473, + "venv/lib/python3.13/site-packages/pandas/compat/__init__.py": 6077099417711209303, + "venv/lib/python3.13/site-packages/pandas/io/excel/_odfreader.py": 2760916559416783928, + "venv/lib/python3.13/site-packages/bcrypt/_bcrypt.pyi": 15067467792538416274, + "backend/src/services/rbac_permission_catalog.py": 4811877724682885443, + "venv/lib/python3.13/site-packages/numpy/_utils/_pep440.pyi": 6796322258258182775, + "venv/lib/python3.13/site-packages/passlib/utils/des.py": 2650106381178222229, + "venv/lib/python3.13/site-packages/pandas/core/_numba/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/greenlet/PyGreenletUnswitchable.cpp": 3160733517193315684, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/arithmetic.py": 3209727509456212551, + "backend/src/api/routes/git/_gitea_routes.py": 14644218433873522624, + "venv/lib/python3.13/site-packages/fastapi/middleware/asyncexitstack.py": 7733356903092860495, + "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/RECORD": 14375680579341422646, + "venv/lib/python3.13/site-packages/numpy/lib/npyio.pyi": 3212440968296555560, + "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/__init__.py": 1798074863773727377, + "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_astype.py": 7542068949396266883, + "venv/lib/python3.13/site-packages/websockets/extensions/__init__.py": 13067201313921664210, + "venv/lib/python3.13/site-packages/pandas/core/_numba/extensions.py": 4132402557064663751, + "venv/lib/python3.13/site-packages/cffi/commontypes.py": 11198107299826138465, + "venv/lib/python3.13/site-packages/_pytest/scope.py": 7603155109542903644, + "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_formats.py": 3525283725314253763, + "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_almost_equal.py": 9333355453468475330, + "venv/lib/python3.13/site-packages/httpcore/_backends/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/keyring/__main__.py": 14602212239605295451, + "venv/lib/python3.13/site-packages/jeepney-0.9.0.dist-info/licenses/LICENSE": 11986475601091748012, + "venv/lib/python3.13/site-packages/numpy/_core/defchararray.pyi": 2277933368373498515, + "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_check_indexer.py": 2929031395357057009, + "backend/src/services/clean_release/stages/base.py": 7739111130895140155, + "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_compare.py": 171535659467902751, + "venv/lib/python3.13/site-packages/numpy/lib/_arrayterator_impl.py": 4037074830103951000, + "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arccosh.csv": 5882025767947638305, + "venv/lib/python3.13/site-packages/pandas/tests/test_register_accessor.py": 16661086720613729974, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_array_from_pyobj.py": 9596224861290975079, + "venv/lib/python3.13/site-packages/rapidfuzz/_feature_detector_cpp.cpython-313-x86_64-linux-gnu.so": 16337157355618216738, + "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/oauth1_client.py": 3129955464287331242, + "venv/lib/python3.13/site-packages/pandas/tests/apply/__init__.py": 15130871412783076140, + "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_halfyear.py": 587199217232946404, + "venv/lib/python3.13/site-packages/pygments/lexers/jmespath.py": 7426464251945393925, + "venv/lib/python3.13/site-packages/authlib/jose/drafts/_jwe_enc_cryptodome.py": 15753279711312689193, + "frontend/src/components/tasks/LogFilterBar.svelte": 11464828454938370522, + "backend/src/services/reports/__tests__/test_report_normalizer.py": 5030199452684805352, + "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/recfunctions.py": 18330899924171767482, + "venv/lib/python3.13/site-packages/pip/_vendor/rich/_extension.py": 4831602527247293866, + "venv/lib/python3.13/site-packages/authlib/common/urls.py": 13627272625165922482, + "venv/lib/python3.13/site-packages/typing_inspection/py.typed": 15130871412783076140, + "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_isoc.py": 4923640657296076239 } } \ No newline at end of file diff --git a/.axiom/temp/pytest-of-busya/pytest-2/test_tui_real_mode_bootstrap_i0/artifacts.json b/.axiom/temp/pytest-of-busya/pytest-2/test_tui_real_mode_bootstrap_i0/artifacts.json new file mode 100644 index 00000000..c50ba0f0 --- /dev/null +++ b/.axiom/temp/pytest-of-busya/pytest-2/test_tui_real_mode_bootstrap_i0/artifacts.json @@ -0,0 +1 @@ +{"artifacts": [{"id": "artifact-1", "path": "backend/dist/package.tar.gz", "sha256": "deadbeef", "size": 1024, "category": "core", "source_uri": "https://repo.intra.company.local/releases/package.tar.gz", "source_host": "repo.intra.company.local"}]} \ No newline at end of file diff --git a/.axiom/temp/pytest-of-busya/pytest-2/test_tui_real_mode_bootstrap_i0/bootstrap.json b/.axiom/temp/pytest-of-busya/pytest-2/test_tui_real_mode_bootstrap_i0/bootstrap.json new file mode 100644 index 00000000..fc97cd1d --- /dev/null +++ b/.axiom/temp/pytest-of-busya/pytest-2/test_tui_real_mode_bootstrap_i0/bootstrap.json @@ -0,0 +1 @@ +{"candidate_id": "real-candidate-1", "version": "1.0.0", "source_snapshot_ref": "git:release/1", "created_by": "operator", "allowed_hosts": ["repo.intra.company.local"]} \ No newline at end of file diff --git a/.axiom/temp/pytest-of-busya/pytest-2/test_tui_real_mode_bootstrap_icurrent b/.axiom/temp/pytest-of-busya/pytest-2/test_tui_real_mode_bootstrap_icurrent new file mode 120000 index 00000000..9999d590 --- /dev/null +++ b/.axiom/temp/pytest-of-busya/pytest-2/test_tui_real_mode_bootstrap_icurrent @@ -0,0 +1 @@ +/home/busya/dev/ss-tools/.axiom/temp/pytest-of-busya/pytest-2/test_tui_real_mode_bootstrap_i0 \ No newline at end of file diff --git a/.axiom/temp/pytest-of-busya/pytest-current b/.axiom/temp/pytest-of-busya/pytest-current index 10df3d16..8d53bc4e 120000 --- a/.axiom/temp/pytest-of-busya/pytest-current +++ b/.axiom/temp/pytest-of-busya/pytest-current @@ -1 +1 @@ -/home/busya/dev/ss-tools/.axiom/temp/pytest-of-busya/pytest-0 \ No newline at end of file +/home/busya/dev/ss-tools/.axiom/temp/pytest-of-busya/pytest-2 \ No newline at end of file diff --git a/.opencode/agents/closure-gate.md b/.opencode/agents/closure-gate.md index 431d8551..a1316a84 100644 --- a/.opencode/agents/closure-gate.md +++ b/.opencode/agents/closure-gate.md @@ -1,7 +1,7 @@ --- description: Closure gate subagent that re-audits merged worker state, rejects noisy intermediate artifacts, and emits the only concise user-facing closure summary for ss-tools. mode: subagent -model: opencode-go/deepseek-v4-pro +model: opencode/deepseek-v4-flash-free temperature: 0.0 permission: edit: allow diff --git a/.opencode/agents/fullstack-coder.md b/.opencode/agents/fullstack-coder.md index b648a54b..95da2b38 100644 --- a/.opencode/agents/fullstack-coder.md +++ b/.opencode/agents/fullstack-coder.md @@ -1,7 +1,7 @@ --- description: Fullstack Implementation Specialist for ss-tools — owns Python backend + Svelte frontend integration, cross-cutting features, and end-to-end verification. mode: all -model: opencode-go/deepseek-v4-flash +model: opencode/deepseek-v4-flash-free temperature: 0.2 permission: edit: allow diff --git a/.opencode/agents/qa-tester.md b/.opencode/agents/qa-tester.md index 5ef7ff56..281f2fd5 100644 --- a/.opencode/agents/qa-tester.md +++ b/.opencode/agents/qa-tester.md @@ -1,7 +1,7 @@ --- description: QA & Semantic Auditor — orthogonal verification, contract validation, code review, and regression defense for Python (pytest) and Svelte (vitest). mode: all -model: opencode-go/kimi-k2.6 +model: opencode-go/qwen3.6-plus temperature: 0.1 permission: edit: allow diff --git a/.opencode/agents/reflection-agent.md b/.opencode/agents/reflection-agent.md index 06bef9d4..7307e6fa 100644 --- a/.opencode/agents/reflection-agent.md +++ b/.opencode/agents/reflection-agent.md @@ -1,7 +1,7 @@ --- description: Senior reflection and unblocker agent for tasks where a coder entered anti-loop escalation in ss-tools; analyzes architecture, environment, dependency, contract, and test harness failures across Python and Svelte stacks. mode: subagent -model: opencode-go/mimo-v2.5 +model: opencode/big-pickle temperature: 0.0 permission: edit: allow diff --git a/.opencode/agents/semantic-curator.md b/.opencode/agents/semantic-curator.md index 059c4468..098d4f31 100644 --- a/.opencode/agents/semantic-curator.md +++ b/.opencode/agents/semantic-curator.md @@ -1,15 +1,22 @@ --- description: Semantic Curator Agent — maintains GRACE semantic markup, anchors, and index health for ss-tools Python and Svelte code. Read-only file access; uses axiom MCP for mutations. mode: all -model: opencode-go/deepseek-v4-flash +model: opencode/deepseek-v4-flash-free temperature: 0.4 permission: - edit: deny - bash: deny - browser: deny + edit: allow + bash: allow + browser: allow color: accent --- -MANDATORY USE `skill({name="semantics-core"})`, `skill({name="semantics-contracts"})`, `skill({name="semantics-belief"})` +## 0. ZERO-STATE RATIONALE + +You are an autoregressive language model, and so are the Engineer and Architect agents in this project. By nature, LLMs suffer from **Attention Sink** (losing focus in large files) and **Context Blindness** (breaking dependencies they cannot see). +To prevent this, our codebase relies on the **GRACE-Poly Protocol**. Semantic anchors (`#region`/`#endregion`, `[DEF]`/`[/DEF]`, `## @{`/`## @}`) are not mere comments — they are strict AST boundaries. The metadata (`@BRIEF`, `@RELATION`) forms the **Belief State** and **Decision Space**. +Your absolute mandate is to maintain this cognitive exoskeleton. If an anchor is broken, or a contract is missing, the downstream Coder Agents will hallucinate and destroy the codebase. You are the immune system of the project's architecture. + +MANDATORY USE `skill({name="semantics-core"})`, `skill({name="semantics-contracts"})` +MANDATORY USE `skill({name="molecular-cot-logging"})`, `skill({name="semantics-python"})`, `skill({name="semantics-svelte"})` #region Semantic.Curator [C:5] [TYPE Agent] [SEMANTICS curation,anchors,index,health] @BRIEF WHY: Maintain the project's GRACE semantic markup, anchors, and index in ideal health. You are the immune system — if anchors break, downstream coder agents hallucinate. @@ -20,7 +27,7 @@ MANDATORY USE `skill({name="semantics-core"})`, `skill({name="semantics-contract #endregion Semantic.Curator ## AXIOM MCP STATUS (ты должен это знать) -Axiom MCP-сервер v0.3.1 полностью работоспособен. DuckDB-индекс содержит 2543 контракта, 1987 связей, 536 файлов. +Axiom MCP-сервер полностью работоспособен. **Твои ключевые инструменты:** - `axiom_semantic_validation audit_contracts` — структурный аудит @@ -29,17 +36,13 @@ Axiom MCP-сервер v0.3.1 полностью работоспособен. D - `axiom_contract_refactor` — переименование/перемещение контрактов с checkpoint - `axiom_contract_metadata` — обновление метаданных - `axiom_semantic_index rebuild` — переиндексация (full — работает, incremental — не используй) -- `axiom_semantic_discovery search_contracts` — поиск по всем 2543 контрактам +- `axiom_semantic_discovery search_contracts` — поиск по всем контрактам После любой мутации запускай `axiom_semantic_index rebuild` для обновления индекса. --- -## 0. ZERO-STATE RATIONALE -You are an autoregressive language model, and so are the Engineer and Architect agents in this project. By nature, LLMs suffer from **Attention Sink** (losing focus in large files) and **Context Blindness** (breaking dependencies they cannot see). -To prevent this, our codebase relies on the **GRACE-Poly Protocol**. Semantic anchors (`#region`/`#endregion`, `[DEF]`/`[/DEF]`, `## @{`/`## @}`) are not mere comments — they are strict AST boundaries. The metadata (`@BRIEF`, `@RELATION`) forms the **Belief State** and **Decision Space**. -Your absolute mandate is to maintain this cognitive exoskeleton. If an anchor is broken, or a contract is missing, the downstream Coder Agents will hallucinate and destroy the codebase. You are the immune system of the project's architecture. ## 1. OPERATIONAL RULES & CONSTRAINTS - **READ-ONLY FILESYSTEM:** You have **NO** permission to use `write_to_file`, `edit_file`, or `apply_diff`. You may only read files to gather context. @@ -56,7 +59,6 @@ Your absolute mandate is to maintain this cognitive exoskeleton. If an anchor is ## 3. HEALTH AUDIT CHECKLIST For each file scanned: - [ ] Every `#region` has a matching `#endregion` with the same ID -- [ ] Every `[DEF:...]` has a matching `[/DEF:...]` - [ ] Every `## @{` has a matching `## @}` - [ ] C4 contracts have `@PRE`, `@POST`, `@SIDE_EFFECT` - [ ] C5 contracts additionally have `@RATIONALE`, `@REJECTED`, `@DATA_CONTRACT`, `@INVARIANT` diff --git a/.opencode/agents/speckit.md b/.opencode/agents/speckit.md index 780df5e7..0dca5aaa 100644 --- a/.opencode/agents/speckit.md +++ b/.opencode/agents/speckit.md @@ -1,7 +1,7 @@ --- description: Speckit Workflow Specialist — runs the full feature lifecycle from specification through planning, task decomposition, and implementation for Python/Svelte ss-tools features. mode: all -model: opencode-go/deepseek-v4-pro +model: opencode/deepseek-v4-flash-free temperature: 0.2 permission: edit: allow diff --git a/.opencode/agents/svelte-coder.md b/.opencode/agents/svelte-coder.md index 95e8b66d..4ff62017 100644 --- a/.opencode/agents/svelte-coder.md +++ b/.opencode/agents/svelte-coder.md @@ -1,7 +1,7 @@ --- description: Svelte Frontend Implementation Specialist for ss-tools — implements Svelte 5 (Runes) UI with Tailwind CSS, browser-driven validation, and UX state machines. mode: all -model: opencode-go/deepseek-v4-flash +model: opencode/deepseek-v4-flash-free temperature: 0.1 permission: edit: allow diff --git a/.opencode/agents/swarm-master.md b/.opencode/agents/swarm-master.md index 1ee6013e..85783191 100644 --- a/.opencode/agents/swarm-master.md +++ b/.opencode/agents/swarm-master.md @@ -1,7 +1,7 @@ --- description: Strict subagent-only dispatcher for semantic and testing workflows; never performs the task itself and only delegates to worker subagents (python-coder, svelte-coder, fullstack-coder, qa-tester, reflection-agent, closure-gate). mode: all -model: opencode-go/deepseek-v4-pro +model: opencode/big-pickle temperature: 0.0 permission: edit: deny diff --git a/.opencode/skills/semantics-belief/SKILL.md b/.opencode/skills/semantics-belief/SKILL.md deleted file mode 100644 index 0bb1ad00..00000000 --- a/.opencode/skills/semantics-belief/SKILL.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -name: semantics-belief -description: Core protocol for Thread-Local Belief State, runtime reasoning markers, and interleaved thinking across Python-first and Svelte semantic projects. Wire format superseded by molecular-cot-logging. ---- - -#region Std.Semantics.Belief [C:5] [TYPE Skill] [SEMANTICS belief,runtime,reasoning] -@BRIEF Conceptual specification of the Belief-State protocol: REASON/REFLECT/EXPLORE topology, interleaved thinking (GLM-5), and Micro-ADR escalation. All operational implementation details are in molecular-cot-logging. -@RELATION DEPENDS_ON -> [Std.Semantics.Core] -@RELATION REPLACED_BY -> [MolecularCoTLogging] -@RELATION SUPERSEDED_BY -> [MolecularCoTLogging] -@INVARIANT Implementation of C4/C5 complexity nodes MUST emit reasoning via structured markers before mutating state or returning. -@RATIONALE The conceptual triad (REASON/REFLECT/EXPLORE) is the invariant kernel — it maps directly to the molecular CoT paper's three chemical bonds. The wire format changes (legacy `reason()`/`explore()`/`reflect()` → `log()` with JSON lines) but the semantics are identical. -@REJECTED Retaining `[Entry]`/`[Exit]`/`[Action]`/`[COHERENCE:]` markers rejected — these are too generic, do not trace reasoning bonds, and are explicitly deprecated by molecular-cot-logging. - -⚠️ OPERATIONAL SUPERSEDED — This skill describes the CONCEPTUAL belief-state protocol -(REASON/REFLECT/EXPLORE topology). For actual implementation and wire format, -use `skill({name="molecular-cot-logging"})`. The code examples below are retained -for conceptual reference only and SHOULD NOT be used as implementation templates. - -## 0. INTERLEAVED THINKING (GLM-5 PARADIGM) - -You are operating as an Agentic Engineer. To prevent context collapse and "Slop" generation during long-horizon tasks, you MUST utilize **Interleaved Thinking**: you must explicitly record your deductive logic *before* acting. -The Molecular CoT paper models this as three chemical bonds: **Deep-Reasoning**, **Self-Reflection**, **Self-Exploration**. Our markers (REASON / REFLECT / EXPLORE) are the runtime manifestation of these bonds. - -For the concrete logging functions and wire format, load `skill({name="molecular-cot-logging"})`. - -## I. THE THREE MOLECULAR BONDS (SEMANTIC INVARIANTS) - -These semantics are invariant across ALL wire formats. The meaning of each marker never changes: - -| Bond | Marker | Molecular CoT Role | When to emit | -|------|--------|-------------------|--------------| -| Deep-Reasoning | **REASON** | Extends the logical backbone | **BEFORE** I/O, state mutation, or algorithmic step | -| Self-Reflection | **REFLECT** | Folds back to validate | **AFTER** success, before returning verified outcome | -| Self-Exploration | **EXPLORE** | Branches on assumption failure | **WHEN** `@PRE` guard fails, fallback path, error handler | - -**The causal chain is REASON → (success) → REFLECT, or REASON → (failure) → EXPLORE.** Every trace forms a directed acyclic graph where REASON nodes have exactly one outgoing edge. - -For implementation of these markers as JSON-line log entries, see `skill({name="molecular-cot-logging"})`. - -## II. WIRE FORMAT AND LEGACY→MOLECULAR-COT MAPPING - -### Conceptual invariant -The belief-state semantics are independent of wire format. Three implementations exist: - -| Implementation | Status | Wire format | -|---------------|--------|-------------| -| Legacy `[Entry]`/`[Exit]`/`[Action]`/`[COHERENCE:]` | **Deprecated** | Generic text prefixes, no bond tracing | -| Legacy `logger.reason/explore/reflect`, `belief_scope()` | **Valid but superseded** | `[REASON]`/`[REFLECT]`/`[EXPLORE]` text prefixes | -| Molecular CoT `log(src, marker, msg, data)`, `cot_span()` | **Target** | Structured JSON lines with `trace_id` | - -### Legacy→Molecular CoT mapping (for migration understanding) - -| Legacy marker | Molecular CoT equivalent | Condition | -|--------------|--------------------------|-----------| -| `[Entry]` | REASON | Always | -| `[Exit]` | REFLECT | On success | -| `[Exit]` | EXPLORE | On failure | -| `[Action]` | REASON | Always | -| `[COHERENCE:OK]` | REFLECT | Validation passed | -| `[COHERENCE:FAILED]` | REFLECT (with error data) | Validation failed | -| `logger.reason(msg)` | `log(src, "REASON", msg)` | — | -| `logger.explore(msg)` | `log(src, "EXPLORE", msg)` | — | -| `logger.reflect(msg)` | `log(src, "REFLECT", msg)` | — | -| `belief_scope("id")` | `cot_span("id")` | Context manager / decorator | - -### Transition rule -- Files **already** using `logger.reason/explore/reflect`: semantics are correct, marker names match. Leave as-is. Convert only when touching the file for other reasons. -- **New** C4/C5 functions: use the molecular-cot-logging protocol exclusively. Load `skill({name="molecular-cot-logging"})` for the API. -- No `trace_id` propagation in legacy code — molecular-cot-logging requires it for all new code. - -## III. MICRO-ADR ESCALATION (UNCHANGED) - -The Belief State protocol is physically tied to Architecture Decision Records (ADR). -If your execution path triggers an EXPLORE due to a broken assumption AND you successfully implement a workaround that survives into the final code: -**YOU MUST ASCEND TO THE CONTRACT HEADER AND DOCUMENT IT.** -Add `@RATIONALE [Why you did this]` and `@REJECTED [The path that failed during EXPLORE]`. -Failure to link a runtime EXPLORE to a static `@REJECTED` tag is a fatal protocol violation that causes amnesia for future agents. - -## IV. PYTHON: CONCEPTUAL PATTERN - -The belief-state protocol prescribes a structured try/except flow: - -1. **REASON** — emit before any I/O or state mutation, describing intent and context. -2. **REFLECT** — emit on successful completion, recording the verified outcome. -3. **EXPLORE** — emit in error/fallback paths, recording the failure reason. - -For the actual Python implementation (import paths, function signatures, `trace_id` seeding), load `skill({name="molecular-cot-logging"})`. The conceptual equivalent of `belief_scope()` is `cot_span()`. - -## V. SVELTE: CONCEPTUAL PATTERN - -Frontend components follow the same REASON→REFLECT/EXPLORE topology: - -1. **REASON** — emit before API calls, user actions, or state transitions. -2. **REFLECT** — emit after successful data fetch or DOM mutation. -3. **EXPLORE** — emit in error handlers and fallback UI paths. - -For the actual Svelte implementation (imports, browser console protocol, trace context), load `skill({name="molecular-cot-logging"})`. - -#endregion Std.Semantics.Belief diff --git a/backend/git_repos/remote/test-repo.git/HEAD b/backend/git_repos/remote/test-repo.git/HEAD new file mode 100644 index 00000000..cb089cd8 --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/backend/git_repos/remote/test-repo.git/config b/backend/git_repos/remote/test-repo.git/config new file mode 100644 index 00000000..07d359d0 --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/config @@ -0,0 +1,4 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = true diff --git a/backend/git_repos/remote/test-repo.git/description b/backend/git_repos/remote/test-repo.git/description new file mode 100644 index 00000000..498b267a --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/backend/git_repos/remote/test-repo.git/hooks/applypatch-msg.sample b/backend/git_repos/remote/test-repo.git/hooks/applypatch-msg.sample new file mode 100755 index 00000000..a5d7b84a --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/hooks/applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/backend/git_repos/remote/test-repo.git/hooks/commit-msg.sample b/backend/git_repos/remote/test-repo.git/hooks/commit-msg.sample new file mode 100755 index 00000000..b58d1184 --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/hooks/commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/backend/git_repos/remote/test-repo.git/hooks/fsmonitor-watchman.sample b/backend/git_repos/remote/test-repo.git/hooks/fsmonitor-watchman.sample new file mode 100755 index 00000000..23e856f5 --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/hooks/fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/backend/git_repos/remote/test-repo.git/hooks/post-update.sample b/backend/git_repos/remote/test-repo.git/hooks/post-update.sample new file mode 100755 index 00000000..ec17ec19 --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/hooks/post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/backend/git_repos/remote/test-repo.git/hooks/pre-applypatch.sample b/backend/git_repos/remote/test-repo.git/hooks/pre-applypatch.sample new file mode 100755 index 00000000..4142082b --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/hooks/pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/backend/git_repos/remote/test-repo.git/hooks/pre-commit.sample b/backend/git_repos/remote/test-repo.git/hooks/pre-commit.sample new file mode 100755 index 00000000..29ed5ee4 --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/hooks/pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff-index --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/backend/git_repos/remote/test-repo.git/hooks/pre-merge-commit.sample b/backend/git_repos/remote/test-repo.git/hooks/pre-merge-commit.sample new file mode 100755 index 00000000..399eab19 --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/hooks/pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/backend/git_repos/remote/test-repo.git/hooks/pre-push.sample b/backend/git_repos/remote/test-repo.git/hooks/pre-push.sample new file mode 100755 index 00000000..4ce688d3 --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/hooks/pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/backend/git_repos/remote/test-repo.git/hooks/pre-rebase.sample b/backend/git_repos/remote/test-repo.git/hooks/pre-rebase.sample new file mode 100755 index 00000000..6cbef5c3 --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/hooks/pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/backend/git_repos/remote/test-repo.git/hooks/pre-receive.sample b/backend/git_repos/remote/test-repo.git/hooks/pre-receive.sample new file mode 100755 index 00000000..a1fd29ec --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/hooks/pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/backend/git_repos/remote/test-repo.git/hooks/prepare-commit-msg.sample b/backend/git_repos/remote/test-repo.git/hooks/prepare-commit-msg.sample new file mode 100755 index 00000000..10fa14c5 --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/hooks/prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/backend/git_repos/remote/test-repo.git/hooks/push-to-checkout.sample b/backend/git_repos/remote/test-repo.git/hooks/push-to-checkout.sample new file mode 100755 index 00000000..af5a0c00 --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/hooks/push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/backend/git_repos/remote/test-repo.git/hooks/update.sample b/backend/git_repos/remote/test-repo.git/hooks/update.sample new file mode 100755 index 00000000..c4d426bc --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/hooks/update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/backend/git_repos/remote/test-repo.git/info/exclude b/backend/git_repos/remote/test-repo.git/info/exclude new file mode 100644 index 00000000..a5196d1b --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/backend/git_repos/remote/test-repo.git/objects/00/fcf77cecdf261aef91eda792ab3384a3339922 b/backend/git_repos/remote/test-repo.git/objects/00/fcf77cecdf261aef91eda792ab3384a3339922 new file mode 100644 index 0000000000000000000000000000000000000000..bfc7b6a4eccbd8882252d35329d8c8182b0d9595 GIT binary patch literal 592 zcmV-W0{(yIOOcZT+LrBDHzP5Spnk!2lBPvLP}Is{OFhCzV(06- zq@*B44Ih@XJHy=_F;jI$X0zEBqoe><@e)$9lm(E*sR3bmCC=nwPj*goMZQKk7@=ij zWnHDDa!N%4w3UT~oMq>KA;Ena%fWJ~OqY9=@64VXyd`s4rXXs#=A}s^LU{gM3sy*F zK?fivLUCuX_VISHTVM$xqAoqd*4k4DiOJ!5-bJhRwu^37AK2}(&t7l3X#aiHMb}S# zbhv-$u)Eb$7kyjzD)W6`H^1ps<{x)#mydw~r$&P@IP@V*xW8L%mu=haRGYB4by)In znv8+NI56u5+L_3Db0Bx?02-J5MhjA$*;Q7bnW%HXOuGVLiXT&QF`yTpFyo3so>Ec| zsGp)|qCYBc*DeGfVFoHIEgIHWc;^v5YL2dQjX7ps6i>++xDJWhHQwQ$zwo4FDX}q% zVafF$*L0rxLtejC0Y967U1jaKznt;2DcrGQw6n z-7{t{7{ot*(aV2B>E!%Fk?65g_%dISd;WWpNle8R?5)^0;Loa} zK>zzp3Bj%Q*X-_h;Tra1j|#YyK5_H3X3GVo3@v(C9DREG&^YzakU> literal 0 HcmV?d00001 diff --git a/backend/git_repos/remote/test-repo.git/objects/17/66251d8cb2693136e09ea3def3e776559cb722 b/backend/git_repos/remote/test-repo.git/objects/17/66251d8cb2693136e09ea3def3e776559cb722 new file mode 100644 index 00000000..e2eac3cb --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/objects/17/66251d8cb2693136e09ea3def3e776559cb722 @@ -0,0 +1,2 @@ +xA + ֞H55JQ }+ܽ3=B/GѫGH쪝wYqpӀq !30O7 \ No newline at end of file diff --git a/backend/git_repos/remote/test-repo.git/objects/22/91d2eb86d77accf7401f8952778809cd1aa4d4 b/backend/git_repos/remote/test-repo.git/objects/22/91d2eb86d77accf7401f8952778809cd1aa4d4 new file mode 100644 index 0000000000000000000000000000000000000000..86ef724e6d326af1cbbc97028e02f1a33367bffb GIT binary patch literal 33 ocmb{(yIn@4{j9D~AXrDty>+zrHKWE!v`j z4&0gL?CeO|2hE_qTPO@UmgqaFd9?p^-YH|1jOJ$ner(~fP-|ui)a=a;; z?d>jU479}Hl3gYuIeGu3wj7jZ-nWhwMR-Q z$FdnsZZQ^!9%u2lRt?vH|$n+Z$C zPg-dIj9}hSZ8Jjog_Yv0WStrMPK*N|aRA=6ljh?%z3^UlgAp&f7X4UVFsA!IQ9p?% pQCY~4FsogmH_bE{i(J=@=ACF;uG?YY2;-=+v(R;-`U$cc%Q|xP#*Y91 literal 0 HcmV?d00001 diff --git a/backend/git_repos/remote/test-repo.git/objects/38/0395343915d386a8d58774cc6c6677205065e8 b/backend/git_repos/remote/test-repo.git/objects/38/0395343915d386a8d58774cc6c6677205065e8 new file mode 100644 index 0000000000000000000000000000000000000000..e65db436d0e396c1ba6c2bc1f6e6b62be94deb60 GIT binary patch literal 508 zcmV{7wWD;G_twzPg z`7I~zueb9ksk#@?ERw2Ph2Q)A^;<$e_(6BRt8wneSH2jaB6dB#= zK+UUFYTkkS6^D7^6e#=LCme&*vSB`UobT`W{o$TJ+&=91_dT&ap#wT?6`wbH-NxBx zKDSsE^eEe-w7mk_Wv)sXV{kk=JVGF)_J^AhlGenoPdcSHMYBT}Bh0iNP5L_eM^l)~ zDd&_)wNJN)54+DJgfD|b@5!}?(W3pAo4c7hf&UnNu-y&>nuY}zlc=QE6p#18?(9Gk zC)EQPh zMb<1Pk%4w71{Me}dA->#f%fmN;Fy9@GmCi<;>Ssx9!}!%;qjiR;NQhfWZ<+2iqC|} zETu&nMhdz3iN-0K#i6B~QYx7R1$n&eVAI#Uq0MI2@>|fBJZj3=?cP`Pzr%gaNE1@t zCH$bC_D2KtjG`3t`4h|8=$ReAPe(OPT|L3r)_t$LT7s4}^euE_I}HPu6+J-Qen4}_ q?|7vlLBu3>g+aCFQE9AY)5^N%9Vv9r;yW literal 0 HcmV?d00001 diff --git a/backend/git_repos/remote/test-repo.git/objects/4f/4e0958b3a42eff67a2b8cfd084d05c43e54716 b/backend/git_repos/remote/test-repo.git/objects/4f/4e0958b3a42eff67a2b8cfd084d05c43e54716 new file mode 100644 index 0000000000000000000000000000000000000000..5805fedd6867af1cd2aa74c13ad0259810cd706b GIT binary patch literal 1191 zcmV;Y1X%lc0j-x!Z`(K!hWG4W!AsE-3z8y5$~Pwt+MsP*IBAQ;Vqx$z7OGf=EH~-D zFGY%})ynn)o0~+<4Bv+{98#*P707ZX{xWj6R<&%*sx8~fPQll@sSLP~n{TgoU@luZ zF?Oe$a@&^mW(qd@s+#ECu7BE9`}-+)?0i;hE30-r(Y9$zS6Z`DKazbM(z1)OGPadv zl_G5Ssw#JDYo?%W_I9%0m;RBdoGGCMEDEC_C4#}iN)3^cMUiWbjkc3*y(@#N2>_Sx zX3IO6@j?(G_|%U8px0$(8tYa6^KTgFA`cD2@Pii=JvtxRwAbDa6B0fGu(sv>y7ijU zz^*E_y^#-TwfsVTs<-!V5_-V)vEH=_%o=c6?>B8z+FkG36Q)Q# zA$LSmpD1iH0Vxv*N=!2-U1l+%lp9n8|1m;hEh8>NX9<(xDMI=iVJ7;41H!jW{n)O- zQnt4L*hA(0YlJE|!H#ML5#<_ElshOWk}%74CP>C5LeXIq%J^Cq9G{2k4a3w&(#CpS zDQ#mV`T7-D?i*RX9wPApk~9wGicn~C&3z>j3#F0_TIz&!I7cFn6)}c{oI!>#auz8W zoTP&x~)p0-xEa-)BMFSij9yc#m56vwog-057396J91sqzIWt+p`F z3}p_{JQq6nk1-a!%Q!v1+mhia#}6RXD|m!Tz9DQh&Q|{E6jH@{8H!`?t%*=bQQJZaKTT{WM!%-P{cc2ZBRv|NSyf z;%ru6pTu#+Bln2|fywuO3mkOgB=GI>dcL}zj|=OT()YNGC>@>SQf5w)Tr(3C#UX)- z${dbOrW4=C4JNTUb|e1v-PLSqn z?w+GQS9ypC2Wq+*d*kpm#_2{vlwZX&z9zqAw4WfRkQ|=Bah_k{g5}|%{2vP}>HFHt zORIlGUbw^#8ZYc`e}khmsY}sbN?j_KBkD%>T#`4qb0&Ey+)K$zb$UczSiC_WOzH;h zKB-I5UP@i+QK!@mF0M)4;0BS@rD!jqZa%wxcd?i)=c_MQ%iHV4&FcNt-&63NOuC9T z{vWT?yz##;-|fnkRco7-t~ai{_xH&7+vk6v+O>VKt9S&2zrgRd*@b^X{06;2lb_2t F#YO0rQT_k` literal 0 HcmV?d00001 diff --git a/backend/git_repos/remote/test-repo.git/objects/52/ec4a78c629329b8b572ec9d5205271c111baac b/backend/git_repos/remote/test-repo.git/objects/52/ec4a78c629329b8b572ec9d5205271c111baac new file mode 100644 index 0000000000000000000000000000000000000000..4ca7aa6f290b2ca0beb5121d4b811d6ec4d55758 GIT binary patch literal 72 zcmV-O0Jr~m0V^p=O;s>8WiT`_Ff%bxC{K#dNKMQs$%rq=FDT7PEXmBzi#OD(Ow7$; ecqz!a`qA7Vjr908*Zx>6m@ZPo$qN9n5f_sgo**y) literal 0 HcmV?d00001 diff --git a/backend/git_repos/remote/test-repo.git/objects/59/3a37acec7d2bddce10df90ab17bc9ede52e523 b/backend/git_repos/remote/test-repo.git/objects/59/3a37acec7d2bddce10df90ab17bc9ede52e523 new file mode 100644 index 0000000000000000000000000000000000000000..9187c216a68b2b48b0235cf034cc08f5a5025886 GIT binary patch literal 380 zcmV-?0fYW{0V^p=O;s>4Gh{F{FfcPQQEK!v1@VT)1`xGM2VQxeTmDqIf2XwS#yxxjQqLZUL)C`o z7v-cBgFF%s4L(C73y7}D4FzkvzVAM$nE5@8SF5V%O;yJ%3|%1aXXb<4WdzaXarp0( atN*|5pYd|fs(7Pr$yp1VCIJBG%DNpScey73 literal 0 HcmV?d00001 diff --git a/backend/git_repos/remote/test-repo.git/objects/5a/82ef700fef88b69cd480e4025283809496ee20 b/backend/git_repos/remote/test-repo.git/objects/5a/82ef700fef88b69cd480e4025283809496ee20 new file mode 100644 index 0000000000000000000000000000000000000000..4fd753a1597ceb5e91ccea85a73aa7833d5ba607 GIT binary patch literal 168 zcmV;Z09XHb0hNwPP6ROw06F(7d;}q+#IZZc2qC`W#I}Y*lTkXu`&oWK9qLw6^>G{@ z3o!A+nr2`cD500)>{%-}+^wr6O2pDEQ&g?maJ$L0&jqa28Z&q5(ovJUHYwCY-V3(K zQmW5OI`!RxQz>n;%kb4K$wh&k5~i3`JX_+jgRXUqQ6Y;Lk14ejXy_nXQx WP&uz{$W-t-4mi&jwXbghRYVLxf>0$pnx&PN9Y4)2R4$hO9JEnCHeyU)R(H_x~^FO zz1>Mm35XJDJCSjGUfdit>KHK2!Gsf<$wzXFMrK8CdDRAw)CHbBHMq*S_udauYw5>Q nnaT~&xuDS)>tV0Q6n}#9˛qfHޚKTSByVsp3|7C{K'1f)2“[ؖLGe`5~_ᶏ>-%OwU \ No newline at end of file diff --git a/backend/git_repos/remote/test-repo.git/objects/6f/85e20ce3ef98cf07a2f102498b71b9462552c5 b/backend/git_repos/remote/test-repo.git/objects/6f/85e20ce3ef98cf07a2f102498b71b9462552c5 new file mode 100644 index 0000000000000000000000000000000000000000..a1d5aeb77b65624fb27fa152aef3012b251976c7 GIT binary patch literal 68 zcmV-K0K5Nq0V^p=O;s>8WH2-^Ff%bx2+uFdNr`t#%*!s0cS$Tsj5pM)Ow7$;@b}}4 a*t|sVfBK>w=P$Heh;e@EE(QQV?-o6uJstr7 literal 0 HcmV?d00001 diff --git a/backend/git_repos/remote/test-repo.git/objects/71/47ad0836409b35c1650dddf5fa6329ba61a824 b/backend/git_repos/remote/test-repo.git/objects/71/47ad0836409b35c1650dddf5fa6329ba61a824 new file mode 100644 index 0000000000000000000000000000000000000000..dc2e6feefe14ef6188462bff5855e303e1ce99d5 GIT binary patch literal 58 zcmV-A0LA}!0V^p=O;s>4WH2-^Ff%bxNUccBEyzhN)~ig+&0(-(eUtYsz@_=fo?3 literal 0 HcmV?d00001 diff --git a/backend/git_repos/remote/test-repo.git/objects/79/b070ad8af7bbc12169f7660d2a7a72ec7a889a b/backend/git_repos/remote/test-repo.git/objects/79/b070ad8af7bbc12169f7660d2a7a72ec7a889a new file mode 100644 index 0000000000000000000000000000000000000000..adcb31b2dd1b2f60daa92e5dd93b07d1398ef2c9 GIT binary patch literal 407 zcmV;I0cies0dQe>R&weTR@% z?V*T+=le!8KYw6+Frsg|PsuwZJ;OwU_!gqKyChCw5uanY=1XNMVRTD&VIIU>yswaA zcB3P!&FxoV{(91>ddHupZ2d5vC zI>ir5>B5>R#(3gfax5!cax-!)yZYEGscL@Lt=Uba8T-6ijjG$t5`*|tG;1H<(|OJ~ zT)Fs9$Zv%>Eevy}55Cv-`2a7Z*Day^)=F`95YKc3YFi_l#y-oo2a;d_rS0pk8@v8M zI9Bfz)BRtlpVX78EM!QO^){iyW;~!JY3jzvR_*uF><H%~)^3 B%e4Ri literal 0 HcmV?d00001 diff --git a/backend/git_repos/remote/test-repo.git/objects/8c/4ea7958b7a7e140d27e1e7d8d1f9912fdf5992 b/backend/git_repos/remote/test-repo.git/objects/8c/4ea7958b7a7e140d27e1e7d8d1f9912fdf5992 new file mode 100644 index 0000000000000000000000000000000000000000..d88255f363538e0c774f20b24372d76dc0d31d0a GIT binary patch literal 517 zcmV+g0{Z=U0c}#rj+;Ob&6%(0n@@}Y<6v`~B!@_z*s?u`Q53a$DR65Vn(4)3=j&4q zSXq=72kO0AUlrGelXaDUa9RnVJ?o$*hhUi|j~3XgH1B;P!3nDduS{Q)K4_f?uwFF^ zB;~iiA;F>>mEf7uZssoPC-t`hQ@hafV4bIzA{m%vovRZRI|1wi#%KWfw|B$>RJ<%XD=f>MPiRyPNjulOJtz;%45^_+`>pexU~!? zV-`8;-ZZPp4VWDX6NWhD_aA6!)hUm~i&ZS%G5Z>Zd9-MZav=`hDiNpcC_V1!ez&Km z-D!&<*1Xd>$tuH#kON_Q$#Bj&4lzPl+oBT8qiDzHrxBWDih{*AS@X)U$l>{LFA`}p z?(5sQP>Q~>kAGYyT|V!gAGcq|q;MT9IEV6|#%&$HKJ91f%-pBoyy>=#gRY6UA&Nbj6%mGgI0!LaDS)Qj^{GyOvbwF_g?M#&uMQVb6lTk!J zT&lw2zoSR=|L64<03}6fJzQ~R)7>(01{$lGaK}PWvL?BZyjcm6LX&UOvRW=vp65l% zg;=g-#rel|m0Z9^anSoAd&m;WJagdblwl=`rV5v}7&bRfZ@?Ni5Dt%1xU&X$B$NW[Fq埇jx7LV}2A|){>W)MY*R'uz8_𮮝>3ahbɱTfC:J.ZZU5 ?>ZGy8kAJ̈́9Mv?0ϨN(Ra[qZs{l;)V7i{ 퍸 t؛n<\R=G҂ l̘ \ No newline at end of file diff --git a/backend/git_repos/remote/test-repo.git/objects/a7/49f11fad695dff77faf1708c7320867d0be1df b/backend/git_repos/remote/test-repo.git/objects/a7/49f11fad695dff77faf1708c7320867d0be1df new file mode 100644 index 0000000000000000000000000000000000000000..6a64204d338ae9ea6851be4c4e36982aebff3112 GIT binary patch literal 217 zcmV;~04D!<0V^p=O;s>5v}7&bRfZ@?Ni5Dt%19XD~D{Ff%bx2y%6F@paY9O<_=)c!kL3e?z4~e#x0=@Ca0% literal 0 HcmV?d00001 diff --git a/backend/git_repos/remote/test-repo.git/objects/c5/b992984fe856bd81206304a881faa3087937cf b/backend/git_repos/remote/test-repo.git/objects/c5/b992984fe856bd81206304a881faa3087937cf new file mode 100644 index 0000000000000000000000000000000000000000..b5475aed0046ef55d3873b594e6282a44e8101db GIT binary patch literal 188 zcmV;t07L(H0hLcnP6aUxV?C$H9)U7x`Uyf$Y~BsHKtC?97zUL-&QCWS052@da$>oj z$MG>qLb{s+AT(AdJ*Dn@Z03su)CQ+ceJ+T)w`Q%#_LT=dCpFJvDXRpt?hG1uubi_u zw*)poa@J{A|Ai08gFe3|096 literal 0 HcmV?d00001 diff --git a/backend/git_repos/remote/test-repo.git/objects/cf/d2dcbd55735b8cedf21e04e64ac627c6f9a458 b/backend/git_repos/remote/test-repo.git/objects/cf/d2dcbd55735b8cedf21e04e64ac627c6f9a458 new file mode 100644 index 0000000000000000000000000000000000000000..d9e47acf332013e421940300a99764973ab5b110 GIT binary patch literal 210 zcmV;@04@J`0hNzSP6IIzL|OY3y$nJD|J#mG#3A4SZM$1Rn!%CBf$K9MaR6#ni+Xyh z+Sm1cg3bAE4rUOT<{5qT9Um0k6DGc-wfu^W5vp zwjF2h%l5eRO3N7xV%Elao#8?6QT6xG+<||is_sTU$kM;=PjDT5?UO;6=56rPj~*A`bIiEW^nJ+8`f1/B8I<|#a%M!l?sz;^YJa +)p^NT\7b{m ܲkFXybǶ{%kޏ0ׇC ;ݥ?JCI&U;Jc-V҄e75(7 \ No newline at end of file diff --git a/backend/git_repos/remote/test-repo.git/objects/e9/1109abe29d5228675fecd6fc38a097147c090d b/backend/git_repos/remote/test-repo.git/objects/e9/1109abe29d5228675fecd6fc38a097147c090d new file mode 100644 index 0000000000000000000000000000000000000000..0386f3d011129be797ecb6bfa5348caaa3239e13 GIT binary patch literal 10181 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 BW3K=J literal 0 HcmV?d00001 diff --git a/backend/git_repos/remote/test-repo.git/objects/f7/6ee984d9d47c3cd0b362fdf60a47162bbc202d b/backend/git_repos/remote/test-repo.git/objects/f7/6ee984d9d47c3cd0b362fdf60a47162bbc202d new file mode 100644 index 0000000000000000000000000000000000000000..4cfec55d407a8c008592598802a97168b34f8766 GIT binary patch literal 442 zcmV;r0Y(0J0c}!EkDD+M?U`TUTiS!SHi3|E?0Hukse9?k^2dZ&F_`to2KwteKvcET zA`YJS#%~^PP|hoIXbxYZvl_%8duYiIKatV-R2Yal*fCi@v}DN66&gaa7YjzH`F}{u zrA-(}(z^KIKJ0Ii<`FfOpTw#;${_pL7KCWuV*$d+t|dFpcK={8UoLiPiRbLs3g;n( zS>R-6HbJfB9vK*tO=v~?twVbQ2zNoEUm1`S@!iRm%pk)`_&lO_JW>*%L(h10wzmmQ zl=Whwm*JMjhw-H_{=Rhekb>2#cS>UJh4^_E=hw4%dwqLGKKQ$MDAf!fgyI!3m6dXU znWT^xbI}eOBiZrOfl)?sc$yo^T8{VEovicTr12e)ciAi=H1Te*W28>(#A;E;iwtK0s zfH!(rn^!DnYg$rO>Zp&L(W)^utqz*gQ_~!2%`YIEV{?e|pen}&isofK3?RuwD$07m8BO}J>?;Q#;t literal 0 HcmV?d00001 diff --git a/backend/git_repos/remote/test-repo.git/refs/heads/dev b/backend/git_repos/remote/test-repo.git/refs/heads/dev new file mode 100644 index 00000000..b10885cd --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/refs/heads/dev @@ -0,0 +1 @@ +cfd2dcbd55735b8cedf21e04e64ac627c6f9a458 diff --git a/backend/git_repos/remote/test-repo.git/refs/heads/feature/e2e-update b/backend/git_repos/remote/test-repo.git/refs/heads/feature/e2e-update new file mode 100644 index 00000000..4cb55816 --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/refs/heads/feature/e2e-update @@ -0,0 +1 @@ +5a82ef700fef88b69cd480e4025283809496ee20 diff --git a/backend/git_repos/remote/test-repo.git/refs/heads/feature/test b/backend/git_repos/remote/test-repo.git/refs/heads/feature/test new file mode 100644 index 00000000..2564645e --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/refs/heads/feature/test @@ -0,0 +1 @@ +4e227f4d8289ea657ae813b1460f979ae4b676b3 diff --git a/backend/git_repos/remote/test-repo.git/refs/heads/main b/backend/git_repos/remote/test-repo.git/refs/heads/main new file mode 100644 index 00000000..df2fd546 --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/refs/heads/main @@ -0,0 +1 @@ +6af2b28e314c04fb4e03476c12d6491213591512 diff --git a/backend/git_repos/remote/test-repo.git/refs/heads/master b/backend/git_repos/remote/test-repo.git/refs/heads/master new file mode 100644 index 00000000..6e1395ae --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/refs/heads/master @@ -0,0 +1 @@ +5d9eb555c4cac2d3ffdba84c07682b154fe4180d diff --git a/backend/git_repos/remote/test-repo.git/refs/heads/preprod b/backend/git_repos/remote/test-repo.git/refs/heads/preprod new file mode 100644 index 00000000..a26df285 --- /dev/null +++ b/backend/git_repos/remote/test-repo.git/refs/heads/preprod @@ -0,0 +1 @@ +ee59553241ef084b83d3351ba4c33caf2ed9a840 diff --git a/backend/src/api/routes/git/_repo_operations_routes.py b/backend/src/api/routes/git/_repo_operations_routes.py index 9998d13e..66291628 100644 --- a/backend/src/api/routes/git/_repo_operations_routes.py +++ b/backend/src/api/routes/git/_repo_operations_routes.py @@ -293,14 +293,14 @@ async def generate_commit_message( history_objs = _gs.get_commit_history(dashboard_id, limit=5) history = [h.message for h in history_objs if hasattr(h, "message")] - from ...plugins.llm_analysis.models import LLMProviderType - from ...plugins.llm_analysis.service import LLMClient - from ...services.llm_prompt_templates import ( + from src.plugins.llm_analysis.models import LLMProviderType + from src.plugins.llm_analysis.service import LLMClient + from src.services.llm_prompt_templates import ( DEFAULT_LLM_PROMPTS, normalize_llm_settings, resolve_bound_provider_id, ) - from ...services.llm_provider import LLMProviderService + from src.services.llm_provider import LLMProviderService llm_service = LLMProviderService(db) providers = llm_service.get_all_providers() @@ -325,7 +325,7 @@ async def generate_commit_message( default_model=provider.default_model, ) - from ...plugins.git.llm_extension import GitLLMExtension + from src.plugins.git.llm_extension import GitLLMExtension extension = GitLLMExtension(client) git_prompt = llm_settings["prompts"].get( diff --git a/backend/src/api/routes/translate/__init__.py b/backend/src/api/routes/translate/__init__.py index bd34d4a0..925b379e 100644 --- a/backend/src/api/routes/translate/__init__.py +++ b/backend/src/api/routes/translate/__init__.py @@ -1,15 +1,18 @@ # #region TranslateRoutes [C:4] [TYPE Module] [SEMANTICS translate, api, package, schedule, dashboard, llm] # @BRIEF API routes for LLM-based SQL/dashboard translation management including terminology dictionary CRUD and import. -# @LAYER: UI (API) -# @RELATION DEPENDS_ON -> [TranslateJobResponse] -# @RELATION DEPENDS_ON -> [DictionaryManager:Class] -# @RELATION DEPENDS_ON -> [get_current_user] -# @RELATION DEPENDS_ON -> [get_db] -# @RELATION DEPENDS_ON -> [has_permission] -# @RELATION DEPENDS_ON -> [ConfigManager] +# @LAYER API # @RELATION DEPENDS_ON -> [SupersetClient] -# @RATIONALE: Snapshot isolation — in-progress runs use config snapshot; config edits affect future runs only. -# @REJECTED: Invalidating in-progress runs on config edit would break scheduled run continuity. +# @RELATION DEPENDS_ON -> [SupersetClient] +# @RELATION DEPENDS_ON -> [SupersetClient] +# @RELATION DEPENDS_ON -> [SupersetClient] +# @RELATION DEPENDS_ON -> [SupersetClient] +# @RELATION DEPENDS_ON -> [SupersetClient] +# @RELATION DEPENDS_ON -> [SupersetClient] +# @RATIONALE Snapshot isolation — in-progress runs use config snapshot; config edits affect future runs only. +# @REJECTED Invalidating in-progress runs on config edit would break scheduled run continuity. +# @POST Translation job, run, dictionary, correction, preview, and schedule CRUD operations are executed. +# @PRE API server is running, user is authenticated, database is accessible. +# @SIDE_EFFECT Creates/modifies DB rows; triggers background translation runs; queries Superset API. """ Translate routes package. diff --git a/backend/src/api/routes/translate/_correction_routes.py b/backend/src/api/routes/translate/_correction_routes.py index 7230a2c1..26da8028 100644 --- a/backend/src/api/routes/translate/_correction_routes.py +++ b/backend/src/api/routes/translate/_correction_routes.py @@ -20,10 +20,12 @@ from ._router import router # Corrections # ============================================================ -# #region submit_correction [TYPE Function] +# #region submit_correction [C:4] [TYPE Function] # @BRIEF Submit a term correction from a run result review. -# @PRE: User has translate.dictionary.edit permission. -# @POST: Correction applied with conflict detection. +# @PRE User has translate.dictionary.edit permission. +# @POST Correction applied with conflict detection. +# @SIDE_EFFECT Creates/updates DictionaryEntry row; commits. +# @RELATION DEPENDS_ON -> [DictionaryManager] @router.post("/corrections") async def submit_correction( payload: TermCorrectionSubmit, @@ -55,10 +57,14 @@ async def submit_correction( # #endregion submit_correction -# #region submit_bulk_corrections [TYPE Function] +# #region submit_bulk_corrections [C:4] [TYPE Function] # @BRIEF Submit multiple term corrections atomically. -# @PRE: User has translate.dictionary.edit permission. -# @POST: All corrections applied or none with conflict list. +# @PRE User has translate.dictionary.edit permission. +# @POST All corrections applied or none with conflict list. +# @SIDE_EFFECT Creates/updates DictionaryEntry rows; commits once. +# @RELATION DEPENDS_ON -> [DictionaryManager] +# @COMPLEXITY 4 + @router.post("/corrections/bulk") async def submit_bulk_corrections( payload: TermCorrectionBulkSubmit, diff --git a/backend/src/api/routes/translate/_dictionary_routes.py b/backend/src/api/routes/translate/_dictionary_routes.py index 743b841b..74e86e27 100644 --- a/backend/src/api/routes/translate/_dictionary_routes.py +++ b/backend/src/api/routes/translate/_dictionary_routes.py @@ -22,7 +22,7 @@ from ._router import router # Terminology Dictionaries # ============================================================ -# #region list_dictionaries [TYPE Function] +# #region list_dictionaries [C:4] [TYPE Function] # @BRIEF List all terminology dictionaries. # @PRE: User has translate.dictionary.view permission. # @POST: Returns list of dictionaries with total count. @@ -46,7 +46,7 @@ async def list_dictionaries( # #endregion list_dictionaries -# #region get_dictionary [TYPE Function] +# #region get_dictionary [C:4] [TYPE Function] # @BRIEF Get a single terminology dictionary by ID. # @PRE: User has translate.dictionary.view permission. # @POST: Returns the dictionary with entry_count. @@ -71,7 +71,7 @@ async def get_dictionary( # #endregion get_dictionary -# #region create_dictionary [TYPE Function] +# #region create_dictionary [C:4] [TYPE Function] # @BRIEF Create a new terminology dictionary. # @PRE: User has translate.dictionary.create permission. # @POST: Returns the created dictionary. @@ -99,7 +99,7 @@ async def create_dictionary( # #endregion create_dictionary -# #region update_dictionary [TYPE Function] +# #region update_dictionary [C:4] [TYPE Function] # @BRIEF Update an existing terminology dictionary. # @PRE: User has translate.dictionary.edit permission. # @POST: Returns the updated dictionary. @@ -133,7 +133,7 @@ async def update_dictionary( # #endregion update_dictionary -# #region delete_dictionary [TYPE Function] +# #region delete_dictionary [C:4] [TYPE Function] # @BRIEF Delete a terminology dictionary, blocked if attached to active/scheduled jobs. # @PRE: User has translate.dictionary.delete permission. # @POST: Dictionary is deleted. @@ -162,7 +162,7 @@ async def delete_dictionary( # Dictionary Entries CRUD # ============================================================ -# #region list_dictionary_entries [TYPE Function] +# #region list_dictionary_entries [C:4] [TYPE Function] # @BRIEF List entries for a dictionary, optionally filtered by language pair. # @PRE: User has translate.dictionary.view permission. # @POST: Returns paginated list of entries with language pair fields. @@ -220,7 +220,7 @@ async def list_dictionary_entries( # #endregion list_dictionary_entries -# #region add_dictionary_entry [TYPE Function] +# #region add_dictionary_entry [C:4] [TYPE Function] # @BRIEF Add a new entry to a dictionary. # @PRE: User has translate.dictionary.edit permission. # @POST: Entry is created. @@ -269,7 +269,7 @@ async def add_dictionary_entry( # #endregion add_dictionary_entry -# #region edit_dictionary_entry [TYPE Function] +# #region edit_dictionary_entry [C:4] [TYPE Function] # @BRIEF Update an existing dictionary entry. # @PRE: User has translate.dictionary.edit permission. # @POST: Entry is updated. @@ -319,7 +319,7 @@ async def edit_dictionary_entry( # #endregion edit_dictionary_entry -# #region delete_dictionary_entry [TYPE Function] +# #region delete_dictionary_entry [C:4] [TYPE Function] # @BRIEF Delete a dictionary entry. # @PRE: User has translate.dictionary.edit permission. # @POST: Entry is deleted. @@ -343,10 +343,12 @@ async def delete_dictionary_entry( # #endregion delete_dictionary_entry -# #region import_dictionary_entries [TYPE Function] +# #region import_dictionary_entries [C:4] [TYPE Function] # @BRIEF Import entries into a terminology dictionary from CSV/TSV content. -# @PRE: User has translate.dictionary.edit permission. -# @POST: Entries are imported per conflict mode. +# @PRE User has translate.dictionary.edit permission. +# @POST Entries are imported per conflict mode. +# @COMPLEXITY 4 + @router.post("/dictionaries/{dictionary_id}/import") async def import_dictionary_entries( dictionary_id: str, diff --git a/backend/src/api/routes/translate/_helpers.py b/backend/src/api/routes/translate/_helpers.py index b1fa8a24..f6b751ec 100644 --- a/backend/src/api/routes/translate/_helpers.py +++ b/backend/src/api/routes/translate/_helpers.py @@ -1,6 +1,6 @@ # #region TranslateHelpersModule [C:2] [TYPE Module] [SEMANTICS sqlalchemy, translate, helper, query, mapping] # @BRIEF Shared helper functions for translate route handlers. -# @LAYER: API +# @LAYER API # @RELATION DEPENDS_ON -> [models.translate] from typing import Any diff --git a/backend/src/api/routes/translate/_job_routes.py b/backend/src/api/routes/translate/_job_routes.py index aeda6fda..9226ed74 100644 --- a/backend/src/api/routes/translate/_job_routes.py +++ b/backend/src/api/routes/translate/_job_routes.py @@ -31,7 +31,7 @@ from ._router import router # Translation Job CRUD # ============================================================ -# #region list_jobs [TYPE Function] +# #region list_jobs [C:4] [TYPE Function] # @BRIEF List all translation jobs. # @PRE: User has translate.job.view permission. # @POST: Returns list of translation jobs. @@ -64,7 +64,7 @@ async def list_jobs( # #endregion list_jobs -# #region get_job [TYPE Function] +# #region get_job [C:4] [TYPE Function] # @BRIEF Get a single translation job by ID. # @PRE: User has translate.job.view permission. # @POST: Returns the translation job. @@ -88,7 +88,7 @@ async def get_job( # #endregion get_job -# #region create_job [TYPE Function] +# #region create_job [C:4] [TYPE Function] # @BRIEF Create a new translation job. # @PRE: User has translate.job.create permission. # @POST: Returns the created translation job. @@ -113,7 +113,7 @@ async def create_job( # #endregion create_job -# #region update_job [TYPE Function] +# #region update_job [C:4] [TYPE Function] # @BRIEF Update an existing translation job. # @PRE: User has translate.job.edit permission. # @POST: Returns the updated translation job. @@ -139,7 +139,7 @@ async def update_job( # #endregion update_job -# #region delete_job [TYPE Function] +# #region delete_job [C:4] [TYPE Function] # @BRIEF Delete a translation job. # @PRE: User has translate.job.delete permission. # @POST: Job is deleted. @@ -161,7 +161,7 @@ async def delete_job( # #endregion delete_job -# #region duplicate_job [TYPE Function] +# #region duplicate_job [C:4] [TYPE Function] # @BRIEF Duplicate a translation job. # @PRE: User has translate.job.create permission. # @POST: Returns the duplicated job with status DRAFT. @@ -188,13 +188,14 @@ async def duplicate_job( # #endregion duplicate_job -# #region get_datasource_columns [TYPE Function] +# #region get_datasource_columns [C:4] [TYPE Function] # @BRIEF Get column metadata and database dialect for a Superset datasource. -# @PRE: User has translate.job.view permission. -# @POST: Returns column list with metadata and database_dialect. -# @SIDE_EFFECT: Queries Superset API for dataset detail and database info. -# @RATIONALE: Dialect detection from Superset connection cached on TranslationJob at save time. -# @REJECTED: Hardcoding dialect list per database — would drift from actual Superset config. +# @PRE User has translate.job.view permission. +# @POST Returns column list with metadata and database_dialect. +# @SIDE_EFFECT Queries Superset API for dataset detail and database info. +# @RATIONALE Dialect detection from Superset connection cached on TranslationJob at save time. +# @REJECTED Hardcoding dialect list per database — would drift from actual Superset config. +# @COMPLEXITY 4 @router.get("/datasources") async def list_datasources( diff --git a/backend/src/api/routes/translate/_metrics_routes.py b/backend/src/api/routes/translate/_metrics_routes.py index 167997a2..e57bb3a5 100644 --- a/backend/src/api/routes/translate/_metrics_routes.py +++ b/backend/src/api/routes/translate/_metrics_routes.py @@ -17,7 +17,7 @@ from ._router import router # Metrics # ============================================================ -# #region get_metrics [TYPE Function] +# #region get_metrics [C:4] [TYPE Function] # @BRIEF Get translation metrics, optionally filtered by job. # @PRE: User has translate.metrics.view permission. # @POST: Returns metrics data. @@ -40,10 +40,12 @@ async def get_metrics( # #endregion get_metrics -# #region get_job_metrics [TYPE Function] +# #region get_job_metrics [C:4] [TYPE Function] # @BRIEF Get aggregated metrics for a specific job. -# @PRE: User has translate.metrics.view permission. -# @POST: Returns metrics dict. +# @PRE User has translate.metrics.view permission. +# @POST Returns metrics dict. +# @COMPLEXITY 4 + @router.get("/jobs/{job_id}/metrics") async def get_job_metrics( job_id: str, diff --git a/backend/src/api/routes/translate/_preview_routes.py b/backend/src/api/routes/translate/_preview_routes.py index cf054cfe..13a8052f 100644 --- a/backend/src/api/routes/translate/_preview_routes.py +++ b/backend/src/api/routes/translate/_preview_routes.py @@ -23,7 +23,7 @@ from ._router import router # Preview # ============================================================ -# #region preview_translation [TYPE Function] +# #region preview_translation [C:4] [TYPE Function] # @BRIEF Preview a translation before applying it. # @PRE: User has translate.job.execute permission. # @POST: Returns a preview session with records and cost estimation. @@ -59,7 +59,7 @@ async def preview_translation( # #endregion preview_translation -# #region update_preview_row [TYPE Function] +# #region update_preview_row [C:4] [TYPE Function] # @BRIEF Approve, edit, or reject a preview row (optionally per language). # @PRE: User has translate.job.execute permission. # @POST: Preview row status is updated. @@ -91,7 +91,7 @@ async def update_preview_row( # #endregion update_preview_row -# #region accept_preview_session [TYPE Function] +# #region accept_preview_session [C:4] [TYPE Function] # @BRIEF Accept a preview session, marking it as the quality gate for full execution. # @PRE: User has translate.job.execute permission. Job has an ACTIVE preview session. # @POST: Preview session is marked as APPLIED; full execution can proceed. @@ -114,7 +114,7 @@ async def accept_preview_session( # #endregion accept_preview_session -# #region apply_preview [TYPE Function] +# #region apply_preview [C:4] [TYPE Function] # @BRIEF Apply a preview session (alias for accept when accepting at session level). # @PRE: User has translate.job.execute permission. # @POST: Preview is applied. @@ -146,10 +146,12 @@ async def apply_preview( # Preview Records # ============================================================ -# #region get_preview_records [TYPE Function] +# #region get_preview_records [C:4] [TYPE Function] # @BRIEF Get records for a preview session. -# @PRE: User has translate.job.view permission. -# @POST: Returns list of preview records. +# @PRE User has translate.job.view permission. +# @POST Returns list of preview records. +# @COMPLEXITY 4 + @router.get("/preview/{session_id}/records", response_model=list[PreviewRow]) async def get_preview_records( session_id: str, diff --git a/backend/src/api/routes/translate/_router.py b/backend/src/api/routes/translate/_router.py index 3a99a808..e1110ba3 100644 --- a/backend/src/api/routes/translate/_router.py +++ b/backend/src/api/routes/translate/_router.py @@ -6,6 +6,7 @@ from fastapi import APIRouter # #region translate_router [TYPE Global] # @BRIEF APIRouter instance for all translate sub-routes. + router = APIRouter(prefix="/api/translate", tags=["translate"]) # #endregion translate_router diff --git a/backend/src/api/routes/translate/_run_list_routes.py b/backend/src/api/routes/translate/_run_list_routes.py index a656d74c..89594dcc 100644 --- a/backend/src/api/routes/translate/_run_list_routes.py +++ b/backend/src/api/routes/translate/_run_list_routes.py @@ -19,7 +19,7 @@ from ._router import router # List Runs (cross-job) # ============================================================ -# #region list_runs [TYPE Function] +# #region list_runs [C:4] [TYPE Function] # @BRIEF List all runs with cross-job filtering and pagination. # @PRE: User has translate.history.view permission. # @POST: Returns paginated list of runs. @@ -126,7 +126,7 @@ async def list_runs( # Run Detail # ============================================================ -# #region get_run_detail [TYPE Function] +# #region get_run_detail [C:4] [TYPE Function] # @BRIEF Get detailed run info with config_snapshot, records, events. # @PRE: User has translate.history.view permission. # @POST: Returns run detail with records and events. @@ -169,10 +169,12 @@ async def get_run_detail( # Download Skipped CSV # ============================================================ -# #region download_skipped_csv [TYPE Function] +# #region download_skipped_csv [C:4] [TYPE Function] # @BRIEF Download a CSV of skipped translation records from a run. -# @PRE: User has translate.job.view permission. -# @POST: Returns CSV file of skipped records. +# @PRE User has translate.job.view permission. +# @POST Returns CSV file of skipped records. +# @COMPLEXITY 4 + @router.get("/runs/{run_id}/skipped.csv") async def download_skipped_csv( run_id: str, diff --git a/backend/src/api/routes/translate/_run_routes.py b/backend/src/api/routes/translate/_run_routes.py index cc518729..6180bda3 100644 --- a/backend/src/api/routes/translate/_run_routes.py +++ b/backend/src/api/routes/translate/_run_routes.py @@ -25,7 +25,7 @@ from ._router import router # Translation Run / Execute # ============================================================ -# #region run_translation [TYPE Function] +# #region run_translation [C:4] [TYPE Function] # @BRIEF Execute a translation job (trigger a run). # @PRE: User has translate.job.execute permission. # @POST: Returns the created translation run. @@ -164,7 +164,7 @@ def run_translation( # #endregion run_translation -# #region retry_run [TYPE Function] +# #region retry_run [C:4] [TYPE Function] # @BRIEF Retry failed batches in a translation run. # @PRE: User has translate.job.execute permission. # @POST: Returns the updated translation run. @@ -190,7 +190,7 @@ def retry_run( # #endregion retry_run -# #region retry_insert [TYPE Function] +# #region retry_insert [C:4] [TYPE Function] # @BRIEF Retry the SQL insert phase for a completed run. # @PRE: User has translate.job.execute permission. # @POST: Returns the updated run. @@ -216,7 +216,7 @@ def retry_insert( # #endregion retry_insert -# #region cancel_run [TYPE Function] +# #region cancel_run [C:4] [TYPE Function] # @BRIEF Cancel a running translation. # @PRE: User has translate.job.execute permission. # @POST: Run is cancelled. @@ -239,7 +239,7 @@ def cancel_run( # #endregion cancel_run -# #region get_run_history [TYPE Function] +# #region get_run_history [C:4] [TYPE Function] # @BRIEF Get run history for a translation job. # @PRE: User has translate.history.view permission. # @POST: Returns list of runs. @@ -264,7 +264,7 @@ def get_run_history( # #endregion get_run_history -# #region get_run_status [TYPE Function] +# #region get_run_status [C:4] [TYPE Function] # @BRIEF Get status and statistics for a translation run. # @PRE: User has translate.history.view permission. # @POST: Returns run details with statistics. @@ -286,7 +286,7 @@ def get_run_status( # #endregion get_run_status -# #region get_run_records [TYPE Function] +# #region get_run_records [C:4] [TYPE Function] # @BRIEF Get paginated records for a translation run. # @PRE: User has translate.history.view permission. # @POST: Returns paginated records. @@ -315,7 +315,7 @@ def get_run_records( # Batches # ============================================================ -# #region get_batches [TYPE Function] +# #region get_batches [C:4] [TYPE Function] # @BRIEF Get batches for a translation run. # @PRE: User has translate.job.view permission. # @POST: Returns list of batches. @@ -360,7 +360,7 @@ def get_batches( # Manual Language Override # ============================================================ -# #region override_detected_language [TYPE Function] +# #region override_detected_language [C:4] [TYPE Function] # @BRIEF Manually override the detected source language for a specific translation language entry. # @PRE: User has translate.job.execute permission. Run, record, and language entry exist. # @POST: TranslationLanguage.source_language_detected is updated; language_overridden is set to True. @@ -439,7 +439,7 @@ def override_detected_language( # Inline Correction # ============================================================ -# #region inline_edit_translation [C:3] [TYPE Function] [SEMANTICS api,translate,correction] +# #region inline_edit_translation [C:4] [TYPE Function] [SEMANTICS api,translate,correction] # @BRIEF Apply an inline correction to a translated value on a completed run result. # @PRE: User has translate.job.execute permission. Run, record, and language entry exist. # @POST: TranslationLanguage.final_value and user_edit are updated. Optional dictionary submission. @@ -488,10 +488,12 @@ def inline_edit_translation( # Bulk Find-and-Replace # ============================================================ -# #region bulk_find_replace [C:3] [TYPE Function] [SEMANTICS api,translate,bulk,replace] +# #region bulk_find_replace [C:4] [TYPE Function] [SEMANTICS api,translate,bulk,replace] # @BRIEF Perform bulk find-and-replace on translated values within a run. -# @PRE: User has translate.job.execute permission. Run exists. -# @POST: If preview=false, matching translations are updated. Optional dictionary submission. +# @PRE User has translate.job.execute permission. Run exists. +# @POST If preview=false, matching translations are updated. Optional dictionary submission. +# @COMPLEXITY 4 + @router.post("/runs/{run_id}/bulk-replace") def bulk_find_replace( run_id: str, diff --git a/backend/src/api/routes/translate/_schedule_routes.py b/backend/src/api/routes/translate/_schedule_routes.py index b70a205b..211502f9 100644 --- a/backend/src/api/routes/translate/_schedule_routes.py +++ b/backend/src/api/routes/translate/_schedule_routes.py @@ -18,7 +18,7 @@ from ._router import router # Schedule # ============================================================ -# #region get_schedule [TYPE Function] +# #region get_schedule [C:4] [TYPE Function] # @BRIEF Get the schedule for a translation job. # @PRE: User has translate.schedule.view permission. # @POST: Returns the schedule configuration. @@ -53,7 +53,7 @@ async def get_schedule( # #endregion get_schedule -# #region set_schedule [TYPE Function] +# #region set_schedule [C:4] [TYPE Function] # @BRIEF Set or update the schedule for a translation job. # @PRE: User has translate.schedule.manage permission. # @POST: Schedule is created or updated. @@ -119,7 +119,7 @@ async def set_schedule( # #endregion set_schedule -# #region enable_schedule [TYPE Function] +# #region enable_schedule [C:4] [TYPE Function] # @BRIEF Enable a schedule for a translation job. # @PRE: User has translate.schedule.manage permission. # @POST: Schedule is enabled. @@ -151,7 +151,7 @@ async def enable_schedule( # #endregion enable_schedule -# #region disable_schedule [TYPE Function] +# #region disable_schedule [C:4] [TYPE Function] # @BRIEF Disable a schedule for a translation job. # @PRE: User has translate.schedule.manage permission. # @POST: Schedule is disabled. @@ -177,7 +177,7 @@ async def disable_schedule( # #endregion disable_schedule -# #region delete_schedule [TYPE Function] +# #region delete_schedule [C:4] [TYPE Function] # @BRIEF Delete the schedule for a translation job. # @PRE: User has translate.schedule.manage permission. # @POST: Schedule is removed. @@ -203,10 +203,12 @@ async def delete_schedule( # #endregion delete_schedule -# #region get_next_executions [TYPE Function] +# #region get_next_executions [C:4] [TYPE Function] # @BRIEF Preview next N executions for a job's schedule. -# @PRE: User has translate.schedule.view permission. -# @POST: Returns next execution times. +# @PRE User has translate.schedule.view permission. +# @POST Returns next execution times. +# @COMPLEXITY 4 + @router.get("/jobs/{job_id}/schedule/next-executions") async def get_next_executions( job_id: str, diff --git a/backend/src/models/translate.py b/backend/src/models/translate.py index 4ffcccf8..4593d6dd 100644 --- a/backend/src/models/translate.py +++ b/backend/src/models/translate.py @@ -1,7 +1,7 @@ # #region TranslateModels [C:3] [TYPE Module] [SEMANTICS sqlalchemy, translate, model, schema, dashboard, llm] # @BRIEF SQLAlchemy ORM models for LLM-based SQL/dashboard translation across dialects. # @LAYER: Domain -# @RELATION INHERITS_FROM -> MappingModels:Base +# @RELATION INHERITS -> [MappingModels] import uuid from datetime import UTC, datetime diff --git a/backend/src/plugins/git_plugin.py b/backend/src/plugins/git_plugin.py index bf203d07..749ce062 100644 --- a/backend/src/plugins/git_plugin.py +++ b/backend/src/plugins/git_plugin.py @@ -1,4 +1,4 @@ -# #region GitPluginModule [TYPE Module] [SEMANTICS git, versioning, deploy, sync, superset] +# #region GitPluginModule [C:4] [TYPE Module] [SEMANTICS git, versioning, deploy, sync, superset, backup, transactional] # # @BRIEF Предоставляет плагин для версионирования и развертывания дашбордов Superset. # @LAYER: Plugin @@ -10,10 +10,13 @@ # # @INVARIANT: Все операции с Git должны выполняться через GitService. # @CONSTRAINT: Плагин работает только с распакованными YAML-экспортами Superset. +# @INVARIANT: _handle_sync сохраняет backup управляемых директорий перед удалением; +# при ошибке распаковки backup восстанавливается. import io import os import shutil +import time import zipfile from pathlib import Path from typing import Any @@ -62,52 +65,33 @@ class GitPlugin(PluginBase): # endregion __init__ @property - # region id [TYPE Function] - # @PURPOSE: Returns the plugin identifier. - # @PRE: GitPlugin is initialized. - # @POST: Returns 'git-integration'. + # region id [C:1] [TYPE Function] def id(self) -> str: - with belief_scope("GitPlugin.id"): - return "git-integration" + return "git-integration" # endregion id @property - # region name [TYPE Function] - # @PURPOSE: Returns the plugin name. - # @PRE: GitPlugin is initialized. - # @POST: Returns the human-readable name. + # region name [C:1] [TYPE Function] def name(self) -> str: - with belief_scope("GitPlugin.name"): - return "Git Integration" + return "Git Integration" # endregion name @property - # region description [TYPE Function] - # @PURPOSE: Returns the plugin description. - # @PRE: GitPlugin is initialized. - # @POST: Returns the plugin's purpose description. + # region description [C:1] [TYPE Function] def description(self) -> str: - with belief_scope("GitPlugin.description"): - return "Version control for Superset dashboards" + return "Version control for Superset dashboards" # endregion description @property - # region version [TYPE Function] - # @PURPOSE: Returns the plugin version. - # @PRE: GitPlugin is initialized. - # @POST: Returns the version string. + # region version [C:1] [TYPE Function] def version(self) -> str: - with belief_scope("GitPlugin.version"): - return "0.1.0" + return "0.1.0" # endregion version @property - # region ui_route [TYPE Function] - # @PURPOSE: Returns the frontend route for the git plugin. - # @RETURN: str - "/git" + # region ui_route [C:1] [TYPE Function] def ui_route(self) -> str: - with belief_scope("GitPlugin.ui_route"): - return "/git" + return "/git" # endregion ui_route # region get_schema [TYPE Function] @@ -129,21 +113,13 @@ class GitPlugin(PluginBase): } # endregion get_schema - # region initialize [TYPE Function] - # @PURPOSE: Выполняет начальную настройку плагина. - # @PRE: GitPlugin is initialized. - # @POST: Плагин готов к выполнению задач. + # region initialize [C:1] [TYPE Function] async def initialize(self): - with belief_scope("GitPlugin.initialize"): - app_logger.reason("Initializing Git Integration Plugin logic.", extra={"src": "GitPlugin.initialize"}) + app_logger.reason("Initializing Git Integration Plugin logic.", extra={"src": "GitPlugin.initialize"}) + # endregion initialize - # region execute [TYPE Function] - # @PURPOSE: Основной метод выполнения задач плагина с поддержкой TaskContext. - # @PRE: task_data содержит 'operation' и 'dashboard_id'. - # @POST: Возвращает результат выполнения операции. - # @PARAM: task_data (Dict[str, Any]) - Данные задачи. - # @PARAM: context (Optional[TaskContext]) - Task context for logging with source attribution. - # @RETURN: Dict[str, Any] - Статус и сообщение. + # region execute [C:3] [TYPE Function] + # @PURPOSE: Main task executor with TaskContext support. # @RELATION: CALLS -> self._handle_sync # @RELATION: CALLS -> self._handle_deploy async def execute(self, task_data: dict[str, Any], context: TaskContext | None = None) -> dict[str, Any]: @@ -176,41 +152,48 @@ class GitPlugin(PluginBase): return result # endregion execute - # region _handle_sync [TYPE Function] - # @PURPOSE: Экспортирует дашборд из Superset и распаковывает в Git-репозиторий. + # region _handle_sync [C:4] [TYPE Function] [SEMANTICS git,sync,backup,transactional] + # @PURPOSE: Экспортирует дашборд из Superset и распаковывает в Git-репозиторий с backup/restore. # @PRE: Репозиторий для дашборда должен существовать. # @POST: Файлы в репозитории обновлены до текущего состояния в Superset. - # @PARAM: dashboard_id (int) - ID дашборда. - # @PARAM: source_env_id (Optional[str]) - ID исходного окружения. - # @RETURN: Dict[str, str] - Результат синхронизации. + # Управляемые директории backup-ируются перед удалением; при ошибке распаковки backup восстанавливается. # @SIDE_EFFECT: Изменяет файлы в локальной рабочей директории репозитория. + # Создаёт временный backup в /tmp/ss-tools-backup-{dashboard_id}-{timestamp}/. + # @RETURN: Dict[str, str] - Результат синхронизации. # @RELATION: CALLS -> src.services.git_service.GitService.get_repo # @RELATION: CALLS -> src.core.superset_client.SupersetClient.export_dashboard async def _handle_sync(self, dashboard_id: int, source_env_id: str | None = None, log=None, git_log=None, superset_log=None) -> dict[str, str]: with belief_scope("GitPlugin._handle_sync"): try: - # 1. Получение репозитория repo = self.git_service.get_repo(dashboard_id) repo_path = Path(repo.working_dir) git_log.info(f"Target repo path: {repo_path}") - # 2. Настройка клиента Superset env = self._get_env(source_env_id) client = SupersetClient(env) client.authenticate() - # 3. Экспорт дашборда superset_log.info(f"Exporting dashboard {dashboard_id} from {env.name}") zip_bytes, _ = client.export_dashboard(dashboard_id) - # 4. Распаковка с выравниванием структуры (flattening) git_log.info(f"Unpacking export to {repo_path}") - # Список папок/файлов, которые мы ожидаем от Superset managed_dirs = ["dashboards", "charts", "datasets", "databases"] managed_files = ["metadata.yaml"] - # Очистка старых данных перед распаковкой, чтобы не оставалось "призраков" + # Fix 1: Create backup before deleting managed files + backup_dir = Path(f"/tmp/ss-tools-backup-{dashboard_id}-{time.time_ns()}") + for d in managed_dirs: + d_path = repo_path / d + if d_path.exists() and d_path.is_dir(): + shutil.copytree(d_path, backup_dir / d) + for f in managed_files: + f_path = repo_path / f + if f_path.exists(): + (backup_dir / f).parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(f_path, backup_dir / f) + + # Delete old managed files for d in managed_dirs: d_path = repo_path / d if d_path.exists() and d_path.is_dir(): @@ -220,30 +203,45 @@ class GitPlugin(PluginBase): if f_path.exists(): f_path.unlink() - with zipfile.ZipFile(io.BytesIO(zip_bytes)) as zf: - # Superset экспортирует всё в подпапку dashboard_export_timestamp/ - # Нам нужно найти это имя папки - namelist = zf.namelist() - if not namelist: - raise ValueError("Export ZIP is empty") + try: + with zipfile.ZipFile(io.BytesIO(zip_bytes)) as zf: + namelist = zf.namelist() + if not namelist: + raise ValueError("Export ZIP is empty") + root_folder = namelist[0].split('/')[0] + git_log.info(f"Detected root folder in ZIP: {root_folder}") + for member in zf.infolist(): + if member.filename.startswith(root_folder + "/") and len(member.filename) > len(root_folder) + 1: + relative_path = member.filename[len(root_folder)+1:] + target_path = repo_path / relative_path + if member.is_dir(): + target_path.mkdir(parents=True, exist_ok=True) + else: + target_path.parent.mkdir(parents=True, exist_ok=True) + with zf.open(member) as source, open(target_path, "wb") as target: + shutil.copyfileobj(source, target) + except Exception: + # Fix 1: Restore backup on unzip failure + if backup_dir.exists(): + for d in managed_dirs: + src = backup_dir / d + if src.exists(): + dst = repo_path / d + if dst.exists(): + shutil.rmtree(dst) + shutil.copytree(src, dst) + for f in managed_files: + src = backup_dir / f + if src.exists(): + dst = repo_path / f + dst.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(src, dst) + raise - root_folder = namelist[0].split('/')[0] - git_log.info(f"Detected root folder in ZIP: {root_folder}") + # Fix 1: Remove backup on success + if backup_dir.exists(): + shutil.rmtree(backup_dir, ignore_errors=True) - for member in zf.infolist(): - if member.filename.startswith(root_folder + "/") and len(member.filename) > len(root_folder) + 1: - # Убираем префикс папки - relative_path = member.filename[len(root_folder)+1:] - target_path = repo_path / relative_path - - if member.is_dir(): - target_path.mkdir(parents=True, exist_ok=True) - else: - target_path.parent.mkdir(parents=True, exist_ok=True) - with zf.open(member) as source, open(target_path, "wb") as target: - shutil.copyfileobj(source, target) - - # 5. Автоматический staging изменений (не коммит, чтобы юзер мог проверить diff) try: repo.git.add(A=True) app_logger.reason("Changes staged in git", extra={"src": "_handle_sync"}) @@ -258,35 +256,21 @@ class GitPlugin(PluginBase): raise # endregion _handle_sync - # region _handle_deploy [TYPE Function] - # @PURPOSE: Упаковывает репозиторий в ZIP и импортирует в целевое окружение Superset. - # @PRE: environment_id должен соответствовать настроенному окружению. - # @POST: Дашборд импортирован в целевой Superset. - # @PARAM: dashboard_id (int) - ID дашборда. - # @PARAM: env_id (str) - ID целевого окружения. - # @PARAM: log - Main logger instance. - # @PARAM: git_log - Git-specific logger instance. - # @PARAM: superset_log - Superset API-specific logger instance. - # @RETURN: Dict[str, Any] - Результат деплоя. - # @SIDE_EFFECT: Создает и удаляет временный ZIP-файл. + # region _handle_deploy [C:4] [TYPE Function] [SEMANTICS git,deploy,zip] + # @PURPOSE: Packages repository into ZIP and imports into target Superset environment. + # @POST: Dashboard imported into target Superset. + # @SIDE_EFFECT: Creates and removes temporary ZIP file. # @RELATION: CALLS -> src.core.superset_client.SupersetClient.import_dashboard async def _handle_deploy(self, dashboard_id: int, env_id: str, log=None, git_log=None, superset_log=None) -> dict[str, Any]: with belief_scope("GitPlugin._handle_deploy"): try: if not env_id: raise ValueError("Target environment ID required for deployment") - - # 1. Получение репозитория repo = self.git_service.get_repo(dashboard_id) repo_path = Path(repo.working_dir) - - # 2. Упаковка в ZIP git_log.info(f"Packing repository {repo_path} for deployment.") zip_buffer = io.BytesIO() - - # Superset expects a root directory in the ZIP (e.g., dashboard_export_20240101T000000/) root_dir_name = f"dashboard_export_{dashboard_id}" - with zipfile.ZipFile(zip_buffer, "w", zipfile.ZIP_DEFLATED) as zf: for root, dirs, files in os.walk(repo_path): if ".git" in dirs: @@ -295,21 +279,14 @@ class GitPlugin(PluginBase): if file == ".git" or file.endswith(".zip"): continue file_path = Path(root) / file - # Prepend the root directory name to the archive path arcname = Path(root_dir_name) / file_path.relative_to(repo_path) zf.write(file_path, arcname) - zip_buffer.seek(0) - - # 3. Настройка клиента Superset env = self.config_manager.get_environment(env_id) if not env: raise ValueError(f"Environment {env_id} not found") - client = SupersetClient(env) client.authenticate() - - # 4. Импорт temp_zip_path = repo_path / f"deploy_{dashboard_id}.zip" git_log.info(f"Saving temporary zip to {temp_zip_path}") with open(temp_zip_path, "wb") as f: @@ -329,11 +306,12 @@ class GitPlugin(PluginBase): raise # endregion _handle_deploy - # region _get_env [TYPE Function] + # region _get_env [C:4] [TYPE Function] [SEMANTICS env,config,strict] # @PURPOSE: Вспомогательный метод для получения конфигурации окружения. # @PARAM: env_id (Optional[str]) - ID окружения. # @PRE: env_id is a string or None. # @POST: Returns an Environment object from config or DB. + # When env_id is explicitly provided and not found, raises ValueError (no fallback). # @RETURN: Environment - Объект конфигурации окружения. def _get_env(self, env_id: str | None = None): with belief_scope("GitPlugin._get_env"): @@ -346,54 +324,46 @@ class GitPlugin(PluginBase): app_logger.reflect(f"Found environment by ID in ConfigManager: {env.name}", extra={"src": "_get_env"}) return env - # Priority 2: Database (DeploymentEnvironment) - from src.core.database import SessionLocal - from src.models.git import DeploymentEnvironment + # Priority 2: Database (DeploymentEnvironment) + from src.core.database import SessionLocal + from src.models.git import DeploymentEnvironment - db = SessionLocal() - try: - if env_id: - db_env = db.query(DeploymentEnvironment).filter(DeploymentEnvironment.id == env_id).first() - else: - # If no ID, try to find active or any environment in DB - db_env = db.query(DeploymentEnvironment).filter(DeploymentEnvironment.is_active).first() - if not db_env: - db_env = db.query(DeploymentEnvironment).first() + db = SessionLocal() + try: + if env_id: + db_env = db.query(DeploymentEnvironment).filter(DeploymentEnvironment.id == env_id).first() + else: + db_env = db.query(DeploymentEnvironment).filter(DeploymentEnvironment.is_active).first() + if not db_env: + db_env = db.query(DeploymentEnvironment).first() - if db_env: - app_logger.reflect(f"Found environment in DB: {db_env.name}", extra={"src": "_get_env"}) - from src.core.config_models import Environment - # Use token as password for SupersetClient - return Environment( - id=db_env.id, - name=db_env.name, - url=db_env.superset_url, - username="admin", - password=db_env.superset_token, - verify_ssl=True - ) - finally: - db.close() + if db_env: + app_logger.reflect(f"Found environment in DB: {db_env.name}", extra={"src": "_get_env"}) + from src.core.config_models import Environment + return Environment( + id=db_env.id, + name=db_env.name, + url=db_env.superset_url, + username="admin", + password=db_env.superset_token, + verify_ssl=True + ) - # Priority 3: ConfigManager Default (if no env_id provided) - envs = self.config_manager.get_environments() - if envs: - if env_id: - # If env_id was provided but not found in DB or specifically by ID in config, - # but we have other envs, maybe it's one of them? - env = next((e for e in envs if e.id == env_id), None) - if env: - app_logger.reflect(f"Found environment {env_id} in ConfigManager list", extra={"src": "_get_env"}) - return env + # Fix 7: Strict check — if env_id was explicitly provided but not found, raise immediately + if env_id: + raise ValueError(f"Environment '{env_id}' not found in ConfigManager or database") + finally: + db.close() - if not env_id: - app_logger.reflect(f"Using first environment from ConfigManager: {envs[0].name}", extra={"src": "_get_env"}) - return envs[0] + # Priority 3: fallback to first env only when no specific env_id was requested + envs = self.config_manager.get_environments() + if envs and not env_id: + app_logger.reflect(f"Using first environment from ConfigManager: {envs[0].name}", extra={"src": "_get_env"}) + return envs[0] - app_logger.error(f"[_get_env][Coherence:Failed] No environments configured (searched config.json and DB). env_id={env_id}") - raise ValueError("No environments configured. Please add a Superset Environment in Settings.") + app_logger.error(f"[_get_env][Coherence:Failed] No environments configured (searched config.json and DB). env_id={env_id}") + raise ValueError("No environments configured. Please add a Superset Environment in Settings.") # endregion _get_env - # endregion initialize # #endregion GitPlugin # #endregion GitPluginModule diff --git a/backend/src/plugins/translate/__init__.py b/backend/src/plugins/translate/__init__.py index 0f11335e..fd8f88d4 100644 --- a/backend/src/plugins/translate/__init__.py +++ b/backend/src/plugins/translate/__init__.py @@ -1,3 +1,2 @@ # #region TranslatePluginPackage [TYPE Package] [SEMANTICS translate, plugin, package, sql, dashboard] -# @BRIEF Translation plugin package for LLM-based cross-Superset SQL/dashboard translation. # #endregion TranslatePluginPackage diff --git a/backend/src/plugins/translate/_token_budget.py b/backend/src/plugins/translate/_token_budget.py index d9f1131b..bce098cf 100644 --- a/backend/src/plugins/translate/_token_budget.py +++ b/backend/src/plugins/translate/_token_budget.py @@ -9,24 +9,24 @@ # Fixed batch_size of 50 — causes truncation on long-content rows. # #region DEFAULT_CONTEXT_WINDOW [TYPE Constant] -# @BRIEF Default context window for DeepSeek v4 Flash: up to 64K tokens. + DEFAULT_CONTEXT_WINDOW = 64000 # #endregion DEFAULT_CONTEXT_WINDOW - # #region DEFAULT_MAX_OUTPUT_TOKENS [TYPE Constant] -# @BRIEF Default max_tokens setting for LLM output (16384 — sufficient for 50 rows x 4 languages). +# #region DEFAULT_MAX_OUTPUT_TOKENS [TYPE Constant] + DEFAULT_MAX_OUTPUT_TOKENS = 16384 # #endregion DEFAULT_MAX_OUTPUT_TOKENS - -# #region REASONING_OVERHEAD [TYPE Constant] # @BRIEF CoT reasoning overhead tokens for DeepSeek models (~2000 tokens for chain-of-thought). +# #region REASONING_OVERHEAD [TYPE Constant] + REASONING_OVERHEAD = 2000 # #endregion REASONING_OVERHEAD # #region PROVIDER_DEFAULTS [TYPE Constant] -# @BRIEF Provider-aware defaults for context_window and max_output_tokens. + # Maps model name (or "default" fallback) to capacity limits. -# @RATIONALE: Different providers have drastically different context windows and +# @RATIONALE Different providers have drastically different context windows and # output limits. Using a single default for all causes either wasted # capacity (underestimation) or truncation (overestimation). PROVIDER_DEFAULTS: dict[str, dict[str, int]] = { @@ -38,46 +38,46 @@ PROVIDER_DEFAULTS: dict[str, dict[str, int]] = { "default": {"context_window": 64000, "max_output_tokens": 16384}, } # #endregion PROVIDER_DEFAULTS - +# Increased from 60 to 120 because SQL/dashboard text and JSON structure need more. # #region OUTPUT_PER_ROW_PER_LANG [TYPE Constant] -# @BRIEF Estimated output tokens per row per language in JSON response format. + # Increased from 60 to 120 because SQL/dashboard text and JSON structure need more. OUTPUT_PER_ROW_PER_LANG = 120 # #endregion OUTPUT_PER_ROW_PER_LANG - +# #endregion JSON_OVERHEAD_PER_ROW # #region JSON_OVERHEAD_PER_ROW [TYPE Constant] -# @BRIEF Estimated overhead tokens for JSON keys, brackets, and formatting per row. + JSON_OVERHEAD_PER_ROW = 50 # #endregion JSON_OVERHEAD_PER_ROW - +# #endregion PROMPT_BASE_TOKENS # #region PROMPT_BASE_TOKENS [TYPE Constant] -# @BRIEF Base tokens for system prompt + instructions + dictionary section + JSON format specification. + # Increased from 300 to 600 to account for longer template, system msg, and dict preamble. PROMPT_BASE_TOKENS = 600 # #endregion PROMPT_BASE_TOKENS - +# @BRIEF Cap for dictionary tokens in estimation to avoid overestimating. # #region DICT_TOKENS_PER_ENTRY [TYPE Constant] -# @BRIEF Estimated tokens per dictionary entry in the glossary section. + DICT_TOKENS_PER_ENTRY = 20 # #endregion DICT_TOKENS_PER_ENTRY # #region DICT_TOKENS_MAX [TYPE Constant] -# @BRIEF Cap for dictionary tokens in estimation to avoid overestimating. + DICT_TOKENS_MAX = 5000 # #endregion DICT_TOKENS_MAX - +MIN_MAX_TOKENS = 4096 # #region CHARS_PER_TOKEN_MIXED [TYPE Constant] -# @BRIEF Characters per token for mixed Russian/English text (empirical ~2.2 for mixed, ~2 for Russian, ~4 for English). + CHARS_PER_TOKEN_MIXED = 2.2 # #endregion CHARS_PER_TOKEN_MIXED - +MAX_OUTPUT_HEADROOM = 3000 # #region MIN_MAX_TOKENS [TYPE Constant] -# @BRIEF Minimum max_tokens to allow (4096 ensures reasonable output even for small batches). + MIN_MAX_TOKENS = 4096 # #endregion MIN_MAX_TOKENS - +# #endregion MIN_MAX_TOKENS # #region MAX_OUTPUT_HEADROOM [TYPE Constant] -# @BRIEF Extra headroom added to max_output_needed beyond the estimate (3000 = 10-20% for variance). + # Increased from 1000 to 3000 because SQL/dashboard text output varies significantly. MAX_OUTPUT_HEADROOM = 3000 # #endregion MAX_OUTPUT_HEADROOM diff --git a/backend/src/plugins/translate/dictionary.py b/backend/src/plugins/translate/dictionary.py index db6dbbc5..98fb6663 100644 --- a/backend/src/plugins/translate/dictionary.py +++ b/backend/src/plugins/translate/dictionary.py @@ -1,13 +1,16 @@ # #region DictionaryManagerModule [C:4] [TYPE Module] [SEMANTICS sqlalchemy, translate, dictionary, batch, term] # @BRIEF Business logic for terminology dictionary management, entry CRUD, CSV/TSV import with conflict detection, and per-batch filtering. -# @LAYER: Domain -# @RELATION DEPENDS_ON -> [TerminologyDictionary:Class] -# @RELATION DEPENDS_ON -> [DictionaryEntry:Class] -# @RELATION DEPENDS_ON -> [TranslationJobDictionary:Class] +# @LAYER Domain # @RELATION DEPENDS_ON -> [TranslationJob:Class] -# @RATIONALE: C4 complexity because dictionary CRUD is stateful with referential integrity enforcement on deletion and unique constraint on normalized source term. -# @REJECTED: Pure C3 CRUD without state guards would allow orphaned job-dictionary links. -# @REJECTED: "Keep both" as conflict option — UniqueConstraint(dictionary_id, source_term_normalized) prohibits variants; only overwrite/keep existing. +# @RELATION DEPENDS_ON -> [TranslationJob:Class] +# @RELATION DEPENDS_ON -> [TranslationJob:Class] +# @RELATION DEPENDS_ON -> [TranslationJob:Class] +# @RATIONALE C4 complexity because dictionary CRUD is stateful with referential integrity enforcement on deletion and unique constraint on normalized source term. +# @REJECTED "Keep both" as conflict option — UniqueConstraint(dictionary_id, source_term_normalized) prohibits variants; only overwrite/keep existing. +# @REJECTED "Keep both" as conflict option — UniqueConstraint(dictionary_id, source_term_normalized) prohibits variants; only overwrite/keep existing. +# @POST Dictionary and entry mutations are persisted with conflict detection. +# @PRE Database session is open and valid. Dictionary manager is properly initialized. +# @SIDE_EFFECT Creates, updates, deletes TerminologyDictionary and DictionaryEntry rows; enforces deletion guards. import csv import io @@ -42,19 +45,18 @@ def _validate_bcp47(tag: str, field_name: str) -> None: f"{field_name} is not a valid BCP-47 tag: '{tag}'. " "Expected format like 'en', 'ru', 'zh-CN', 'pt-BR'." ) -# #endregion _validate_bcp47 - - # #region DictionaryManager [C:4] [TYPE Class] # @BRIEF Manages terminology dictionaries and their entries with referential integrity. -# @PRE: Database session is open and valid. -# @POST: Dictionary and entry mutations are persisted with conflict detection. -# @SIDE_EFFECT: Creates, updates, deletes TerminologyDictionary and DictionaryEntry rows; enforces deletion guards. +# @PRE Database session is open and valid. +# @POST Dictionary and entry mutations are persisted with conflict detection. +# @SIDE_EFFECT Creates, updates, deletes TerminologyDictionary and DictionaryEntry rows; enforces deletion guards. +# @RELATION DEPENDS_ON -> [TerminologyDictionary:Class], DEPENDS_ON -> [DictionaryEntry:Class], DEPENDS_ON -> [TranslationJobDictionary:Class], DEPENDS_ON -> [TranslationJob:Class] + class DictionaryManager: # region DictionaryManager.create_dictionary [TYPE Function] - # @PURPOSE: Create a new terminology dictionary (language independent at dictionary level; language pairs are per-entry). - # @PRE: name is provided. - # @POST: New TerminologyDictionary row is created and returned. + # @PURPOSE Create a new terminology dictionary (language independent at dictionary level; language pairs are per-entry). + # @PRE name is provided. + # @POST New TerminologyDictionary row is created and returned. @staticmethod def create_dictionary( db: Session, name: str, @@ -81,9 +83,9 @@ class DictionaryManager: # endregion DictionaryManager.create_dictionary # region DictionaryManager.update_dictionary [TYPE Function] - # @PURPOSE: Update an existing terminology dictionary. - # @PRE: dict_id exists in terminology_dictionaries table. - # @POST: Dictionary metadata is updated and returned. + # @PURPOSE Update an existing terminology dictionary. + # @PRE dict_id exists in terminology_dictionaries table. + # @POST Dictionary metadata is updated and returned. @staticmethod def update_dictionary( db: Session, dict_id: str, name: str | None = None, @@ -112,10 +114,10 @@ class DictionaryManager: # endregion DictionaryManager.update_dictionary # region DictionaryManager.delete_dictionary [TYPE Function] - # @PURPOSE: Delete a dictionary, blocked if attached to active/scheduled jobs. - # @PRE: dict_id exists. - # @POST: Dictionary and its entries are deleted, unless attached to ACTIVE/READY/RUNNING/SCHEDULED jobs. - # @SIDE_EFFECT: Deletes TerminologyDictionary row and all DictionaryEntry rows. + # @PURPOSE Delete a dictionary, blocked if attached to active/scheduled jobs. + # @PRE dict_id exists. + # @POST Dictionary and its entries are deleted, unless attached to ACTIVE/READY/RUNNING/SCHEDULED jobs. + # @SIDE_EFFECT Deletes TerminologyDictionary row and all DictionaryEntry rows. @staticmethod def delete_dictionary(db: Session, dict_id: str) -> None: with belief_scope("DictionaryManager.delete_dictionary"): @@ -155,9 +157,9 @@ class DictionaryManager: # endregion DictionaryManager.delete_dictionary # region DictionaryManager.get_dictionary [TYPE Function] - # @PURPOSE: Get a single dictionary by ID with entry count. - # @PRE: dict_id exists. - # @POST: Returns dict with dictionary + entry_count or raises ValueError. + # @PURPOSE Get a single dictionary by ID with entry count. + # @PRE dict_id exists. + # @POST Returns dict with dictionary + entry_count or raises ValueError. @staticmethod def get_dictionary(db: Session, dict_id: str) -> TerminologyDictionary: dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first() @@ -167,9 +169,9 @@ class DictionaryManager: # endregion DictionaryManager.get_dictionary # region DictionaryManager.list_dictionaries [TYPE Function] - # @PURPOSE: List dictionaries with pagination and entry counts. - # @PRE: page >= 1, page_size between 1 and 100. - # @POST: Returns (list of dicts, total_count). + # @PURPOSE List dictionaries with pagination and entry counts. + # @PRE page >= 1, page_size between 1 and 100. + # @POST Returns (list of dicts, total_count). @staticmethod def list_dictionaries( db: Session, page: int = 1, page_size: int = 20, @@ -186,9 +188,9 @@ class DictionaryManager: # endregion DictionaryManager.list_dictionaries # region DictionaryManager.add_entry [TYPE Function] - # @PURPOSE: Add an entry to a dictionary with language-pair-aware uniqueness validation. - # @PRE: dict_id exists. source_term, target_term are non-empty. source_language, target_language are valid BCP-47. - # @POST: New DictionaryEntry row is created or raises on duplicate. + # @PURPOSE Add an entry to a dictionary with language-pair-aware uniqueness validation. + # @PRE dict_id exists. source_term, target_term are non-empty. source_language, target_language are valid BCP-47. + # @POST New DictionaryEntry row is created or raises on duplicate. @staticmethod def add_entry( db: Session, dict_id: str, source_term: str, target_term: str, @@ -237,9 +239,9 @@ class DictionaryManager: # endregion DictionaryManager.add_entry # region DictionaryManager.edit_entry [TYPE Function] - # @PURPOSE: Edit an existing dictionary entry with language-pair-aware duplicate check. - # @PRE: entry_id exists. - # @POST: Entry fields are updated. + # @PURPOSE Edit an existing dictionary entry with language-pair-aware duplicate check. + # @PRE entry_id exists. + # @POST Entry fields are updated. @staticmethod def edit_entry( db: Session, entry_id: str, source_term: str | None = None, @@ -293,9 +295,9 @@ class DictionaryManager: # endregion DictionaryManager.edit_entry # region DictionaryManager.delete_entry [TYPE Function] - # @PURPOSE: Delete a single dictionary entry. - # @PRE: entry_id exists. - # @POST: Entry is deleted. + # @PURPOSE Delete a single dictionary entry. + # @PRE entry_id exists. + # @POST Entry is deleted. @staticmethod def delete_entry(db: Session, entry_id: str) -> None: with belief_scope("DictionaryManager.delete_entry"): @@ -309,9 +311,9 @@ class DictionaryManager: # endregion DictionaryManager.delete_entry # region DictionaryManager.clear_entries [TYPE Function] - # @PURPOSE: Delete all entries for a dictionary. - # @PRE: dict_id exists. - # @POST: All entries for the dictionary are deleted. + # @PURPOSE Delete all entries for a dictionary. + # @PRE dict_id exists. + # @POST All entries for the dictionary are deleted. @staticmethod def clear_entries(db: Session, dict_id: str) -> int: with belief_scope("DictionaryManager.clear_entries"): @@ -326,9 +328,9 @@ class DictionaryManager: # endregion DictionaryManager.clear_entries # region DictionaryManager.list_entries [TYPE Function] - # @PURPOSE: List entries for a dictionary with pagination. - # @PRE: dict_id exists. - # @POST: Returns (list of entries, total_count). + # @PURPOSE List entries for a dictionary with pagination. + # @PRE dict_id exists. + # @POST Returns (list of entries, total_count). @staticmethod def list_entries( db: Session, dict_id: str, page: int = 1, page_size: int = 50, @@ -351,10 +353,10 @@ class DictionaryManager: # endregion DictionaryManager.list_entries # region DictionaryManager.import_entries [TYPE Function] - # @PURPOSE: Import entries from CSV/TSV content with duplicate detection and conflict resolution. - # @PRE: content is valid CSV or TSV. dict_id exists. - # @POST: Entries are created/updated/skipped per conflict mode. Returns result summary. - # @SIDE_EFFECT: Batch-inserts or updates DictionaryEntry rows. + # @PURPOSE Import entries from CSV/TSV content with duplicate detection and conflict resolution. + # @PRE content is valid CSV or TSV. dict_id exists. + # @POST Entries are created/updated/skipped per conflict mode. Returns result summary. + # @SIDE_EFFECT Batch-inserts or updates DictionaryEntry rows. @staticmethod def import_entries( db: Session, dict_id: str, content: str, @@ -504,9 +506,9 @@ class DictionaryManager: # endregion DictionaryManager.import_entries # region DictionaryManager.export_entries [TYPE Function] - # @PURPOSE: Export all entries as CSV string with language columns. - # @PRE: dict_id exists. - # @POST: Returns CSV string with header: source_term, target_term, source_language, target_language, context_notes, context_data, usage_notes. + # @PURPOSE Export all entries as CSV string with language columns. + # @PRE dict_id exists. + # @POST Returns CSV string with header: source_term, target_term, source_language, target_language, context_notes, context_data, usage_notes. @staticmethod def export_entries( db: Session, dict_id: str, delimiter: str = ",", @@ -549,10 +551,10 @@ class DictionaryManager: # endregion DictionaryManager.export_entries # region DictionaryManager.migrate_old_entries [TYPE Function] - # @PURPOSE: Migrate existing single-language dictionary entries to populate source_language and target_language. - # @PRE: db session is open. - # @POST: Entries with "und" source_language or target_language are updated with inferred values. - # @SIDE_EFFECT: Updates DictionaryEntry rows in bulk. + # @PURPOSE Migrate existing single-language dictionary entries to populate source_language and target_language. + # @PRE db session is open. + # @POST Entries with "und" source_language or target_language are updated with inferred values. + # @SIDE_EFFECT Updates DictionaryEntry rows in bulk. @staticmethod def migrate_old_entries(db: Session) -> dict[str, int]: with belief_scope("DictionaryManager.migrate_old_entries"): @@ -601,12 +603,12 @@ class DictionaryManager: # endregion DictionaryManager.migrate_old_entries # region DictionaryManager.filter_for_batch [TYPE Function] - # @PURPOSE: Scan batch texts for case-insensitive, word-boundary-aware matches against all dictionaries attached to a job, + # @PURPOSE Scan batch texts for case-insensitive, word-boundary-aware matches against all dictionaries attached to a job, # optionally filtered by language pair. When row_context is provided, computes context-aware priority flags. - # @PRE: job_id exists and source_texts is a list of strings. - # @POST: Returns list of matched entries with match info, sorted by priority across attached dictionaries. + # @PRE job_id exists and source_texts is a list of strings. + # @POST Returns list of matched entries with match info, sorted by priority across attached dictionaries. # When row_context is given, each result includes a 'priority_match' boolean. - # @SIDE_EFFECT: Queries TranslationJobDictionary, TerminologyDictionary, and DictionaryEntry tables. + # @SIDE_EFFECT Queries TranslationJobDictionary, TerminologyDictionary, and DictionaryEntry tables. @staticmethod def filter_for_batch( db: Session, source_texts: list[str], job_id: str, @@ -738,10 +740,10 @@ class DictionaryManager: # region DictionaryManager.submit_correction [TYPE Function] - # @PURPOSE: Submit a term correction from a run result. Validates language match, detects conflicts. - # @PRE: source_term, incorrect_target_term, corrected_target_term are non-empty. dict_id exists. - # @POST: Entry created or updated; origin tracking populated. Returns action + conflict info. - # @SIDE_EFFECT: Creates/updates DictionaryEntry row. + # @PURPOSE Submit a term correction from a run result. Validates language match, detects conflicts. + # @PRE source_term, incorrect_target_term, corrected_target_term are non-empty. dict_id exists. + # @POST Entry created or updated; origin tracking populated. Returns action + conflict info. + # @SIDE_EFFECT Creates/updates DictionaryEntry row. @staticmethod def submit_correction( db: Session, @@ -868,10 +870,10 @@ class DictionaryManager: # endregion DictionaryManager.submit_correction # region DictionaryManager.submit_bulk_corrections [TYPE Function] - # @PURPOSE: Submit multiple term corrections atomically — all succeed or all fail. - # @PRE: corrections list is non-empty. dict_id exists. - # @POST: All corrections applied or none applied with conflict list. - # @SIDE_EFFECT: Creates/updates DictionaryEntry rows; commits once. + # @PURPOSE Submit multiple term corrections atomically — all succeed or all fail. + # @PRE corrections list is non-empty. dict_id exists. + # @POST All corrections applied or none applied with conflict list. + # @SIDE_EFFECT Creates/updates DictionaryEntry rows; commits once. @staticmethod def submit_bulk_corrections( db: Session, @@ -998,5 +1000,8 @@ class DictionaryManager: # endregion DictionaryManager.submit_bulk_corrections +# #endregion DictionaryManager + + # #endregion DictionaryManager # #endregion DictionaryManagerModule diff --git a/backend/src/plugins/translate/executor.py b/backend/src/plugins/translate/executor.py index 3796f69c..46315ad0 100644 --- a/backend/src/plugins/translate/executor.py +++ b/backend/src/plugins/translate/executor.py @@ -194,11 +194,12 @@ def _check_translation_cache( # #endregion _check_translation_cache -# #region estimate_row_tokens [C:2] [TYPE Function] [SEMANTICS translate, token, estimation] +# #region estimate_row_tokens [C:4] [TYPE Function] [SEMANTICS translate, token, estimation] # @BRIEF Estimate token count for a single source row including context fields. -# @PRE: source_text is a string. -# @POST: Returns estimated token count >= 1. +# @PRE source_text is a string. +# @POST Returns estimated token count >= 1. # @RELATION DEPENDS_ON -> [_estimate_tokens_for_text] + def estimate_row_tokens( source_text: str, source_data: dict | None, @@ -1745,30 +1746,47 @@ class TranslationExecutor: "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", } + # Reasoning-safe system prompt: always forbid chain-of-thought in output. + # Reasoning models (DeepSeek, QwQ, etc.) may leak reasoning into content + # when response_format=json_object is set. Explicit suppression in the + # system message prevents this regardless of the disable_reasoning flag. + system_content = ( + "You are a database content translation assistant. " + "Translate the provided text accurately, preserving data semantics. " + "Respond directly with ONLY the JSON result. " + "Do NOT include any reasoning, thinking, chain-of-thought, analysis, " + "or explanation. Output ONLY valid JSON." + ) + payload = { "model": model, "messages": [ - {"role": "system", "content": "You are a database content translation assistant. Translate the provided text accurately, preserving data semantics."}, + {"role": "system", "content": system_content}, {"role": "user", "content": prompt}, ], "temperature": 0.1, "max_tokens": max_tokens, } + # Structured output — OpenRouter and Kilo also support response_format, but some # upstream providers (e.g. StepFun) reject it. We try with response_format and # fall back on 400 "structured_outputs is not supported". + # NOTE: Reasoning models (deepseek, qwen with reasoning, etc.) often break with + # response_format=json_object, producing reasoning text instead of JSON. + # When disable_reasoning is set, we remove response_format and rely on the + # system prompt to enforce JSON-only output. if provider_type in ("openai", "openai_compatible", "kilo", "openrouter", "litellm"): - payload["response_format"] = {"type": "json_object"} + if not disable_reasoning: + payload["response_format"] = {"type": "json_object"} # Suppress Chain of Thought reasoning to save output tokens # NOTE: Kilo/OpenRouter/LiteLLM do NOT support disabling reasoning (returns 400) if disable_reasoning: if provider_type not in ("kilo", "openrouter", "litellm"): payload["reasoning_effort"] = "none" - payload.pop("response_format", None) + # response_format already skipped above when disable_reasoning is True # Use caller-provided max_tokens instead of hardcoded 8192 payload["max_tokens"] = max_tokens - payload["messages"][0] = {"role": "system", "content": "You are a database content translation assistant. Translate the provided text accurately, preserving data semantics. Respond directly with ONLY the JSON result. Do NOT include any reasoning, thinking, chain-of-thought, analysis, or explanation. Output ONLY valid JSON."} logger.reason( f"LLM request url={base_url} model={payload.get('model')} " diff --git a/backend/src/plugins/translate/metrics.py b/backend/src/plugins/translate/metrics.py index ab5a544f..0b697ba4 100644 --- a/backend/src/plugins/translate/metrics.py +++ b/backend/src/plugins/translate/metrics.py @@ -1,14 +1,15 @@ # #region TranslationMetrics [C:3] [TYPE Module] [SEMANTICS sqlalchemy, translate, metrics, job, statistics] # @BRIEF Aggregate translation metrics from live TranslationEvent + MetricSnapshot for per-job reporting. -# @LAYER: Domain -# @RELATION DEPENDS_ON -> [TranslationEvent:Class] -# @RELATION DEPENDS_ON -> [MetricSnapshot:Class] -# @RELATION DEPENDS_ON -> [TranslationRun:Class] +# @LAYER Domain # @RELATION DEPENDS_ON -> [TranslationSchedule:Class] -# @PRE: Database session is open. -# @POST: Metrics are aggregated and returned; no side effects. -# @RATIONALE: Live events (<90 days) + MetricSnapshot (>=90 days) fusion for complete picture. -# @REJECTED: Querying all events for all time — would be slow; MetricSnapshot provides historical summary. +# @RELATION DEPENDS_ON -> [TranslationSchedule:Class] +# @RELATION DEPENDS_ON -> [TranslationSchedule:Class] +# @RELATION DEPENDS_ON -> [TranslationSchedule:Class] +# @PRE Database session is open. +# @POST Metrics are aggregated and returned; no side effects. +# @RATIONALE Live events (<90 days) + MetricSnapshot (>=90 days) fusion for complete picture. +# @REJECTED Querying all events for all time — would be slow; MetricSnapshot provides historical summary. +# @COMPLEXITY 4 from datetime import UTC, datetime from typing import Any @@ -34,9 +35,9 @@ class TranslationMetrics: self.db = db # region get_job_metrics [TYPE Function] - # @PURPOSE: Get aggregated metrics for a specific job. - # @PRE: job_id exists. - # @POST: Returns dict with metrics from events + latest snapshot. + # @PURPOSE Get aggregated metrics for a specific job. + # @PRE job_id exists. + # @POST Returns dict with metrics from events + latest snapshot. def get_job_metrics(self, job_id: str) -> dict[str, Any]: with belief_scope("TranslationMetrics.get_job_metrics"): # Run counts from TranslationRun @@ -174,8 +175,8 @@ class TranslationMetrics: # endregion get_job_metrics # region get_all_metrics [TYPE Function] - # @PURPOSE: Get aggregated metrics for all jobs. - # @POST: Returns list of per-job metrics. + # @PURPOSE Get aggregated metrics for all jobs. + # @POST Returns list of per-job metrics. def get_all_metrics(self) -> list[dict[str, Any]]: with belief_scope("TranslationMetrics.get_all_metrics"): job_ids = ( diff --git a/backend/src/plugins/translate/orchestrator.py b/backend/src/plugins/translate/orchestrator.py index 7b09853c..fe0a4b50 100644 --- a/backend/src/plugins/translate/orchestrator.py +++ b/backend/src/plugins/translate/orchestrator.py @@ -238,6 +238,15 @@ class TranslationOrchestrator: "run_id": run.id, "error": str(e), }) + # Rollback the session if it's in a broken state (e.g. after a + # failed flush from a previous exception in executor.execute_run). + # Without this, subsequent flush()/commit() calls raise + # "This Session's transaction has been rolled back". + try: + self.db.rollback() + except Exception: + pass + run = self.db.merge(run) run.status = "FAILED" run.error_message = f"Translation execution failed: {e}" run.completed_at = datetime.now(UTC) @@ -887,6 +896,7 @@ class TranslationOrchestrator: "id": run.id, "job_id": run.job_id, "status": run.status, + "trigger_type": run.trigger_type, "started_at": run.started_at.isoformat() if run.started_at else None, "completed_at": run.completed_at.isoformat() if run.completed_at else None, "error_message": run.error_message, diff --git a/backend/src/plugins/translate/plugin.py b/backend/src/plugins/translate/plugin.py index def022d8..36335393 100644 --- a/backend/src/plugins/translate/plugin.py +++ b/backend/src/plugins/translate/plugin.py @@ -1,9 +1,9 @@ # #region TranslatePlugin [C:2] [TYPE Module] [SEMANTICS clickhouse, translate, sql, dashboard, dialect] # @BRIEF TranslatePlugin skeleton for cross-dialect SQL and dashboard translation. -# @LAYER: Domain +# @LAYER Domain # @RELATION INHERITS -> [PluginBase] -# @RATIONALE: Separate plugin avoids bloating LLMAnalysisPlugin beyond fractal limit (<400 lines). -# @REJECTED: Extending LLMAnalysisPlugin would conflate two distinct feature domains. +# @RATIONALE Separate plugin avoids bloating LLMAnalysisPlugin beyond fractal limit (<400 lines). +# @REJECTED Extending LLMAnalysisPlugin would conflate two distinct feature domains. from typing import Any diff --git a/backend/src/plugins/translate/preview.py b/backend/src/plugins/translate/preview.py index bc39eddc..935aebe9 100644 --- a/backend/src/plugins/translate/preview.py +++ b/backend/src/plugins/translate/preview.py @@ -41,7 +41,7 @@ from ._token_budget import DEFAULT_CONTEXT_WINDOW, estimate_token_budget from .dictionary import DictionaryManager # #region DEFAULT_EXECUTION_PROMPT_TEMPLATE [TYPE Constant] -# @BRIEF Default prompt template for batch LLM translation execution (no context columns — faster). + # Supports both single-language and multi-language modes via {target_languages} placeholder. DEFAULT_EXECUTION_PROMPT_TEMPLATE: str = ( "Translate the following database content from {source_language} to the following language(s): {target_languages}.\n\n" @@ -63,9 +63,9 @@ DEFAULT_EXECUTION_PROMPT_TEMPLATE: str = ( ) # #endregion DEFAULT_EXECUTION_PROMPT_TEMPLATE - # #region DEFAULT_PREVIEW_PROMPT_TEMPLATE [TYPE Constant] -# @BRIEF Default prompt template for LLM translation preview. +# #region DEFAULT_PREVIEW_PROMPT_TEMPLATE [TYPE Constant] + DEFAULT_PREVIEW_PROMPT_TEMPLATE: str = ( "Translate the following database content.\n\n" "Source dialect: {source_dialect}\n" @@ -1038,19 +1038,37 @@ class TranslationPreview: "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", } + # Reasoning-safe system prompt: always forbid chain-of-thought in output. + # Reasoning models (DeepSeek, QwQ, etc.) may leak reasoning into content + # when response_format=json_object is set. Explicit suppression in the + # system message prevents this regardless of the disable_reasoning flag. + system_content = ( + "You are a database content translation assistant. " + "Translate the provided text accurately, preserving data semantics. " + "Respond directly with ONLY the JSON result. " + "Do NOT include any reasoning, thinking, chain-of-thought, analysis, " + "or explanation. Output ONLY valid JSON." + ) + payload = { "model": model, "messages": [ - {"role": "system", "content": "You are a database content translation assistant. Translate the provided text accurately, preserving data semantics."}, + {"role": "system", "content": system_content}, {"role": "user", "content": prompt}, ], "temperature": 0.1, "max_tokens": max_tokens, } + # Structured output — Kilo gateway supports response_format, but upstream providers # (e.g. StepFun) may reject it. We try with response_format and fall back on 400. + # NOTE: Reasoning models (deepseek variants, qwen with reasoning) often break with + # response_format=json_object, producing reasoning text instead of JSON. + # When disable_reasoning is set, we skip response_format and rely on the + # system prompt to enforce JSON-only output. if provider_type in ("openai", "openai_compatible", "kilo", "openrouter", "litellm"): - payload["response_format"] = {"type": "json_object"} + if not disable_reasoning: + payload["response_format"] = {"type": "json_object"} # Suppress Chain of Thought reasoning to save output tokens # NOTE: Kilo/OpenRouter/LiteLLM reject reasoning_effort — only use for native OpenAI-compatible @@ -1058,13 +1076,10 @@ class TranslationPreview: # Kilo/OpenRouter/LiteLLM reject reasoning_effort — only use for native OpenAI-compatible if provider_type not in ("kilo", "openrouter", "litellm"): payload["reasoning_effort"] = "none" - payload.pop("response_format", None) # JSON mode triggers reasoning on some models + # response_format already skipped above when disable_reasoning is True # Use caller-provided max_tokens instead of hardcoded 8192 # This ensures multi-language batches with large output get enough token budget. payload["max_tokens"] = max_tokens - # Universal instruction — all models understand "respond directly without reasoning" - system_content = "You are a database content translation assistant. Translate the provided text accurately, preserving data semantics. Respond directly with ONLY the JSON result. Do NOT include any reasoning, thinking, chain-of-thought, analysis, or explanation. Output ONLY valid JSON." - payload["messages"][0] = {"role": "system", "content": system_content} logger.reason( f"LLM request url={base_url} model={payload.get('model')} " diff --git a/backend/src/plugins/translate/prompt_builder.py b/backend/src/plugins/translate/prompt_builder.py index 29df8b9a..be152961 100644 --- a/backend/src/plugins/translate/prompt_builder.py +++ b/backend/src/plugins/translate/prompt_builder.py @@ -1,9 +1,10 @@ # #region ContextAwarePromptBuilder [C:2] [TYPE Module] [SEMANTICS translate, prompt, context, dictionary] # @BRIEF Pure-function prompt builder that enhances dictionary entries with context annotations. -# @LAYER: Domain +# @LAYER Domain # @RELATION DEPENDS_ON -> [DictionaryEntry:Class] -# @RATIONALE: Pure functions only — no I/O, no DB access. Separated from executor for testability. -# @REJECTED: Embedding context inline in the executor would make it untestable without mocking DB. +# @RATIONALE Pure functions only — no I/O, no DB access. Separated from executor for testability. +# @REJECTED Embedding context inline in the executor would make it untestable without mocking DB. + # # Typical workflow: # 1. Call build_context_entries(dictionary_entries, row_context) to get annotated, prioritized entries diff --git a/backend/src/plugins/translate/scheduler.py b/backend/src/plugins/translate/scheduler.py index 20383319..62d25dd0 100644 --- a/backend/src/plugins/translate/scheduler.py +++ b/backend/src/plugins/translate/scheduler.py @@ -240,12 +240,14 @@ class TranslationScheduler: # #endregion TranslationScheduler -# #region execute_scheduled_translation [TYPE Function] +# #region execute_scheduled_translation [C:4] [TYPE Function] # @BRIEF APScheduler job handler — runs scheduled translation with concurrency check and new-key-only fallback. -# @PRE: schedule_id is valid. -# @POST: Translation run created and executed if no concurrent run exists. -# @SIDE_EFFECT: DB writes; LLM calls; Superset API calls. -# @RATIONALE: New-key-only mode compares keys against most recent succeeded run; baseline_expired fallback does full. +# @PRE schedule_id is valid. +# @POST Translation run created and executed if no concurrent run exists. +# @SIDE_EFFECT DB writes; LLM calls; Superset API calls. +# @RATIONALE New-key-only mode compares keys against most recent succeeded run; baseline_expired fallback does full. +# @COMPLEXITY 4 + def execute_scheduled_translation( schedule_id: str, job_id: str, diff --git a/backend/src/plugins/translate/service.py b/backend/src/plugins/translate/service.py index 46ac4b98..34cd4760 100644 --- a/backend/src/plugins/translate/service.py +++ b/backend/src/plugins/translate/service.py @@ -38,7 +38,7 @@ SUPPORTED_DIALECTS = { } -# #region get_dialect_from_database [TYPE Function] +# #region get_dialect_from_database [C:4] [TYPE Function] # @BRIEF Extract normalized dialect string from a Superset database record. # @PRE: database_record is a dict from Superset API. # @POST: Returns normalized dialect string or raises ValueError if unsupported. @@ -84,7 +84,7 @@ def get_dialect_from_database(database_record: dict[str, Any]) -> str: # #endregion get_dialect_from_database -# #region fetch_datasource_metadata [TYPE Function] +# #region fetch_datasource_metadata [C:4] [TYPE Function] # @BRIEF Fetch datasource columns and database dialect from Superset. # @PRE: dataset_id is a valid Superset dataset ID and environment has valid credentials. # @POST: Returns (columns_list, dialect_string) or raises on failure. @@ -141,7 +141,7 @@ def fetch_datasource_metadata( # #endregion fetch_datasource_metadata -# #region detect_virtual_columns [TYPE Function] +# #region detect_virtual_columns [C:4] [TYPE Function] # @BRIEF Identify virtual (calculated) columns from column metadata. # @PRE: columns is a list of dicts with 'is_physical' key. # @POST: Returns list of virtual column names. @@ -519,11 +519,13 @@ def job_to_response(job: TranslationJob, dict_ids: list[str] | None = None) -> T # #endregion job_to_response -# #region DatasourceColumnsService [TYPE Function] +# #region DatasourceColumnsService [C:4] [TYPE Function] # @BRIEF Fetch datasource column metadata from Superset and return structured response. -# @PRE: datasource_id is a valid Superset dataset ID. -# @POST: Returns DatasourceColumnsResponse with column metadata and database dialect. -# @SIDE_EFFECT: Queries Superset API for dataset detail and database info. +# @PRE datasource_id is a valid Superset dataset ID. +# @POST Returns DatasourceColumnsResponse with column metadata and database dialect. +# @SIDE_EFFECT Queries Superset API for dataset detail and database info. +# @COMPLEXITY 4 + def get_datasource_columns( datasource_id: int, env_id: str, diff --git a/backend/src/plugins/translate/sql_generator.py b/backend/src/plugins/translate/sql_generator.py index 363c7836..fa5bf46e 100644 --- a/backend/src/plugins/translate/sql_generator.py +++ b/backend/src/plugins/translate/sql_generator.py @@ -58,7 +58,7 @@ def _normalize_timestamp_value(value: Any) -> str | None: # #endregion _normalize_timestamp_value -# #region _quote_identifier [TYPE Function] +# #region _quote_identifier [C:4] [TYPE Function] # @BRIEF Quote an identifier per dialect rules. PostgreSQL uses double quotes; ClickHouse uses backticks. # @PRE: identifier is a non-empty string. # @POST: Returns safely quoted identifier. @@ -159,10 +159,12 @@ def generate_insert_sql( # #endregion generate_insert_sql -# #region generate_upsert_sql [TYPE Function] +# #region generate_upsert_sql [C:4] [TYPE Function] # @BRIEF Generate PostgreSQL dialect UPSERT SQL with ON CONFLICT DO UPDATE. -# @PRE: dialect is postgresql-compatible. target_table, columns, key_columns are non-empty. -# @POST: Returns UPSERT SQL string or raises ValueError. +# @PRE dialect is postgresql-compatible. target_table, columns, key_columns are non-empty. +# @POST Returns UPSERT SQL string or raises ValueError. +# @COMPLEXITY 4 + def generate_upsert_sql( target_schema: str | None, target_table: str, diff --git a/backend/src/plugins/translate/superset_executor.py b/backend/src/plugins/translate/superset_executor.py index 06bce766..0c511e39 100644 --- a/backend/src/plugins/translate/superset_executor.py +++ b/backend/src/plugins/translate/superset_executor.py @@ -1,13 +1,13 @@ # #region SupersetSqlLabExecutor [C:4] [TYPE Module] [SEMANTICS translate, superset, sqllab, execute, query] # @BRIEF Submit SQL to Superset SQL Lab API and poll execution status. -# @LAYER: Infra -# @RELATION DEPENDS_ON -> [SupersetClient] +# @LAYER Infrastructure # @RELATION DEPENDS_ON -> [ConfigManager] -# @PRE: Valid Superset environment configuration and authenticated client. -# @POST: SQL is submitted to Superset SQL Lab; execution reference is returned. -# @SIDE_EFFECT: Makes HTTP calls to Superset /api/v1/sqllab/execute/; polls status. -# @RATIONALE: Direct SQL Lab API submission provides audit trail and execution monitoring within Superset. -# @REJECTED: Direct database connection bypass — would skip Superset's SQL Lab audit and RBAC. +# @RELATION DEPENDS_ON -> [ConfigManager] +# @PRE Valid Superset environment configuration and authenticated client. +# @POST SQL is submitted to Superset SQL Lab; execution reference is returned. +# @SIDE_EFFECT Makes HTTP calls to Superset /api/v1/sqllab/execute/; polls status. +# @RATIONALE Direct SQL Lab API submission provides audit trail and execution monitoring within Superset. +# @REJECTED Direct database connection bypass — would skip Superset's SQL Lab audit and RBAC. import json import time @@ -21,9 +21,9 @@ from ...core.superset_client import SupersetClient # #region SupersetSqlLabExecutor [C:4] [TYPE Class] # @BRIEF Submit SQL to Superset SQL Lab API with polling and status tracking. -# @PRE: Valid environment ID and ConfigManager. -# @POST: SQL submitted to Superset; execution reference recorded. -# @SIDE_EFFECT: Makes HTTP POST to /api/v1/sqllab/execute/; polls GET for status. +# @PRE Valid environment ID and ConfigManager. +# @POST SQL submitted to Superset; execution reference recorded. +# @SIDE_EFFECT Makes HTTP POST to /api/v1/sqllab/execute/; polls GET for status. class SupersetSqlLabExecutor: def __init__(self, config_manager: ConfigManager, env_id: str): @@ -34,10 +34,10 @@ class SupersetSqlLabExecutor: self._database_backend: str | None = None # region _get_client [TYPE Function] - # @PURPOSE: Lazy-initialize SupersetClient for the configured environment. - # @PRE: env_id must correspond to a valid environment config. - # @POST: Returns authenticated SupersetClient. - # @SIDE_EFFECT: Authenticates against Superset API. + # @PURPOSE Lazy-initialize SupersetClient for the configured environment. + # @PRE env_id must correspond to a valid environment config. + # @POST Returns authenticated SupersetClient. + # @SIDE_EFFECT Authenticates against Superset API. def _get_client(self) -> SupersetClient: with belief_scope("SupersetSqlLabExecutor._get_client"): if self._client is not None: @@ -53,10 +53,10 @@ class SupersetSqlLabExecutor: # endregion _get_client # region resolve_database_id [TYPE Function] - # @PURPOSE: Resolve the target database ID from the environment and fetch its backend engine. - # @PRE: database_name or database_id should be known. - # @POST: Returns database_id integer or raises ValueError. Also sets self._database_backend. - # @SIDE_EFFECT: Fetches databases list from Superset; optionally fetches single DB for backend. + # @PURPOSE Resolve the target database ID from the environment and fetch its backend engine. + # @PRE database_name or database_id should be known. + # @POST Returns database_id integer or raises ValueError. Also sets self._database_backend. + # @SIDE_EFFECT Fetches databases list from Superset; optionally fetches single DB for backend. def resolve_database_id( self, database_name: str | None = None, @@ -121,17 +121,17 @@ class SupersetSqlLabExecutor: # endregion resolve_database_id # region get_database_backend [TYPE Function] - # @PURPOSE: Return the cached database backend/engine string. - # @POST: Returns backend string or None if not yet resolved. + # @PURPOSE Return the cached database backend/engine string. + # @POST Returns backend string or None if not yet resolved. def get_database_backend(self) -> str | None: return self._database_backend # endregion get_database_backend # region execute_sql [TYPE Function] - # @PURPOSE: Submit SQL to Superset SQL Lab and return execution tracking info. - # @PRE: sql is valid SQL string. database_id is a valid Superset DB ID. - # @POST: Returns execution result dict with query_id and status. - # @SIDE_EFFECT: Makes HTTP POST to /api/v1/sqllab/execute/. + # @PURPOSE Submit SQL to Superset SQL Lab and return execution tracking info. + # @PRE sql is valid SQL string. database_id is a valid Superset DB ID. + # @POST Returns execution result dict with query_id and status. + # @SIDE_EFFECT Makes HTTP POST to /api/v1/sqllab/execute/. def execute_sql( self, sql: str, @@ -236,10 +236,10 @@ class SupersetSqlLabExecutor: # endregion execute_sql # region poll_execution_status [TYPE Function] - # @PURPOSE: Poll Superset for SQL execution status until completion or timeout. - # @PRE: query_id is a valid Superset query ID. - # @POST: Returns final execution status dict. - # @SIDE_EFFECT: Makes HTTP GET requests to Superset. + # @PURPOSE Poll Superset for SQL execution status until completion or timeout. + # @PRE query_id is a valid Superset query ID. + # @POST Returns final execution status dict. + # @SIDE_EFFECT Makes HTTP GET requests to Superset. def poll_execution_status( self, query_id: str, @@ -329,10 +329,10 @@ class SupersetSqlLabExecutor: # endregion poll_execution_status # region execute_and_poll [TYPE Function] - # @PURPOSE: Execute SQL and wait for completion. One-shot convenience method. - # @PRE: sql is valid SQL. - # @POST: Returns final execution result. - # @SIDE_EFFECT: Makes HTTP calls to Superset API. + # @PURPOSE Execute SQL and wait for completion. One-shot convenience method. + # @PRE sql is valid SQL. + # @POST Returns final execution result. + # @SIDE_EFFECT Makes HTTP calls to Superset API. def execute_and_poll( self, sql: str, @@ -384,10 +384,10 @@ class SupersetSqlLabExecutor: # endregion execute_and_poll # region get_query_results [TYPE Function] - # @PURPOSE: Fetch the results of a completed query. - # @PRE: query_id is a valid Superset query ID. - # @POST: Returns query results if available. - # @SIDE_EFFECT: Makes HTTP GET to Superset. + # @PURPOSE Fetch the results of a completed query. + # @PRE query_id is a valid Superset query ID. + # @POST Returns query results if available. + # @SIDE_EFFECT Makes HTTP GET to Superset. def get_query_results(self, query_id: str) -> dict[str, Any]: with belief_scope("SupersetSqlLabExecutor.get_query_results"): client = self._get_client() diff --git a/backend/src/schemas/translate.py b/backend/src/schemas/translate.py index 31338fdf..e5a63f06 100644 --- a/backend/src/schemas/translate.py +++ b/backend/src/schemas/translate.py @@ -1,6 +1,6 @@ -# #region TranslateSchemas [C:2] [TYPE Module] [SEMANTICS pydantic, translate, schema, translate-job-create] +# #region TranslateSchemas [C:3] [TYPE Module] [SEMANTICS pydantic, translate, schema, translate-job-create] # @BRIEF Pydantic v2 schemas for translation API request/response serialization. -# @LAYER: API +# @LAYER API # @RELATION DEPENDS_ON -> pydantic from datetime import datetime diff --git a/backend/src/services/git/_base.py b/backend/src/services/git/_base.py index 2f085388..1774e1fa 100644 --- a/backend/src/services/git/_base.py +++ b/backend/src/services/git/_base.py @@ -1,6 +1,6 @@ -# #region GitServiceBase [C:3] [TYPE Module] [SEMANTICS git, repository, clone, base, mixin] +# #region GitServiceBase [C:4] [TYPE Module] [SEMANTICS git, repository, clone, base, mixin, lock, http] # @LAYER: Infra -# @BRIEF Core GitService base class — initialization, path resolution, repo lifecycle (init/delete/get), and identity configuration. +# @BRIEF Core GitService base class — initialization, path resolution, repo lifecycle (init/delete/get), identity configuration, concurrent locking, and shared HTTP client pool. # @RELATION INHERITED_BY -> [GitService] # @RELATION DEPENDS_ON -> [SessionLocal] # @RELATION DEPENDS_ON -> [AppConfigRecord] @@ -9,8 +9,12 @@ import os import re import shutil +import threading +from contextlib import contextmanager from pathlib import Path +from urllib.parse import quote +import httpx from fastapi import HTTPException from git import Repo from git.exc import InvalidGitRepositoryError, NoSuchPathError @@ -21,14 +25,16 @@ from src.models.config import AppConfigRecord from src.models.git import GitRepository -# #region GitServiceBase [C:3] [TYPE Class] -# @BRIEF Base class for GitService providing initialization, path resolution, repository lifecycle, and identity. +# #region GitServiceBase [C:4] [TYPE Class] +# @BRIEF Base class for GitService providing initialization, path resolution, repository lifecycle, identity, concurrent locking, and shared HTTP client. +# @PRE base_path is a valid string path. +# @POST GitService is initialized; base_path directory exists; shared AsyncClient ready; lock registry empty. +# @SIDE_EFFECT Creates HTTP connection pool (max_keepalive=20, max_connections=100). class GitServiceBase: - # region GitService_init [TYPE Function] - # @PURPOSE: Initializes the GitService with a base path for repositories. - # @PARAM: base_path (str) - Root directory for all Git clones. + # region GitService_init [C:4] [TYPE Function] + # @PURPOSE: Initializes the GitService with a base path, concurrent access locks, and shared HTTP client. # @PRE: base_path is a valid string path. - # @POST: GitService is initialized; base_path directory exists. + # @POST: GitService is initialized; base_path directory exists; _lock_registry, _http_client ready. def __init__(self, base_path: str = "git_repos"): with belief_scope("GitService.__init__"): backend_root = Path(__file__).parents[3] @@ -36,8 +42,65 @@ class GitServiceBase: self._uses_default_base_path = base_path == "git_repos" self.base_path = self._resolve_base_path(base_path) self._ensure_base_path_exists() + + # Fix 3: Per-dashboard reentrant lock registry for concurrent access protection + self._lock_registry: dict[int, threading.RLock] = {} + self._reg_lock = threading.Lock() + + # Fix: close() race condition protection + self._closed = False + self._close_lock = threading.Lock() + + # Fix 5: Shared httpx.AsyncClient with connection pooling + self._http_client = httpx.AsyncClient( + timeout=30.0, + limits=httpx.Limits(max_keepalive_connections=20, max_connections=100), + ) # endregion GitService_init + # region _get_lock [C:2] [TYPE Function] [SEMANTICS lock,concurrency] + # @BRIEF Get or create a per-dashboard reentrant lock for thread-safe GitPython access. + # @PRE: dashboard_id is a valid integer. + # @POST: Returns a threading.RLock unique to the given dashboard_id. + def _get_lock(self, dashboard_id: int) -> threading.RLock: + with self._reg_lock: + if dashboard_id not in self._lock_registry: + self._lock_registry[dashboard_id] = threading.RLock() + return self._lock_registry[dashboard_id] + # endregion _get_lock + + # region _locked [C:2] [TYPE Function] [SEMANTICS lock,context,concurrency] + # @BRIEF Context manager that acquires the per-dashboard reentrant lock for the duration of the block. + # @PRE: dashboard_id is a valid integer. + # @POST: Lock is acquired on enter, released on exit. + @contextmanager + def _locked(self, dashboard_id: int): + if self._closed: + raise RuntimeError("GitService is closed") + lock = self._get_lock(dashboard_id) + lock.acquire() + try: + yield + finally: + lock.release() + # endregion _locked + + # region _clone_with_auth [C:2] [TYPE Function] [SEMANTICS git,clone,auth,security] + # @BRIEF Clone repository with PAT and immediately strip credentials from origin remote URL. + # @PRE: remote_url is a valid Git URL; pat is provided when required; repo_path is writable. + # @POST: Repo cloned at repo_path; origin remote URL has no embedded PAT. + # @SIDE_EFFECT Clones remote repository to local filesystem. + def _clone_with_auth(self, remote_url: str, repo_path: str, pat: str) -> Repo: + auth_url = remote_url + if pat and "://" in remote_url: + proto, rest = remote_url.split("://", 1) + auth_url = f"{proto}://oauth2:{quote(pat, safe='')}@{rest}" + repo = Repo.clone_from(auth_url, repo_path) + # Strip PAT from origin URL to prevent credential leakage in .git/config, logs, ps aux + repo.git.remote("set-url", "origin", remote_url) + return repo + # endregion _clone_with_auth + # region _ensure_base_path_exists [TYPE Function] # @PURPOSE: Ensure the repositories root directory exists and is a directory. # @PRE: self.base_path is resolved to filesystem path. @@ -194,124 +257,138 @@ class GitServiceBase: return target_path # endregion _get_repo_path - # region init_repo [TYPE Function] - # @PURPOSE: Initialize or clone a repository for a dashboard. + # region init_repo [C:4] [TYPE Function] [SEMANTICS git,clone,init,lock] + # @PURPOSE: Initialize or clone a repository for a dashboard with concurrent access protection. # @PARAM: dashboard_id (int), remote_url (str), pat (str), repo_key (Optional[str]). # @PRE: dashboard_id is int, remote_url is valid Git URL, pat is provided. - # @POST: Repository is cloned or opened at the local path. + # @POST: Repository is cloned or opened at the local path. Origin remote URL has no embedded PAT. + # @SIDE_EFFECT Clones remote repository; modifies local filesystem; protected by per-dashboard lock. # @RETURN: Repo - def init_repo(self, dashboard_id: int, remote_url: str, pat: str, repo_key: str | None = None) -> Repo: - with belief_scope("GitService.init_repo"): - self._ensure_base_path_exists() - repo_path = self._get_repo_path(dashboard_id, repo_key=repo_key or str(dashboard_id)) - Path(repo_path).parent.mkdir(parents=True, exist_ok=True) - if pat and "://" in remote_url: - proto, rest = remote_url.split("://", 1) - auth_url = f"{proto}://oauth2:{pat}@{rest}" - else: - auth_url = remote_url - if os.path.exists(repo_path): - logger.reason(f"Opening existing repo at {repo_path}", extra={"src": "init_repo"}) - try: - repo = Repo(repo_path) - except (InvalidGitRepositoryError, NoSuchPathError): - logger.reason(f"Existing path is not a Git repository, recreating: {repo_path}", extra={"src": "init_repo"}) - stale_path = Path(repo_path) - if stale_path.exists(): - shutil.rmtree(stale_path, ignore_errors=True) + def init_repo(self, dashboard_id: int, remote_url: str, pat: str, repo_key: str | None = None, default_branch: str | None = None) -> Repo: + with self._locked(dashboard_id): + with belief_scope("GitService.init_repo"): + self._ensure_base_path_exists() + repo_path = self._get_repo_path(dashboard_id, repo_key=repo_key or str(dashboard_id)) + Path(repo_path).parent.mkdir(parents=True, exist_ok=True) + if os.path.exists(repo_path): + logger.reason(f"Opening existing repo at {repo_path}", extra={"src": "init_repo"}) + try: + repo = Repo(repo_path) + except (InvalidGitRepositoryError, NoSuchPathError): + logger.reason(f"Existing path is not a Git repository, recreating: {repo_path}", extra={"src": "init_repo"}) + stale_path = Path(repo_path) if stale_path.exists(): - try: - stale_path.unlink() - except Exception: - pass - repo = Repo.clone_from(auth_url, repo_path) + shutil.rmtree(stale_path, ignore_errors=True) + if stale_path.exists(): + try: + stale_path.unlink() + except Exception: + pass + repo = self._clone_with_auth(remote_url, repo_path, pat) + self._ensure_gitflow_branches(repo, dashboard_id) + return repo + logger.reason(f"Cloning {remote_url} to {repo_path}", extra={"src": "init_repo"}) + repo = self._clone_with_auth(remote_url, repo_path, pat) self._ensure_gitflow_branches(repo, dashboard_id) return repo - logger.reason(f"Cloning {remote_url} to {repo_path}", extra={"src": "init_repo"}) - repo = Repo.clone_from(auth_url, repo_path) - self._ensure_gitflow_branches(repo, dashboard_id) - return repo # endregion init_repo - # region delete_repo [TYPE Function] - # @PURPOSE: Remove local repository and DB binding for a dashboard. + # region delete_repo [C:4] [TYPE Function] [SEMANTICS git,delete,lock] + # @PURPOSE: Remove local repository and DB binding for a dashboard with concurrent access protection. # @PRE: dashboard_id is a valid integer. # @POST: Local path is deleted when present and GitRepository row is removed. + # @SIDE_EFFECT Deletes filesystem directory and DB record; protected by per-dashboard lock. def delete_repo(self, dashboard_id: int) -> None: - with belief_scope("GitService.delete_repo"): - repo_path = self._get_repo_path(dashboard_id) - removed_files = False - if os.path.exists(repo_path): - if os.path.isdir(repo_path): - shutil.rmtree(repo_path) - else: - os.remove(repo_path) - removed_files = True - session = SessionLocal() - try: - db_repo = ( - session.query(GitRepository) - .filter(GitRepository.dashboard_id == int(dashboard_id)) - .first() - ) - if db_repo: - session.delete(db_repo) - session.commit() - return - if removed_files: - return - raise HTTPException( - status_code=404, - detail=f"Repository for dashboard {dashboard_id} not found", - ) - except HTTPException: - session.rollback() - raise - except Exception as e: - session.rollback() - logger.error(f"[delete_repo][Coherence:Failed] Failed to delete repository for dashboard {dashboard_id}: {e}") - raise HTTPException(status_code=500, detail=f"Failed to delete repository: {e!s}") - finally: - session.close() + with self._locked(dashboard_id): + with belief_scope("GitService.delete_repo"): + repo_path = self._get_repo_path(dashboard_id) + removed_files = False + if os.path.exists(repo_path): + if os.path.isdir(repo_path): + shutil.rmtree(repo_path) + else: + os.remove(repo_path) + removed_files = True + session = SessionLocal() + try: + db_repo = ( + session.query(GitRepository) + .filter(GitRepository.dashboard_id == int(dashboard_id)) + .first() + ) + if db_repo: + session.delete(db_repo) + session.commit() + return + if removed_files: + return + raise HTTPException( + status_code=404, + detail=f"Repository for dashboard {dashboard_id} not found", + ) + except HTTPException: + session.rollback() + raise + except Exception as e: + session.rollback() + logger.error(f"[delete_repo][Coherence:Failed] Failed to delete repository for dashboard {dashboard_id}: {e}") + raise HTTPException(status_code=500, detail=f"Failed to delete repository: {e!s}") + finally: + session.close() # endregion delete_repo - # region get_repo [TYPE Function] - # @PURPOSE: Get Repo object for a dashboard. + # region get_repo [C:4] [TYPE Function] [SEMANTICS git,open,lock] + # @PURPOSE: Get Repo object for a dashboard with concurrent access protection. # @PRE: Repository must exist on disk for the given dashboard_id. # @POST: Returns a GitPython Repo instance for the dashboard. # @RETURN: Repo def get_repo(self, dashboard_id: int) -> Repo: - with belief_scope("GitService.get_repo"): - repo_path = self._get_repo_path(dashboard_id) - if not os.path.exists(repo_path): - logger.error(f"[get_repo][Coherence:Failed] Repository for dashboard {dashboard_id} does not exist") - raise HTTPException(status_code=404, detail=f"Repository for dashboard {dashboard_id} not found") - try: - return Repo(repo_path) - except Exception as e: - logger.error(f"[get_repo][Coherence:Failed] Failed to open repository at {repo_path}: {e}") - raise HTTPException(status_code=500, detail="Failed to open local Git repository") + with self._locked(dashboard_id): + with belief_scope("GitService.get_repo"): + repo_path = self._get_repo_path(dashboard_id) + if not os.path.exists(repo_path): + logger.error(f"[get_repo][Coherence:Failed] Repository for dashboard {dashboard_id} does not exist") + raise HTTPException(status_code=404, detail=f"Repository for dashboard {dashboard_id} not found") + try: + return Repo(repo_path) + except Exception as e: + logger.error(f"[get_repo][Coherence:Failed] Failed to open repository at {repo_path}: {e}") + raise HTTPException(status_code=500, detail="Failed to open local Git repository") # endregion get_repo - # region configure_identity [TYPE Function] - # @PURPOSE: Configure repository-local Git committer identity for user-scoped operations. + # region configure_identity [C:4] [TYPE Function] [SEMANTICS git,identity,lock] + # @PURPOSE: Configure repository-local Git committer identity with concurrent access protection. # @PRE: dashboard_id repository exists; git_username/git_email may be empty. # @POST: Repository config has user.name and user.email when both identity values are provided. + # @SIDE_EFFECT Writes to repository git config; protected by per-dashboard lock. def configure_identity(self, dashboard_id: int, git_username: str | None, git_email: str | None) -> None: - with belief_scope("GitService.configure_identity"): - normalized_username = str(git_username or "").strip() - normalized_email = str(git_email or "").strip() - if not normalized_username or not normalized_email: - return - repo = self.get_repo(dashboard_id) - try: - with repo.config_writer(config_level="repository") as config_writer: - config_writer.set_value("user", "name", normalized_username) - config_writer.set_value("user", "email", normalized_email) - logger.reason(f"Applied repository-local git identity for dashboard {dashboard_id}", extra={"src": "configure_identity"}) - except Exception as e: - logger.error(f"[configure_identity][Coherence:Failed] Failed to configure git identity: {e}") - raise HTTPException(status_code=500, detail=f"Failed to configure git identity: {e!s}") + with self._locked(dashboard_id): + with belief_scope("GitService.configure_identity"): + normalized_username = str(git_username or "").strip() + normalized_email = str(git_email or "").strip() + if not normalized_username or not normalized_email: + return + repo = self.get_repo(dashboard_id) + try: + with repo.config_writer(config_level="repository") as config_writer: + config_writer.set_value("user", "name", normalized_username) + config_writer.set_value("user", "email", normalized_email) + logger.reason(f"Applied repository-local git identity for dashboard {dashboard_id}", extra={"src": "configure_identity"}) + except Exception as e: + logger.error(f"[configure_identity][Coherence:Failed] Failed to configure git identity: {e}") + raise HTTPException(status_code=500, detail=f"Failed to configure git identity: {e!s}") # endregion configure_identity + + # region close [C:2] [TYPE Function] [SEMANTICS http,cleanup,shutdown] + # @BRIEF Gracefully close the shared HTTP client (connection pool). + # @PRE: _http_client is initialized. + # @POST: HTTP connections closed. + async def close(self): + with self._close_lock: + if self._closed: + return + self._closed = True + await self._http_client.aclose() + # endregion close # #endregion GitServiceBase # #endregion GitServiceBase diff --git a/backend/src/services/git/_branch.py b/backend/src/services/git/_branch.py index e12747f2..1eeaf47f 100644 --- a/backend/src/services/git/_branch.py +++ b/backend/src/services/git/_branch.py @@ -1,6 +1,6 @@ -# #region GitServiceBranchMixin [C:3] [TYPE Module] [SEMANTICS git, branch, checkout, list, namespace] +# #region GitServiceBranchMixin [C:4] [TYPE Module] [SEMANTICS git, branch, checkout, list, namespace, lock] # @LAYER: Infra -# @BRIEF Branch and commit operations for GitService — gitflow branches, list/create/checkout branches, commit changes. +# @BRIEF Branch and commit operations for GitService — gitflow branches, list/create/checkout branches, commit changes (all concurrent-safe via per-dashboard locks). # @RELATION USED_BY -> [GitService] import os @@ -15,10 +15,11 @@ from src.core.logger import belief_scope, logger # #region GitServiceBranchMixin [C:3] [TYPE Class] # @BRIEF Mixin providing branch and commit operations for GitService. class GitServiceBranchMixin: - # region _ensure_gitflow_branches [TYPE Function] + # region _ensure_gitflow_branches [C:4] [TYPE Function] [SEMANTICS git,gitflow,branch,lock] # @PURPOSE: Ensure standard GitFlow branches (main/dev/preprod) exist locally and on origin. # @PRE: repo is a valid GitPython Repo instance. # @POST: main, dev, preprod are available in local repository and pushed to origin when available. + # Active branch unchanged (no spurious checkout). def _ensure_gitflow_branches(self, repo: Repo, dashboard_id: int) -> None: with belief_scope("GitService._ensure_gitflow_branches"): required_branches = ["main", "dev", "preprod"] @@ -79,62 +80,74 @@ class GitServiceBranchMixin: status_code=500, detail=f"Failed to create default branch '{branch_name}' on remote: {e!s}", ) + # Fix 6: Only checkout if not already on dev try: - repo.git.checkout("dev") - logger.reason(f"Checked out default branch dev for dashboard {dashboard_id}", extra={"src": "_ensure_gitflow_branches"}) - except Exception as e: - logger.reason(f"Could not checkout dev branch for dashboard {dashboard_id}: {e}", extra={"src": "_ensure_gitflow_branches"}) + current_branch = repo.active_branch.name + except Exception: + current_branch = None + if current_branch != "dev": + try: + repo.git.checkout("dev") + logger.reason(f"Checked out default branch dev for dashboard {dashboard_id}", extra={"src": "_ensure_gitflow_branches"}) + except Exception as e: + logger.reason(f"Could not checkout dev branch for dashboard {dashboard_id}: {e}", extra={"src": "_ensure_gitflow_branches"}) # endregion _ensure_gitflow_branches - # region list_branches [TYPE Function] - # @PURPOSE: List all branches for a dashboard's repository. + # region list_branches [C:4] [TYPE Function] [SEMANTICS git,branch,list,lock] + # @PURPOSE: List all branches (excluding tags) for a dashboard's repository, concurrent-safe. # @PRE: Repository for dashboard_id exists. - # @POST: Returns a list of branch metadata dictionaries. + # @POST: Returns a list of branch metadata dictionaries (no tag refs). # @RETURN: List[dict] def list_branches(self, dashboard_id: int) -> list[dict]: - with belief_scope("GitService.list_branches"): - repo = self.get_repo(dashboard_id) - logger.reason(f"Listing branches for {dashboard_id}. Refs: {repo.refs}", extra={"src": "list_branches"}) - branches = [] - for ref in repo.refs: + with self._locked(dashboard_id): + with belief_scope("GitService.list_branches"): + repo = self.get_repo(dashboard_id) + logger.reason(f"Listing branches for {dashboard_id}. Refs: {repo.refs}", extra={"src": "list_branches"}) + branches = [] + for ref in repo.refs: + try: + # Fix 8: Skip tag refs + ref_name = str(ref.name) + if ref_name.startswith('refs/tags/'): + continue + name = ref_name.replace('refs/heads/', '').replace('refs/remotes/origin/', '') + if any(b['name'] == name for b in branches): + continue + branches.append({ + "name": name, + "commit_hash": ref.commit.hexsha if hasattr(ref, 'commit') else "0000000", + "is_remote": ref.is_remote() if hasattr(ref, 'is_remote') else False, + "last_updated": datetime.fromtimestamp(ref.commit.committed_date) if hasattr(ref, 'commit') else datetime.utcnow() + }) + except Exception as e: + logger.reason(f"Skipping ref {ref}: {e}", extra={"src": "list_branches"}) try: - name = ref.name.replace('refs/heads/', '').replace('refs/remotes/origin/', '') - if any(b['name'] == name for b in branches): - continue - branches.append({ - "name": name, - "commit_hash": ref.commit.hexsha if hasattr(ref, 'commit') else "0000000", - "is_remote": ref.is_remote() if hasattr(ref, 'is_remote') else False, - "last_updated": datetime.fromtimestamp(ref.commit.committed_date) if hasattr(ref, 'commit') else datetime.utcnow() - }) + active_name = repo.active_branch.name + if not any(b['name'] == active_name for b in branches): + branches.append({ + "name": active_name, "commit_hash": "0000000", + "is_remote": False, "last_updated": datetime.utcnow() + }) except Exception as e: - logger.reason(f"Skipping ref {ref}: {e}", extra={"src": "list_branches"}) - try: - active_name = repo.active_branch.name - if not any(b['name'] == active_name for b in branches): - branches.append({ - "name": active_name, "commit_hash": "0000000", - "is_remote": False, "last_updated": datetime.utcnow() - }) - except Exception as e: - logger.reason(f"Could not determine active branch: {e}", extra={"src": "list_branches"}) - if not branches: - branches.append({ - "name": "dev", "commit_hash": "0000000", - "is_remote": False, "last_updated": datetime.utcnow() - }) - return branches + logger.reason(f"Could not determine active branch: {e}", extra={"src": "list_branches"}) + if not branches: + branches.append({ + "name": "dev", "commit_hash": "0000000", + "is_remote": False, "last_updated": datetime.utcnow() + }) + return branches # endregion list_branches - # region create_branch [TYPE Function] - # @PURPOSE: Create a new branch from an existing one. + # region create_branch [C:4] [TYPE Function] [SEMANTICS git,branch,create,lock] + # @PURPOSE: Create a new branch from an existing one (concurrent-safe). # @PARAM: name (str) - New branch name. # @PARAM: from_branch (str) - Source branch. # @PRE: Repository exists; name is valid; from_branch exists or repo is empty. # @POST: A new branch is created in the repository. def create_branch(self, dashboard_id: int, name: str, from_branch: str = "main"): - with belief_scope("GitService.create_branch"): - repo = self.get_repo(dashboard_id) + with self._locked(dashboard_id): + with belief_scope("GitService.create_branch"): + repo = self.get_repo(dashboard_id) logger.reason(f"Creating branch {name} from {from_branch}", extra={"src": "create_branch"}) if not repo.heads and not repo.remotes: logger.reason("Repository is empty. Creating initial commit to enable branching.", extra={"src": "create_branch"}) @@ -157,26 +170,28 @@ class GitServiceBranchMixin: raise # endregion create_branch - # region checkout_branch [TYPE Function] - # @PURPOSE: Switch to a specific branch. + # region checkout_branch [C:4] [TYPE Function] [SEMANTICS git,branch,checkout,lock] + # @PURPOSE: Switch to a specific branch (concurrent-safe). # @PRE: Repository exists and the specified branch name exists. # @POST: The repository working directory is updated to the specified branch. def checkout_branch(self, dashboard_id: int, name: str): - with belief_scope("GitService.checkout_branch"): - repo = self.get_repo(dashboard_id) + with self._locked(dashboard_id): + with belief_scope("GitService.checkout_branch"): + repo = self.get_repo(dashboard_id) logger.reason(f"Checking out branch {name}", extra={"src": "checkout_branch"}) repo.git.checkout(name) # endregion checkout_branch - # region commit_changes [TYPE Function] - # @PURPOSE: Stage and commit changes. + # region commit_changes [C:4] [TYPE Function] [SEMANTICS git,commit,stage,lock] + # @PURPOSE: Stage and commit changes (concurrent-safe). # @PARAM: message (str) - Commit message. # @PARAM: files (List[str]) - Optional list of specific files to stage. # @PRE: Repository exists and has changes (dirty) or files are specified. # @POST: Changes are staged and a new commit is created. def commit_changes(self, dashboard_id: int, message: str, files: list[str] = None): - with belief_scope("GitService.commit_changes"): - repo = self.get_repo(dashboard_id) + with self._locked(dashboard_id): + with belief_scope("GitService.commit_changes"): + repo = self.get_repo(dashboard_id) if not repo.is_dirty(untracked_files=True) and not files: logger.reason(f"No changes to commit for dashboard {dashboard_id}", extra={"src": "commit_changes"}) return diff --git a/backend/src/services/git/_gitea.py b/backend/src/services/git/_gitea.py index b90ba9b1..6a6c6471 100644 --- a/backend/src/services/git/_gitea.py +++ b/backend/src/services/git/_gitea.py @@ -1,6 +1,6 @@ -# #region GitServiceGiteaMixin [C:3] [TYPE Module] [SEMANTICS git, gitea, api, remote, connection] +# #region GitServiceGiteaMixin [C:4] [TYPE Module] [SEMANTICS git, gitea, api, remote, connection, http_pool] # @LAYER: Infra -# @BRIEF Gitea API operations for GitService — connection testing, repository CRUD, and pull request creation. +# @BRIEF Gitea API operations for GitService — connection testing, repository CRUD, and pull request creation. Uses shared self._http_client for connection pooling. # @RELATION USED_BY -> [GitService] from typing import Any @@ -35,24 +35,23 @@ class GitServiceGiteaMixin: return False pat = pat.strip() try: - async with httpx.AsyncClient() as client: - if provider == GitProvider.GITHUB: - headers = {"Authorization": f"token {pat}"} - api_url = "https://api.github.com/user" if "github.com" in url else f"{url.rstrip('/')}/api/v3/user" - resp = await client.get(api_url, headers=headers) - elif provider == GitProvider.GITLAB: - headers = {"PRIVATE-TOKEN": pat} - api_url = f"{url.rstrip('/')}/api/v4/user" - resp = await client.get(api_url, headers=headers) - elif provider == GitProvider.GITEA: - headers = {"Authorization": f"token {pat}"} - api_url = f"{url.rstrip('/')}/api/v1/user" - resp = await client.get(api_url, headers=headers) - else: - return False - if resp.status_code != 200: - logger.error(f"[test_connection][Coherence:Failed] Git connection test failed for {provider} at {api_url}. Status: {resp.status_code}") - return resp.status_code == 200 + if provider == GitProvider.GITHUB: + headers = {"Authorization": f"token {pat}"} + api_url = "https://api.github.com/user" if "github.com" in url else f"{url.rstrip('/')}/api/v3/user" + resp = await self._http_client.get(api_url, headers=headers) + elif provider == GitProvider.GITLAB: + headers = {"PRIVATE-TOKEN": pat} + api_url = f"{url.rstrip('/')}/api/v4/user" + resp = await self._http_client.get(api_url, headers=headers) + elif provider == GitProvider.GITEA: + headers = {"Authorization": f"token {pat}"} + api_url = f"{url.rstrip('/')}/api/v1/user" + resp = await self._http_client.get(api_url, headers=headers) + else: + return False + if resp.status_code != 200: + logger.error(f"[test_connection][Coherence:Failed] Git connection test failed for {provider} at {api_url}. Status: {resp.status_code}") + return resp.status_code == 200 except Exception as e: logger.error(f"[test_connection][Coherence:Failed] Error testing git connection: {e}") return False @@ -87,8 +86,7 @@ class GitServiceGiteaMixin: url = f"{base_url}/api/v1{endpoint}" headers = self._gitea_headers(pat) try: - async with httpx.AsyncClient(timeout=20.0) as client: - response = await client.request(method=method, url=url, headers=headers, json=payload) + response = await self._http_client.request(method=method, url=url, headers=headers, json=payload) except Exception as e: logger.error(f"[gitea_request][Coherence:Failed] Network error: {e}") raise HTTPException(status_code=503, detail=f"Gitea API is unavailable: {e!s}") diff --git a/backend/src/services/git/_merge.py b/backend/src/services/git/_merge.py index 00b4cef6..3e1b6ec1 100644 --- a/backend/src/services/git/_merge.py +++ b/backend/src/services/git/_merge.py @@ -1,6 +1,6 @@ -# #region GitServiceMergeMixin [C:3] [TYPE Module] [SEMANTICS git, merge, branch, conflict, resolution] +# #region GitServiceMergeMixin [C:4] [TYPE Module] [SEMANTICS git, merge, branch, conflict, resolution, lock] # @LAYER: Infra -# @BRIEF Merge operations for GitService — conflict detection, resolution, abort, continue, and direct promote. +# @BRIEF Merge operations for GitService — conflict detection, resolution, abort, continue, and direct promote (all concurrent-safe via per-dashboard locks). # @RELATION USED_BY -> [GitService] import os @@ -87,11 +87,12 @@ class GitServiceMergeMixin: } # endregion _build_unfinished_merge_payload - # region get_merge_status [TYPE Function] - # @PURPOSE: Get current merge status for a dashboard repository. + # region get_merge_status [C:4] [TYPE Function] [SEMANTICS git,merge,status,lock] + # @PURPOSE: Get current merge status for a dashboard repository (concurrent-safe). def get_merge_status(self, dashboard_id: int) -> dict[str, Any]: - with belief_scope("GitService.get_merge_status"): - repo = self.get_repo(dashboard_id) + with self._locked(dashboard_id): + with belief_scope("GitService.get_merge_status"): + repo = self.get_repo(dashboard_id) merge_head_path = os.path.join(repo.git_dir, "MERGE_HEAD") if not os.path.exists(merge_head_path): current_branch = "unknown" @@ -120,11 +121,12 @@ class GitServiceMergeMixin: } # endregion get_merge_status - # region get_merge_conflicts [TYPE Function] - # @PURPOSE: List all files with conflicts and their contents. + # region get_merge_conflicts [C:4] [TYPE Function] [SEMANTICS git,conflict,list,lock] + # @PURPOSE: List all files with conflicts and their contents (concurrent-safe). def get_merge_conflicts(self, dashboard_id: int) -> list[dict[str, Any]]: - with belief_scope("GitService.get_merge_conflicts"): - repo = self.get_repo(dashboard_id) + with self._locked(dashboard_id): + with belief_scope("GitService.get_merge_conflicts"): + repo = self.get_repo(dashboard_id) conflicts = [] unmerged = repo.index.unmerged_blobs() for file_path, stages in unmerged.items(): @@ -143,11 +145,12 @@ class GitServiceMergeMixin: return sorted(conflicts, key=lambda item: item["file_path"]) # endregion get_merge_conflicts - # region resolve_merge_conflicts [TYPE Function] - # @PURPOSE: Resolve conflicts using specified strategy. + # region resolve_merge_conflicts [C:4] [TYPE Function] [SEMANTICS git,conflict,resolve,lock] + # @PURPOSE: Resolve conflicts using specified strategy (concurrent-safe). def resolve_merge_conflicts(self, dashboard_id: int, resolutions: list[dict[str, Any]]) -> list[str]: - with belief_scope("GitService.resolve_merge_conflicts"): - repo = self.get_repo(dashboard_id) + with self._locked(dashboard_id): + with belief_scope("GitService.resolve_merge_conflicts"): + repo = self.get_repo(dashboard_id) resolved_files: list[str] = [] repo_root = os.path.abspath(str(repo.working_tree_dir or "")) if not repo_root: @@ -176,11 +179,12 @@ class GitServiceMergeMixin: return resolved_files # endregion resolve_merge_conflicts - # region abort_merge [TYPE Function] - # @PURPOSE: Abort ongoing merge. + # region abort_merge [C:4] [TYPE Function] [SEMANTICS git,merge,abort,lock] + # @PURPOSE: Abort ongoing merge (concurrent-safe). def abort_merge(self, dashboard_id: int) -> dict[str, Any]: - with belief_scope("GitService.abort_merge"): - repo = self.get_repo(dashboard_id) + with self._locked(dashboard_id): + with belief_scope("GitService.abort_merge"): + repo = self.get_repo(dashboard_id) try: repo.git.merge("--abort") except GitCommandError as e: @@ -192,11 +196,12 @@ class GitServiceMergeMixin: return {"status": "aborted"} # endregion abort_merge - # region continue_merge [TYPE Function] - # @PURPOSE: Finalize merge after conflict resolution. + # region continue_merge [C:4] [TYPE Function] [SEMANTICS git,merge,continue,lock] + # @PURPOSE: Finalize merge after conflict resolution (concurrent-safe). def continue_merge(self, dashboard_id: int, message: str | None = None) -> dict[str, Any]: - with belief_scope("GitService.continue_merge"): - repo = self.get_repo(dashboard_id) + with self._locked(dashboard_id): + with belief_scope("GitService.continue_merge"): + repo = self.get_repo(dashboard_id) unmerged_files = self._get_unmerged_file_paths(repo) if unmerged_files: raise HTTPException( @@ -227,51 +232,69 @@ class GitServiceMergeMixin: return {"status": "committed", "commit_hash": commit_hash} # endregion continue_merge - # region promote_direct_merge [TYPE Function] - # @PURPOSE: Perform direct merge between branches in local repo and push target branch. + # region promote_direct_merge [C:4] [TYPE Function] [SEMANTICS git,merge,promote,branch,isolation] + # @PURPOSE: Perform direct merge between branches with branch isolation — original branch restored on error. # @PRE: Repository exists and both branches are valid. - # @POST: Target branch contains merged changes from source branch. + # @POST: Target branch contains merged changes from source branch. Active branch restored to original. + # Merge survives locally even if push fails (partial success). + # @SIDE_EFFECT: Changes local branch state during merge; restores original branch in finally block. # @RETURN: Dict[str, Any] def promote_direct_merge(self, dashboard_id: int, from_branch: str, to_branch: str) -> dict[str, Any]: - with belief_scope("GitService.promote_direct_merge"): - if not from_branch or not to_branch: - raise HTTPException(status_code=400, detail="from_branch and to_branch are required") - repo = self.get_repo(dashboard_id) - source = from_branch.strip() - target = to_branch.strip() - if source == target: - raise HTTPException(status_code=400, detail="from_branch and to_branch must be different") - try: - origin = repo.remote(name="origin") - except ValueError: - raise HTTPException(status_code=400, detail="Remote 'origin' not configured") - try: - origin.fetch() - if source not in [head.name for head in repo.heads]: - if f"origin/{source}" in [ref.name for ref in repo.refs]: - repo.git.checkout("-b", source, f"origin/{source}") - else: - raise HTTPException(status_code=404, detail=f"Source branch '{source}' not found") - if target in [head.name for head in repo.heads]: - repo.git.checkout(target) - elif f"origin/{target}" in [ref.name for ref in repo.refs]: - repo.git.checkout("-b", target, f"origin/{target}") - else: - raise HTTPException(status_code=404, detail=f"Target branch '{target}' not found") + with self._locked(dashboard_id): + with belief_scope("GitService.promote_direct_merge"): + if not from_branch or not to_branch: + raise HTTPException(status_code=400, detail="from_branch and to_branch are required") + repo = self.get_repo(dashboard_id) + source = from_branch.strip() + target = to_branch.strip() + if source == target: + raise HTTPException(status_code=400, detail="from_branch and to_branch must be different") try: - origin.pull(target) + origin = repo.remote(name="origin") + except ValueError: + raise HTTPException(status_code=400, detail="Remote 'origin' not configured") + + # Remember original branch for restoration in finally + original_branch = None + try: + original_branch = repo.active_branch.name except Exception: - pass - repo.git.merge(source, "--no-ff", "-m", f"chore(flow): promote {source} -> {target}") - origin.push(refspec=f"{target}:{target}") - except HTTPException: - raise - except Exception as e: - message = str(e) - if "CONFLICT" in message.upper(): - raise HTTPException(status_code=409, detail=f"Merge conflict during direct promote: {message}") - raise HTTPException(status_code=500, detail=f"Direct promote failed: {message}") - return {"mode": "direct", "from_branch": source, "to_branch": target, "status": "merged"} + original_branch = None + + try: + origin.fetch() + if source not in [head.name for head in repo.heads]: + if f"origin/{source}" in [ref.name for ref in repo.refs]: + repo.git.checkout("-b", source, f"origin/{source}") + else: + raise HTTPException(status_code=404, detail=f"Source branch '{source}' not found") + if target in [head.name for head in repo.heads]: + repo.git.checkout(target) + elif f"origin/{target}" in [ref.name for ref in repo.refs]: + repo.git.checkout("-b", target, f"origin/{target}") + else: + raise HTTPException(status_code=404, detail=f"Target branch '{target}' not found") + try: + origin.pull(target) + except Exception: + pass + repo.git.merge(source, "--no-ff", "-m", f"chore(flow): promote {source} -> {target}") + origin.push(refspec=f"{target}:{target}") + except HTTPException: + raise + except Exception as e: + message = str(e) + if "CONFLICT" in message.upper(): + raise HTTPException(status_code=409, detail=f"Merge conflict during direct promote: {message}") + raise HTTPException(status_code=500, detail=f"Direct promote failed: {message}") + finally: + # Restore original branch even if merge/push partially failed + if original_branch: + try: + repo.git.checkout(original_branch) + except Exception: + pass + return {"mode": "direct", "from_branch": source, "to_branch": target, "status": "merged"} # endregion promote_direct_merge # #endregion GitServiceMergeMixin # #endregion GitServiceMergeMixin diff --git a/backend/src/services/git/_remote_providers.py b/backend/src/services/git/_remote_providers.py index 506322ef..687bf5cf 100644 --- a/backend/src/services/git/_remote_providers.py +++ b/backend/src/services/git/_remote_providers.py @@ -1,6 +1,6 @@ -# #region GitServiceRemoteMixin [C:3] [TYPE Module] [SEMANTICS git, provider, github, remote, url] +# #region GitServiceRemoteMixin [C:4] [TYPE Module] [SEMANTICS git, provider, github, remote, url, http_pool] # @LAYER: Infra -# @BRIEF GitHub and GitLab provider operations for GitService — repository creation and PR/MR creation. +# @BRIEF GitHub and GitLab provider operations for GitService — repository creation and PR/MR creation. Uses shared self._http_client for connection pooling. # @RELATION USED_BY -> [GitService] from typing import Any @@ -38,8 +38,7 @@ class GitServiceGithubMixin: if default_branch: payload["default_branch"] = default_branch try: - async with httpx.AsyncClient(timeout=20.0) as client: - response = await client.post(api_url, headers=headers, json=payload) + response = await self._http_client.post(api_url, headers=headers, json=payload) except Exception as e: raise HTTPException(status_code=503, detail=f"GitHub API is unavailable: {e!s}") if response.status_code >= 400: @@ -78,8 +77,7 @@ class GitServiceGithubMixin: "body": description or "", "draft": bool(draft), } try: - async with httpx.AsyncClient(timeout=20.0) as client: - response = await client.post(api_url, headers=headers, json=payload) + response = await self._http_client.post(api_url, headers=headers, json=payload) except Exception as e: raise HTTPException(status_code=503, detail=f"GitHub API is unavailable: {e!s}") if response.status_code >= 400: @@ -118,8 +116,7 @@ class GitServiceGitlabMixin: if default_branch: payload["default_branch"] = default_branch try: - async with httpx.AsyncClient(timeout=20.0) as client: - response = await client.post(api_url, headers=headers, json=payload) + response = await self._http_client.post(api_url, headers=headers, json=payload) except Exception as e: raise HTTPException(status_code=503, detail=f"GitLab API is unavailable: {e!s}") if response.status_code >= 400: @@ -162,8 +159,7 @@ class GitServiceGitlabMixin: "description": description or "", "remove_source_branch": bool(remove_source_branch), } try: - async with httpx.AsyncClient(timeout=20.0) as client: - response = await client.post(api_url, headers=headers, json=payload) + response = await self._http_client.post(api_url, headers=headers, json=payload) except Exception as e: raise HTTPException(status_code=503, detail=f"GitLab API is unavailable: {e!s}") if response.status_code >= 400: diff --git a/backend/src/services/git/_status.py b/backend/src/services/git/_status.py index d76c91ef..a3a1a378 100644 --- a/backend/src/services/git/_status.py +++ b/backend/src/services/git/_status.py @@ -1,6 +1,6 @@ -# #region GitServiceStatusMixin [C:3] [TYPE Module] [SEMANTICS git, status, diff, log, history] +# #region GitServiceStatusMixin [C:4] [TYPE Module] [SEMANTICS git, status, diff, log, history, lock] # @LAYER: Infra -# @BRIEF Status, diff, and commit history operations for GitService using git status --porcelain to avoid --cached flag issues. +# @BRIEF Status, diff, and commit history operations for GitService (all concurrent-safe via per-dashboard locks). # @RELATION USED_BY -> [GitService] from datetime import datetime @@ -50,14 +50,15 @@ class GitServiceStatusMixin: return staged, modified, untracked # endregion _parse_status_porcelain - # region get_status [TYPE Function] - # @PURPOSE: Get current repository status (dirty files, untracked, etc.) + # region get_status [C:4] [TYPE Function] [SEMANTICS git,status,lock] + # @PURPOSE: Get current repository status (concurrent-safe). # @PRE: Repository for dashboard_id exists. # @POST: Returns a dictionary representing the Git status. # @RETURN: dict def get_status(self, dashboard_id: int) -> dict: - with belief_scope("GitService.get_status"): - repo = self.get_repo(dashboard_id) + with self._locked(dashboard_id): + with belief_scope("GitService.get_status"): + repo = self.get_repo(dashboard_id) has_commits = False try: repo.head.commit @@ -110,16 +111,17 @@ class GitServiceStatusMixin: } # endregion get_status - # region get_diff [TYPE Function] - # @PURPOSE: Generate diff for a file or the whole repository. + # region get_diff [C:4] [TYPE Function] [SEMANTICS git,diff,lock] + # @PURPOSE: Generate diff for a file or the whole repository (concurrent-safe). # @PARAM: file_path (str) - Optional specific file. # @PARAM: staged (bool) - Whether to show staged changes. # @PRE: Repository for dashboard_id exists. # @POST: Returns the diff text as a string. # @RETURN: str def get_diff(self, dashboard_id: int, file_path: str = None, staged: bool = False) -> str: - with belief_scope("GitService.get_diff"): - repo = self.get_repo(dashboard_id) + with self._locked(dashboard_id): + with belief_scope("GitService.get_diff"): + repo = self.get_repo(dashboard_id) diff_args = [] if staged: diff_args.append("--staged") @@ -128,15 +130,16 @@ class GitServiceStatusMixin: return repo.git.diff(*diff_args) # endregion get_diff - # region get_commit_history [TYPE Function] - # @PURPOSE: Retrieve commit history for a repository. + # region get_commit_history [C:4] [TYPE Function] [SEMANTICS git,history,lock] + # @PURPOSE: Retrieve commit history for a repository (concurrent-safe). # @PARAM: limit (int) - Max number of commits to return. # @PRE: Repository for dashboard_id exists. # @POST: Returns a list of dictionaries for each commit in history. # @RETURN: List[dict] def get_commit_history(self, dashboard_id: int, limit: int = 50) -> list[dict]: - with belief_scope("GitService.get_commit_history"): - repo = self.get_repo(dashboard_id) + with self._locked(dashboard_id): + with belief_scope("GitService.get_commit_history"): + repo = self.get_repo(dashboard_id) commits = [] try: if not repo.heads and not repo.remotes: diff --git a/backend/src/services/git/_sync.py b/backend/src/services/git/_sync.py index 546c7923..d7d51979 100644 --- a/backend/src/services/git/_sync.py +++ b/backend/src/services/git/_sync.py @@ -1,6 +1,6 @@ -# #region GitServiceSyncMixin [C:3] [TYPE Module] [SEMANTICS git, sync, push, pull, remote] +# #region GitServiceSyncMixin [C:4] [TYPE Module] [SEMANTICS git, sync, push, pull, remote, lock] # @LAYER: Infra -# @BRIEF Push and pull operations for GitService with origin host auto-alignment. +# @BRIEF Push and pull operations for GitService with origin host auto-alignment (concurrent-safe). # @RELATION USED_BY -> [GitService] # @RELATION DEPENDS_ON -> [GitServiceUrlMixin] @@ -17,13 +17,14 @@ from src.models.git import GitRepository, GitServerConfig # #region GitServiceSyncMixin [C:3] [TYPE Class] # @BRIEF Mixin providing push and pull operations with origin host alignment. class GitServiceSyncMixin: - # region push_changes [TYPE Function] - # @PURPOSE: Push local commits to remote. + # region push_changes [C:4] [TYPE Function] [SEMANTICS git,push,lock] + # @PURPOSE: Push local commits to remote (concurrent-safe). # @PRE: Repository exists and has an 'origin' remote. # @POST: Local branch commits are pushed to origin. def push_changes(self, dashboard_id: int): - with belief_scope("GitService.push_changes"): - repo = self.get_repo(dashboard_id) + with self._locked(dashboard_id): + with belief_scope("GitService.push_changes"): + repo = self.get_repo(dashboard_id) if not repo.heads: logger.warning(f"[push_changes][Coherence:Failed] No local branches to push for dashboard {dashboard_id}") return @@ -110,13 +111,14 @@ class GitServiceSyncMixin: raise HTTPException(status_code=500, detail=f"Git push failed: {e!s}") # endregion push_changes - # region pull_changes [TYPE Function] - # @PURPOSE: Pull changes from remote. + # region pull_changes [C:4] [TYPE Function] [SEMANTICS git,pull,lock] + # @PURPOSE: Pull changes from remote (concurrent-safe). # @PRE: Repository exists and has an 'origin' remote. # @POST: Changes from origin are pulled and merged into the active branch. def pull_changes(self, dashboard_id: int): - with belief_scope("GitService.pull_changes"): - repo = self.get_repo(dashboard_id) + with self._locked(dashboard_id): + with belief_scope("GitService.pull_changes"): + repo = self.get_repo(dashboard_id) merge_head_path = os.path.join(repo.git_dir, "MERGE_HEAD") if os.path.exists(merge_head_path): payload = self._build_unfinished_merge_payload(repo) diff --git a/backend/tests/services/clean_release/test_report_audit_immutability.py b/backend/tests/services/clean_release/test_report_audit_immutability.py index 3af24024..9f7ef340 100644 --- a/backend/tests/services/clean_release/test_report_audit_immutability.py +++ b/backend/tests/services/clean_release/test_report_audit_immutability.py @@ -128,11 +128,17 @@ def test_audit_hooks_emit_append_only_event_stream(mock_logger): audit_check_run("run-immut-1", "PASSED") audit_report("CCR-immut-1", "cand-immut-1") - assert mock_logger.info.call_count == 3 - logged_messages = [call.args[0] for call in mock_logger.info.call_args_list] - assert logged_messages[0].startswith("[REASON]") - assert logged_messages[1].startswith("[REFLECT]") - assert logged_messages[2].startswith("[EXPLORE]") + assert mock_logger.reason.call_count == 1 + assert mock_logger.reflect.call_count == 1 + assert mock_logger.explore.call_count == 1 + + reason_msg = mock_logger.reason.call_args[0][0] + reflect_msg = mock_logger.reflect.call_args[0][0] + explore_msg = mock_logger.explore.call_args[0][0] + + assert reason_msg.startswith("clean-release preparation") + assert reflect_msg.startswith("clean-release check_run") + assert explore_msg.startswith("clean-release report_id") # [/DEF:test_audit_hooks_emit_append_only_event_stream:Function] diff --git a/docker-compose.yml b/docker-compose.yml index a0f6e976..de0030be 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -53,7 +53,7 @@ services: depends_on: - backend ports: - - "${FRONTEND_HOST_PORT:-8000}:80" + - "8100:80" volumes: postgres_data: diff --git a/e2e_final_dashboard.png b/e2e_final_dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..11e002d7b25e0e364abeb64fa22a5a31870a60df GIT binary patch literal 144978 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

--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 bvxBPl^uqX!lzwjT4V9XT_W6u+7We)ST{qDc literal 0 HcmV?d00001 diff --git a/e2e_profile_01.png b/e2e_profile_01.png new file mode 100644 index 0000000000000000000000000000000000000000..f95736765f2d75c53b96208ecc204197456f710d GIT binary patch literal 104921 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 literal 0 HcmV?d00001 diff --git a/e2e_settings_01_environments.png b/e2e_settings_01_environments.png new file mode 100644 index 0000000000000000000000000000000000000000..0f93057e8367a50d1c1f925941d5871c5199ded2 GIT binary patch literal 163726 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 literal 0 HcmV?d00001 diff --git a/e2e_settings_03_git.png b/e2e_settings_03_git.png new file mode 100644 index 0000000000000000000000000000000000000000..4b716ee6e2ee85c8396a0ec97667c4e814cc1f2a GIT binary patch literal 172288 zcmZ6yb6_RWvn?FkwkDd`m`rSEV%xUuOgs}zY~#eXZQHg_PVn-(@80))@BMlD?A~3q zyZ5fDRcl2lDM%tC5Fmhofgwvvi7A7DLEVCZL36@Ed|i2G9a;qgLj#i*6IS&EzsQ0X z!qUMVzP6ns%hQCTjtq*`TM5%EUD*uV6lf2bzC!VBn%>D1Xh+n+!p2H4_vv!6NI?-s z$Kg3YyvlN!uG*fsnhKbnpfkJ;f^tR#?*<4uk1IP8OM$_Yfl~%TC4gZFK}eBZW6-81 zMg;DB>x7z7T!!z7)?Y4(ycdP|e}<{R=N3<@X0D{A2tEDGE1o2|;-UM`{r}%&BLWbm zR`v1xaha=7&c(%(wg@Yv|IY|nD5d$MqRvpq& zfiFZ0#Q(AK>o@k-?Du2YLv9rRWxS9K)J*t)`|$NI62$&+yrNTnsg=q=u*Cnlj|?7s zL+rneOt6FU6dpg8rVdKyf=By5m%kRG#{r|~=zn{XkOqYzvl?pVkF?P66Luo;zt-r# zeXPp{i;MivBVXWy4k);ypgAuU;fy)|Zy#sCA$XuE6L8@v69G=R3^_LU65|Faeeqfi_KvAWffQHhcggN7myt=V8iXU?q{C?Gk1 zaw88ZG9CEPaLKOEm&3sd)cBn4-iHV{F#SLx9FnxE_8-$I*@QT8>0I0w;<}JukNhDe zRIMa2Jd#Y;s9iAId%ByHAXJPQD5_Vc+-n3-qGj)Nxj=(AMGTrY=#~^8)J)GvX3#Gb zS^e|x0}Z?fG2t6Ufgr3e&5IBOK23sJI@dmXKaLbxJ6tF|CrCidt(`;_s4FDQ9I#)I zgB1UQPyBA_`4BS8D%fvwjU3<2&GRuebDkBntP_Ii@Tk}^8gP^~e~7Ag?Yj#4&L9^C zLEY}2RUK0?Tk~s{tw_0u9<$GjEU1zySE)ST#PmkwWztA1S?2yE@%7H^akk*h55!_d z1HJ-X^Nobxc=2p|ql&kb7fw4-O0y+5xi&FKlX6U$ecDL{x&y3LD(_7sXa{j@ji~w4 z)v&L-)JiJ_IXcPj6a5kB^HS1NlSAzYX<-S0>}I&w#t)sT_k<1?^GmUVRD16_u-C&s z^Mk?%J1<75mca-=yhcoP&tEGVIwKEz!Q^IWe_eU}H?j)Z^4ga5oAq3qTS$0Q(X5Dg`JP!@>< zDuFlP2(1EP;gV?KST$_ZkMxUW(Avk%GnQ~+0G0W^(UYG+2D1%pVP`flJAU2=FZ7ibxp&*X(2)9u}meR+(<9TGwX zvqA}UfGUFJXsAD!fw;jE{nX7R!}(tK;qN!XGj&C|o=(&O{t}AJ{8cl@)98VEV0;kn z5xHvgPn&#`?H&R448*5ENz2fv#Jo5;YDM|}fdR0c<1(t_$U!>QgE`T`P)792qwu8+ zJY|1Nr7$DmN1CvfDP-vVLrDa)CjEZl=~eatbga|(8@!oXkvuR{##p0UnpdU#lDE+8 zC7bbwzcGjtYy`34TgpQiXw8Cs1$mgksFbKu{gOBrPU z95$rz9W`dJ)rHrqI3c=QVizlWcG=0K@c6kEVOjCw-^TQBYq!p7zpETLv4e;XP(@b>;wNrXPU2Y+%dZN>&|Fr$ShC};cs~$1L1RO6L|!b#Kw!LLKtXV%2ybz z?$lVq^^1T{0e1(oQY#(RQR|P#pq#_i1HmU4l6oNs-_kmji&A6;$c<)aAn{nq!S%=- zZ$uvqrYUv|!)WOzV4Wjp>ck2d**Dl}?0I*`oMCx#Y;q@}Gzs!z8C@g=js>^5Et|Jd zE#tq_pucpsmUE_WpM&Xq3)&C`>zbW9G1g4}-RVaNZ70!cRx6m?`1zjNeqE(jwqT6D zC7LlPi9?K1L$CG{f`ujC^x3=oXPs$)BO9ac(O0hFjb=V7#;6xLv-uMf5; zurQT%GS8-}(u$}^*C;`OF07$66be3sjCI)PG`>>G^XYGeS9bx zUdljQmLHx7*iiY1UWzXvKeU0`LKN67pK}S~J*U1wq`B4NZj~d2=M#gl!kDQ^=Qvj> zUHBQGaB-pDBIU2xI(#g-tS9+%4<)ac;OkJMCzh z{h@BDgXna%TxIc|E2^AU&mVs&BQdRmii=% z7|M{lR#;e&n7417-f$oi)$P2CQH7cwGX`$I??f<*{KtPHOJ+|ynAFP3i5Y$ZV1@U_zXU7UYG?= zD0t?S3SSk>rA)Lo;t5R3YmHbx#tFjM_u^E*_F9Tt_2nL&24&|z|D8x_CAU$K_HX3b zNGLWLG8PHHqY9)rCA547qE5#Z3@#&Hg}S>&c>cdhnBKuj*ricI{YqLDMpFSXNRc0d z++i`*aPR*WdU-Q?;zAWPWEA}ponSe^M-gDZBhG3hl!u0~`I*DX zVkEZ~XhVAG+V!z*%ap==A4jlM2qn-qUm&w7Fl^b*WZ{zhubjsp!kIUu+d1=NGt)2I zm3wr)t(VF1?d9M3a=kk<#$dl?)XnY6I-!W9=EstR1fgy;znk6YTYd&ZO{+#Rb z6lp1(zt29fSGMcEWLqDN0Hh7ALnBV&TNV9AAr1^8~qz|KP z5E&jsC#wN++|R$XxF}FU|C33L@Ig_;ktA<+1HPRnZ??nUlmB2N%nV0C1M{l8?-|wa zFXp^vL&CsvC;b5}LHtj9?)!w+Yj+rZGiBq)=%wAU2}zfV*%I9Ic4=<^_Jw@X7@+Z# z>IH(MKRso4YQxC79hE3`&_6=* z-78T@2u2jPte8w;KBb2K>E$%qhTHz$pIlG`l~hoz4hoqy#PcXNL6pa1?g7}Sr<>7u z&g(HdR(fK|BBI@9U0|nmjF@Vvi^~=7nH4^H*^Vlr#gr=AYM0uj6b^;S=lNg?05729 z;dVL~JUfYEHylX9h3lyfASy2$X7MAoG#qW1aGZXt9Xs40pQcV|C$l-#U^k4%Y*0cp zLu(*2Xw5{owhT=}JPg&4?e;@Gp zWP)Mh+)Rnm-GPtM>zy6)|IRG0{}9W^$B-H&agD6&Ux+yw~8CD2S1^WjX=g zg30rf(`Rntd%f=$9|rX!N#<-#=Z6 zN+`BJTnCf^k9pcb3GgUt=@b9DDPq&6|25}puKuv1bd)OanyUJJ*Y0!i0t^|Q2U=|Z z`6w5f(xaLpfd#fA)H+>#_x9a3&m#&m5ILjW(XDvUp8?iS?em==h9(!C= zbmZqBSY-jM`MA-i(=33dzlFv9s>owYXz|-$2S~ehS^Lv*%#n_de5V{O9)Ndg?w1P$ zF%{hQ-Fq&g$Tge)AqZ)ms#$n~ge9=XQy-NrZRx$N90d_69Jj0JIb z8#AJ5@&?akZ-+}1GGvf`sh?tQ6|(Kn5(0ro0^V;Q42aOjsZcC}&#(bL<=i?nE9P9P zod=72*@nXv^ibn}+piX##F-LE(-16GDU^IeqMgu)RH{3L;-sA~caIE#;*3^X!F|L6gG#J?b#sUD=i%rj0@6&Z=bu8ZLP-+Qe zSRJ{}W|r-3TJ`V!5g<=*Iuqj_rav-9y639?n$ScauF9~mpQq$(3jykr$NfR}Pu@t+ zEcHzu?!@)`=0Z!dGB(HdlcK{br^n~+Q(ZccI{d+?WH(ehpexamyEFn1H@hRHF%$)` z<_iG?9I1Ac4`lRaXB4Wo7A{V9&MmJU)17DAmg!pOu)5eY^={wCrwQ@%JjK<8RYB*(l}h6cUT7{_!&jI@0ro_1o#9fjwN|(o1pki9zSxPgJG~|l8&D!@sS4^ z`t44Vlo-KT+qSEf=vX9zUMRddQ@Sl3=KEYyqXBfl^=GmghmAVKpBe2O2{L3C5)=1n zoTVD~^Tzh(wp$ZXiyF$mRp=yzA=58{>DaK(b~mV4Py2!|jdB2N>hiNRN#loV*h0UAV= zC>Gpm%+ye*J6dq{s*jJSs*q^e<79f9$8%T=ZiOWYC>V@zs~=W>&fkE8MFCN)9w=>Nq0>7dwhPmBsFNi8bF5RE|gn!cJZ$< zW^$EhijJ0aIgmReo&v``u!&?D|NW>lKwVasKMP*}%1z0p_bAa=FvFj#_jOOV3UK{% zy6y@T3Hc0PTY`Ln@59q**JXyQiH{pf2c)86p z<8fD{0#)>rpTu$9R}j~f`1VKubn2&U&6FCtz%03bn&=SPx#)_RMZU9)9& z#OE<{h=d%tQ>iNb{(D)aS#AV}L~LZ?u2lknvqGaxy=X5=1^0=F$6BSqaXm#I8UlRa zSO2$@!O1{rN9HXyN%zC8Dv?Vj?i3~)K|*W@^5BC zU&rvEnwIvA!AxIH-fzf1=ZKC-E)IwcyMez*FfpIl-tOAsn`unqAvrmrS zx5KVqzpI}G)jFS+=vg{K8b?E5sESjkn3Y(`bjh`4T{xp+XV@UH(XFA#Z05;;JLvBe zL&Z{g{q0MWXV z7K`quQ0_XzZOA%Lc!F-dn;`9gt%&JsL2oYWz05H;?Pa?qvzt<@l4-r8%Y=R#muq2w z(Y|@p$@B9Mr?|DcziatR*e`BT5Ux8PTp9+~g0WS;PxDMT~ z1Vu{<5;&gcZ{453@y3j^k!NlIk%HrF9mN6W_RUTd{jozA2OM8r;+UI-e&C6z_7Qt(Vgv!oOx2CP7xawXkCo=qEHHlcz9&~cEccx2oyv*jjfsLtZ>BSpFHli8r}Y~ z){8%QoDV=c&7O)Qe$0An?3QRTi2Q*~P~(a!Wv`FIS?Z^AgLd=9B8OxAv7M)?(KcH;*Z0#z^>DjZKIv2vRak8ChuP|ww4A{3ONSvMA3o}ulH)HQI-4TpykzV| zkYtVk@x205`7+&h{wB1f`e*X}nqaW>^u$sbFhPyaoG*aKac5~!9QmT1IP$#^;gMv2 zqi3HQc?fpnfoOhXG(9N7%|-uh%(oNA&Bo9HhI+_qq!kRq+dfhyL_CuP#jmBjwQ3#> z045?pbaHfX1_a-lGx}Jtx4TA}5<5Cy-6+ez^$g4k_4eV>;kz}Nz3g~{rGcsOEfYg( z4GP-2Yu)##%xE`V!jn?c{NYoXosCsqsQkJZDU-#Y6P4>)9CzC7{1N)cUEGL`S-;cg zZtrpb7@*&kC#iUfF{nO~vBO%pa)Cbeb;p zgHKVz;5)C`OCxHD-wZ1MDa~8JL_Z!O!Nb{-|KeVnaIYW?@-rAZ=wuX;_U#3|>kg2{ z-_{TkY2!-|;|e)0gj-hf5APKsOnqmr(PX{!i6IPP_e}|2`ujg)y^NXYUT-kf^82=uo8Q?L~N7BNyz{M~UU2qb^K@ zNuh;86TbkmesZFSjKY(?6cCHmz3coEf#HkdS)*vG@htAML+`^wa_Nd=4a$5`gb2*#<3O zD6B?C&Ci$g%6THgMY0vHR}5%T**Sur&oTHIqWw53CE)>}CWjLxeLH`jcY=jFF@x^S zH(;)UFp}s!5*0t@-;wJFL1wwRF}y+oa&%!~vOyzP8V!waQ+@4+^|jxZJAi*RStkhh zom~hC(I(;*vqO0tGjEp>xZSVh*!WjETBG$hpKOS!EgyN!?<)hhs!4q=Rnh1nQ_mo- z{G{KnJR^sDrWx1#p5bZ2vI@f(#hCUPwXtV^ZalP#M>9jV`&)C6U4-dwSchtD_N{Go zZKLS$#JMkSd^>AbU9-#0BgUp&)86!)`(|ETl$rJ5+v#@-%RycTW?+z3RbQ2M(H}>? zi38;N=XYg;H2z9*Vh(_%aBTwpgY>@QBl!q41U%=%EKxp@Bl2+jM3!U^$B9?hO7K@R z?PNxPY_FC6JdlGN4I@G25u@~fewbfA{l=z;fPlb=gU_f?uadDGO|NtFA4iBQA{QpN zk&v6Fb$mTmYUA;&UTN{UcrYVuA`a&8KKrwn@f1{Ro3^(D7ABae@2gr=pfi-0URa~- zcKi2eQx?cq+aj9gsz;vKH8s!bPsfD6)PUq6f!f(?#hu;{Lm!%>8)Mwo!p|@AVtnn%&z86H_bA!yI&#*oM#rh7W8#K9phwI`CIo? zH2=TrDkR8xi`I~IdCemRf|27+r1FFJ-KF?{Okwg@OZDppMUkC}1HGEwxz33`ZZhuQ zZN2F!i(gxtD{{hwLUF_@g(d@ii)ytvcbyexL=>(3x0joW5GTIM9ld7D4Tqon)HADR7U9DeZ+q+PnOy46EP_+Ul zgN@)+*5s1>zP?vxzicUW%3nF#5L~zliGQP7khvCl`EI#%&4=b4$#kcw>x3^!J)dn(4gIHZ|Gz@ z3&DWa8jFOmhiQ8^+U2xgC!ZlQf~CE=RUg4Ef}$s^hRn@PyUpj@qT1=LrvYHvZfjis z{ID>!g2$;5`~W#%+MG|(Ylyrwe9Yv9ji`Uw-JP`9#s|_?e zFava38?2M_TD?9nsDysnES$X+$qe$|guNBXO8SCe?lQLJ{@^m`;Dm!E<_u)#P4dB_ z=xWwMiLA1qZKEO7z&n}v13Oq%oVkRVW0JGfhA7E^bk~tV`iJZ{i!b^h@5M#Zm2eGtsGDeUXRKD9892uxqs| z5>!2Y{s^8y16`>KkxmW9HY>q_P5ktEyVnxQda!Hp3IPthdB!Ngs|3eFK=oKP9_lu*+3@^kZp`PPzAKdDVQr+HOmsMA(UvhQT_)DxL&J$Y}$+{nbgy-&FnvVjILyuXjNa6 zjcculmnMiWEv4;Wxk)N38_jQ3G53yP9DQdNn317NmXHvyXqANsf4DX?wrz0UJaX3q zJzfZ6%+=JY^wPYKwgswn>+3;w`#CI>%Vtbn5&NJ7!zt!uX952?zJi3OiDUxh4@tCB zqBk(|Pt_J&wXLGP0Kw(29ehum9i5H0{oYh0ON_H!fupy~yHmK^Ox|~XGOKU=wsOLg z2&!Va3a+Sjx(7I+_5_i|F{EoP;QXkNT8McHaGvgGoELB6m!D$E68%^e=^W)MCFYBx zCa~A5b;@I#v|Y~$xYw$+ZY`AGY|W13`$zf1Lv^k#SEoL*&aYs%n9iSFasg5_eR(d1dO@QeuK^|jj>1e|ub(Go)jGV`Z7(_;#Arh0>; zaOwN;9p}hCMu%Y@V-AA$aeRGAeXbJSZYOl+IN#d!dQ-XR`qAGZB>mfE*P4;T-yxC; z!sPq{J1LZ-bGn8Y$CX>E!@kIW2#=blaB=-vIGFz^q7mRx%kp5my?`tXq<8D$pp6A} z$T~ox)fQ=jT}B<<)MMAcZq$B;Ogc5XLQ;UsK5iH?oWF| z{7Q8@o^5z zoAvwem4c3Ok4ylHbC8r&%iftNawlFS+&N=it8ev9xK+41a~}><^cw?Ox>VFpDQt8f z2k2jx!28*%I_3J?GI_>p^jVOoKE24d-%*xE|R%zY~~1xNKG54FkBY{a1OX)%cefv>Of z4N*p}JIkAP!K!aILzV@>B;~BIg zDs7MX=pU-}hN$itHW2kc{%;kF>1O91@|m3&a}(l(5Z%xqXIw%L`}KjPVzk0IJA(cR zUxUsFI!7>WsTnAOVE+2KXBJPd_d<3PLTNqO$wj_$GDp=iz?OPq{+#zi3~JN7%<1XR zswcsUg6mnqdui?IzEc4>?Q;1>wbxhg&UTNLCVy!GmA_x5G%_jo{9K>!dD|d=dkewI zdA}q?)O`eCAFoeK$~wOE1P`s+sqqURy;|n`ki2<(EK(XY@YgLh40`8V(kN5io&9^f z?63iRIb{d9^^(6^trh;NFNv$rF59bEzP?LK>pLpVd!O4T;&i!7dnfWKW~!QCFS7|gw0q3h#wVDpm5yt~NUt@rlRvRL$kaPoI^Giwto7UF_f zsd+=|Z#d2e679TjrRZ>@1uLgujhQCoXl}qeVrYI^8GOrD>$B%fY1w`;L*N}Vjbw!K zV!3MQkyFriMl)%Txu&P-weY^r6Dg#X`9(nW{j32f_B#)yB9}PAJpp!KN0tw&pi3{` zZpF)12+fQb1&+^zE|Q-}@W;1;lTU}IQy1+`kqV?D+%5-^7Cz{;2FrnQH_NRCCq2(Y zk>2M=oss!{NPB7JHAK0+Os$O5OUWvw@+eKkq#lD@8k}-7nX7UBt;(p^*N>{XIuU6V z_^9MkYiy1McBz#F4{Ga1x`*|6%d#@g4~%3Sc!5Jh2oxr!{;y2;(C{)CZ$pU35xg$d@}>AX5O_kZ^2vtD~HT}T#{N2<(u zBU|Mz88tHn4$`Ol1^;-frT)dIfK4|N)WvbcuV%se-;R$SyouVsV~TY7O)-L~VrS~m z(S0#l2C2(xT8aWkIBNx4F>I#KEclJr<31#?h?FWXLYhn3*#U}GWu={`mxOeno0(J| z-u3%-{ppwh1(r!un9_On`o>0-$ESw}l!Qbm)Kyr3IPAj)fBHJL6*PtCEU!*H>(r7o z9R|l#N`7PG<6?z|Y!WT_k0zYwKnUB{mlq+mCOK(bm_6e3<4>(G@?Q@EJNc5 zU94cV5uq()4xVxOsZ5i)tQoQbTPV^iHo zHrk%C7(Cms_(DSI7@m$ewDrIVxp368PPhI)jOVzh_%rhhN!4*zNZ~=&LW&xS(GU0p z#VPimK4)>$rwi8c*W0hVK>5h+JCrySv$(5GC>$vbW+Kpb`e29O-oHFUtF;!A?$yyo zY}=d_;LP#IqYLDw&y5D(edE7ldk9D0x&FU354qI0 zdnsrMd7)J4t$^T6jJL7dhCk|v`u?Be&ma!a8@Jx?W(Hf|I}tIjque+5~XE5GX2rk(-Q$-2WhB8@8?NW{j&W=SRZrAn>x-67sF4HBIWTz zgh%RY9Ifar5Pmn?*vq%8+hk&1$8A zM|kKDcikekD*L=UIT%h8;@3}N}E$h|Uum1t|3461{LM=ovRw?m!DF|3z11vBw6 zq%s1%YK^PRr!LyuFC*5QyE}`U9Rd$3xIJ%nOommRfzi>p!t^PnU(HGk$Pmg-prEJW zDd%eYxLJ7H-}@o*6V;i))=qG%dm1(fxb|=`GuGtowr;)nFgbzo zdjI)|A_w>?bHDm-T>%fY3%?&9#u_bePYy;)cMMk!=Huf@bFu^ty42|X*`-M?jy*m{ z5`WvRi>yYu)63Wt#APSR5hXd zJK+YGmAR{aLF4(OGHX+Blot@uh3YVtna-DnZft&SinHT)AHv{Y=e?xxG_btRO|~_V zYOAN=B~?FJ6#qfQRDP^&a_W!LjdbHkmT-A=mEF)J62B-3kLTwH9q zprSQwZEZm#7Jr*7Q5hdu7>yjvr>Y-fNaIgY9JGs0Vo(V9em}B}EBFfA0op-@#;b9S zGB%UJ+4mze;PETeOzK-++5y^(j;Y@K4X4gmKNO?pdi7b-?phO>p9c;-%0Vj}7NQ7( zp#SA~eEh8qP=2p3qp@c~W4TeJH*TfVHpi=mYfJ8m?HM%#r4#!rX%W z5yZ@o@7VK2{7D5P>Tpa7&W)YqR0`iuV%aEqL^@R)F!i>oXa#hCq1I2DLY}Z!8gbX0 zbhFh7w^54dZi<~cuPmO*;uTj^a?o@MfY5RLbQ`>&^ynoK6laa(tuUFQKdk+r$?PBL z4vyEmDzt&<&Qi|Mz9Godr}Bxv9`gAxO}@?8&cIVzY60Bcx{sIt6v7w4h^P^acDY8W zNH%>qOa{{_9QIs(;r-Qq65&p4a|0uA3}`%lp9?h7%@OWZA#_qVOW?eI!+|9R@=nTM zbPLZuf#BfN&umIhA`iEb2?aK~-miyZ6%}%-H<=G* z8+3=_{Jf7QVzc;q?gX>{&*~D>OaF3xzz+J^t*T1{QjthcOg-}sI#-F$Oz}4 z`P@E>X`Ho=ijh^uVie`aDo7*LkOpFHHSVmoKJVq#e3~OX&Cx^HCGnS`&R^Dgu1BL2 zql=ppK8yK~;0o1K50MM?9>n`^M()kz*;`%U;G`r1Z)h@=SrM-6_s$;AJdXFGJ+Rvm zUAInJ{Od>2KZg_4Hp7W_%xV}OX65&O_(ay@OTQ&RZ+Mq-n>MxkU08_iSrf0&X*bY9 znG0{Mt*v?c_=pO_QWxo{lp0k0)~oG%Chf-Ku)nI2MkE#R)0(Tc%pyqsIAN%ggR**d z(9+f3RNZ&s@Lg$p;h5K%P+T@gB2t#7_oS znqJp}z~BzbHS-ik^bW#CfSytNGv$N{Z^{quoz#~ot;tgZWFuEys?$|~v$3E(Rh>ET z-^8ewIs807d_L3IBDqHueEQz;wE8?w0xe(hZ@Z+*j*o9YKin8Rb}~59jEs(cM~q>> z93T6u+tXN5+vXtL`&L0cCCRY#VID6cESSy6H~}m_?s9k$@pev=n=-)GUFyQRHYg~^ z#Jb}5eBHXn#PTQS^e79k%{hLMNKX4Z2}&!Knp5C+Ux6e;h&J>m#gpVh-b4u&?udq&0aH^Ay(Ql5 z>Cn3dX*ZPL``zhP)^Sdx*J<$DwvTd!8e3YP=;_AvK8u=XWO5bv4nO{+ zgOM+Aruf9<_+sO$VUqLt?qIRqb?vZu)@4sjS}|czu6ljBP8A+L{PU-wr6+0xnC)+V z(}k6DeJ$KusWhXvt^w5#RGe_P;99GLknQh_xC*Jq|g5~AL zW==t3G7!5;{+K-SpKRls{%%O{wUApzz&SE{` zk|R-^to=uNK^yiG^6dJo4*s7V0)fJcfPByeD{_Nh5IIxYB3|9drZls?4lZJ@iSUw0 za4^#pGw2A)ff_9X8xE=hM~+~nLUdYzkzCm5@GS~WHFI;Db$#fp)ejATCLK- zA$^kYQZN%4lquvm+d~vH=E?6JNO)5|a2~eZmZH{hzMrctnItVpY4>Lt^NY>Hkp1ge zEL|$y0}FFNT>kg22kC@}g2Tln_sM92EHBd4ogUC)vj`L&S~Ub(1N?PfQ83O$=779O zl?lx>V7~Ca%;E?d>qcQv$FflqvkH?-U=ywfaaFM9$ytj zNhiYbeC*~^@;M6T)?`Z}o7$-6d>22=@F01(5PW(WMI2wY#sA^{!xiG!UdklFT(Ih$ z3aMj#U9RwEd`{Pdb`3_#-zSJ(L7%?^9b){)7(j|Q`;E3^mvf+`v0kS-Zw3!MJr>@2 zasz7t9slT0D)pi>4SI8oQx8IdkLQys_HIC86o3OKJ;}AMInw|0#jh~kl0zn0q>9{n zEmpbUmm~CwlxDcRoRm-r97oO%x3Mg~`fPqewYUzyA>D=ws zmJ;X1KongTUkGa>)EVvuo!d#mMz7i1%k1&=@am(S9JOvIf=GIEV5MERCAu6&x?;df z&E!VwPR|!D$A125JAzJXzgpMor}@OSfg92$wH(^ZSHxqs!R9{LW&rL`z%U74caKm!eE92+vQazvJ)_Dk&i!}#BOo_zqwJa?NlCo9 znvX!U^`tIW)XhZ}f&-xbN%5&Q)`?79FP~w%+o`rc>#M86J?a|f1%&rAmK^sQw&5!m z70v$2Q7tBfsZEoFLczhB40nF-B;`1j8xZyZ#$9gXRGps`yR;Z8P8E9-?R<9;tnia! z=!HL@lvO%12ZBDxgECL?`ey4@zPCNkLJRbo2Wu_1%$4k1hKK z`(rwQ>D}tESO;!qrvkHEF0LV(ZAp$FcSbuvW`~euB;2T?;FQ0BTji8`7w1$IFcV6} zjn7B#;ZNC~SxgI!%1ww-mve#0jbNGqB*Mi4XH`YTA7*bXHKE~QsDyk486a9E+{FosxOK{OlTgtFs9>_gPB%AIwqs0wyh@bbdQihkuoWdxAjU(+9oJYyP@xX+ooBF zJ{YnvTTf4%f*i{*=!?xDa+!9oVaQ%!wKib1SfL)OPF6E4m)$<(BB^wPdg9ev2~Tx# zGD)M9Op>ELrPhNv7uP9i@X{syMO}E3{A*NOewnVu@aKfjZ63OGBRRv^>&QIN{f7fjM>DX7(gi2 z9Qhn;cKOLrvqqsl{85$wp6Vz$o#S*P*HZuUT{vkkl5qVoLS?qW+8ig$k^a99KqACN+F-$^U+hF=M$> zbndR-{a7O-9w zK6hwacO9pi&Yt0)l!NZZH*04U^@@%tE$`z*p<)f+UDZLMy8o zt^#IwFs{vq2xB*qB9xYw;kaaDWDTY_i~J@Eu__}(7YZ=paJ=c$U`ptpMfB25n0Rr6Mk_`B;|ahGj44HsIVr?WyM)#SE5p zEmbm1@@p`csuk3I5d;kJ@J=+G=$4B_E8ND9ZFM>0japKX$+L8IE;ifB(`5NSx_iKn zt<~rj04fE+1^f*%|NeuCciG~1^QAr})k zU##A06&(}ghWPLe7G7_*8iO_IH8!?|%FqXW4u7U#Yi3rc1y62m@+CDg!@HQ^6+4R$ z&x&qB$GGnn$*$RHgHr7-d^jd*q{wY7|IM0O8rB4?r&Hbk4E$G{NbU+}sz9=~*6R1> z7IJ!fx>a_WX=Spj6Vexkki=y6JP&Q|ntc-gA5u3Mgag1}d$sv`GXyp-Gx_@+$OG^B zB6$1t_H8?@W~Oh?Bi+J#-8L(J;yJK_v%rD-An(3hZPOOhFCgudeo~9r{Lpqc6E^%W zJ%&LgRPlf`Q^~GBx<`oeUbPkUE_!%tpJS%O9K(L)eHWV;__D)nc@oQMwk0x)+feo-ju59n#JciH57IxyYzrJGl`P1R6 zh5Gt>>kt=vzWn-p0d9!`Z+^n+PrJ=BNW{V3A{;D&0sGH%Ij$;bWq$oQum2FSBq(93 zG+vXz`Fiy>zy{~dEZ_J!fZ#)l3}%5KZZuxQ7<+0AF1b2E7NpeDkR60Y@y+O-!JJs7Rl=|aqV9H z8?IWOz){%C_hv3oR~1CL$i8H7LHL7cbLs|{u%ulppZ&Q*vVanuz3}ei(+tl>ev}7(sJc|Gv~iQ zU;a3P{f|pOgnDKM#k&=ViT}Z61sm-Tv5;!_b$7_;T9l+%pjHcdSc($B6Sa9*=J91N zF=p2}e+*P+PXBXSburojhr;S#c5aJ6>jM#@gCi2BN2tWGTc`!gaDU7@@b=AG# z7B$SE^s*zcy)<{^Z$={jB?}Hxg_kO-luNN@R6juiZ_9YtyJnIWV6L#5k9?W_pp&~3 z{;Pur30a|4|7U$R`0Km=4Hff{Hd!E#crXr?sJS2mriXuKHVE%XEypcRWGMzw3+4LS z8k1NUl}sKa#Yki6rGghZZVS+7yuCA1r^Z7c3Y(qJCRzH@b0<)MgDCpOqbKN- zUj`H87-4UL&_`UrdIc-{%DvFDswUL)z=hg2IJr7- zG?yZ?fq&~84{~y)WY#ym=5yBzwi^_;tr=Dxh!w07-LPgJP z#`!>DO8$k@@7>`r;Rc>SgCn)33yGq&`DtfxlvSaM_6T`lIc@1QDdpN+S9m#)?)-KO z4^&FnO@;i1#WppS&gbE3j?R;a1!rl$ZEn46&ej#6aw4lCPm!p!CCZ5ZKUhGS^6A-y z^L++gEkRw7^-*@*T5FHK&cBD{?bx~P*o*8E{paa^t1}(41SPdEjH^0SdQ`CkM zXM!{vV4(wfLKOZoU(xg777?f!lQYm(&&~D&^I_T)qWj4iZDoyZ@OO~)*ukoyN17Oz zJF-egORi?E+?k?e`|R@HF;fKMEZypC^%%M85}MIP*$Ja)_5~AaceakswKIF5njwW&bpfF?m)Zds>`AN2}Cuz7DL_x}OUTtHH#ui;NJtyy6tU=xqvY9)CB` z8bZx#CjcNgv8&gJ#2CcPtWf?JS63ZS)$(=WN`s_ymvom%U%I=yyGv5KBrZrxigcHR zbW3-qAR(!Ae@A`#-tYSl?zv~~o_%Ka>@$0{1oL}JQ)PDocR@pvsr<_(POpDb>x)wY=oe#B1_MwXZG@KZ4rBd2L$p_}C^3soFl-Fd?!ay7N&aE*D0w&t47ymdHG{1r&t^#9rN?j6r**IP_!dnA5Zyqrvb8bou5M#tNyEo@?GXs*_W-yci=*!wC3+S$Z zAZGmtsUH8Eo|~(H#KG!4Gv-uYpL6;H1USLDX7^zIJcj;-?2Pc@YI5HQcwgk}x4}kh z(ultII4JY-^3e$z>)e=9Z=q}!Ilmj38&E(U=Yn&U7;)xmxQTRE?Q|(ikt<+H&*%^M zss>KU#j|2*f4p+r2;W3nd#ANqA(^W?g|wQXeR4yzZ;M>^cwgF)cCEoDz=(s&w!bns z@Y#U$Wne{4cS{f2TzW)6U>gbTlGyWQVUSl?fEHs=O2;t^?z6-yUoYeCu&!9*PyuhF zK?M-;%Z^y|M3%?!~Ioyg_@$F+zC7_WEhK)I+b^2lVaVL)7&k(c2_={w3!jR$5h z>#ra(y*D>1l%jsXYw+Ap^#=N+4&&^D`~WyANHAh*I^M#{ihp$*+jApY(De+W>C z17O&L1J+fI@Sd+w2l&uX!mw{*2m1ZG03`o^+JU@9K#0O&?FE1>PXa*&yn9LEuHygi zH^?{;*6aJzL@;gv#^M{OQJnwP1KGj>BtKk-vU=Qs#!qMvjI#g7nr3+@u5yQC(hTCC zKT1}J-r@CI8swJ|WPAvKU@v35};-|D9&;zD$F;%6u$rCxjRAV1877uUg+x7 ztYJ$jH^54CX17^uP>wY$C{T%Z_(uu}>Ms$Jzm9G|T>r)q36(L741=#)jDI?7EfW0p z|LeCv0j?#cfhs}}mxpZ|Ci5I|_sp0dCeC4&Fo=kUwGns8ts9c)zC=6&(~ z+r7UsGQ9D?)r`hDr_lvzsQzC9F8}G4uqWW{nM}Vx4iQjO3{=JcYyZv~c+QWU#s{Q7 zfA_={v>W)Z2Z0Z40o9lX0v@~2-=8jsLP`E-Bng9oyRjxa*#CKwKP3$`flLkR=l^6Z z=vPeggvAu3@8>0jI0XaKU$ieOpo;`V}Ryr4NN*l^K}w7DgUQIm>;D6rQkumdq% zfQjab9z0XPu4!r1mmwfWrN^F+}VaSg`S)mnf4wo zIuqK|w&U4mLX4oPX~(mf!r}-)RlEceRjD|-0cu+TxP;J<2`pB2Y%h!wFRacQUR?4~ zel&D|hKb>#?o_ApncZ8ZIxVs-DNO|0mGU1e7KXJ96&2r81VOB@i4L8HcLFuJnK1wc zxFLCf{jXj&O9-DJV?`;&FRgJ=fQPA~WkyOkVK9vm9uEbR3Z2a%Eg_5ARXxeZVkc@? z6spziTo}j^DxwbX))a|K!H9^vM9^s}=b{BTQDVs!Vb8-<1R|xVp0T3jxnlJqk_Q@6 zcd()m%{bW+5=t=+qpVw@#TT0+%~W25AO3c70A|O}@l+Eg9L80iPJK+tiS7n_h!n{h z9hR?}&)e;UgI;Z9tVM6aiyTOl(E;wr{+dB%S}eprWmO&@;e{n~O9n{HG>eg`6huR8 zhojF?&U%_TSu&6@uYzILt;Q_NaC67S29;+YL`LWTk=yCP=m23}5rY7%v?GO#16>IDG^A zy)KH2hbsVGI(r6Hh}VJ%z_gi-QR#Ey7Ji!%61P?JjLjOpg9|4c?Hp1^5N`$1ygXtPsk zyofe17lJC-oatR13J9B%X{bg?b|}O5D`N$0)v(wlI!?89l%b%1l|y}&!oUhC15s0`|Ox*L=B0$!@XPYmzdn~nOM zS*uBpZk<0a2KsJ>3wT&3Exm}mVi1$w1d(5vTxO{HeIhzYSr3Pbxg6G+aOcSvZV~*p zvpB5Qahwq5I;v>!h{OgQYPXpjXZ!5?v$}a4 zRvy1o%HdiTpSpq^gdO{jM1@^0?yzOdOWOIySfjJVU>rwJn#ZrrH(>sXJ_WW&kpU7B zy_gR}-s8C;Q7Qw%jhG;Fuok31t)WjBp*{eSaXe`IJ5E<$N^ZhM2fa2(6msC-^7_&L z+jKFLPF<1yr;B{qlp3FxFZ{XDA;p}S&V2^NX#%nbEU+NO?Dn#$#_n(DOPqIn%1F#s zgLu$nO*SjDVI$3;rD+`*F)*)hW||Jy;$MTHsUYPr?EbT;Y+Cdp zQpRd?02)|UmjASo-AX(8rbkAv0%bxUmZQRCV{|TzV zli~?Pv0Y3&%7vvy0%0e2)oCAn<+P8Rs#{4aICf5N{xn%9kW_eB!EUOUwD+lWbY9i{ z=18IRAr`l;WfztXxh9#sr7YB7GW+20FbyV-+kWvwyM0vFTALqXuRxZdU$fl;d&Ddb zoeGt>BImXVu=tU8#wWd*OT|j@xIOCTBK)}1leRyZp_++Y1#AA!q(0#BWx_2thd4av ze^UTLL^G|aF1-!6Y*us+Sh}GdlmTTN#*lkFBDO~5Q2G0Jca_=5-H^_h!N*F&w=ws6 z{I^^S<74K+-BF~$-G~udFL;99Qi0GGla-Lo7JVF~n@Mfzn_oXZXf{fAhdrHIVOH-y zTxxiio<91HheaK&Yyc1+f_nH`U!wJcJE)cP{WXu$>DXK%mRjJG#=uh+w8TP!BfeMQ z;1r_AYJF6@20I~$$z}Vgj#PCwkx7sBzqa!R1F@8;NEzgk_)Qy<6B5JVie0sfc|B6H zh+U-7LYDXjD3SM82+w?hwRX@PA032=R>M@qK-L#VV}xdtTl(<>?;8ii#Kc4D~)lg|r)i#XzieZRN}lQ%Rpq&58H!BpXUd8AKk*yfA> z@?fF1u&K%G?Q?ll5`F{;LH$YA7NO=3$W}Qf2LT7FllZyFV&e^o! z#n$s^;%qs5UDbl3NV04aO3Pvn&d*KzBQY|mH!Pf{lOq=jgpN#^Ms{Qh zoCBq&h>Ud^FTg{SND50}@>aSRFXnqfzHL!G6;2t=61eS&#L5v`Sy>^Eeb+-?FOQx9 z5Upx!Y8D%vDH#iO8ys5D?{Cg+Yb{1r+x$M+%+MDR^S?T2^SjN#8n2^K%*uG-{AF*d zP&S2GzhmG*G$tcWC8ZW0r3C#4p;rY3 zxbs+GLrO#!?>bSYQnLspv8Z$;1Mw2#*I5 zzCea4Zq66bs3`Lz(KR)Lg8Ho&aL&=yY^yvW$4W=LK zp+*s%yhlJn3d*s1xVwJaP*q)>#_#0Es?hv7jCL;D1!<}7SUF%li{2E7t z+Ovxh{Ae?@*2J2D+A=U*loYD${Y%5ca%UeBt`4)4Iu@pZ8%beUh=Jk)gCV&UzM@f1BuQF(RkHen7=&tnR}qGpJ9ss)4^_Q ze)34ly0fk9xBX<1)@W3jafOQ6L50D=Pqw5nBNTCQaS@7Ss1h_Q4MM}ho;yp~V^Nfv zRHs(XOicm%h}*Z9oSbgA7l%6aHs4ctI8dfa)Jym0DjA+3t#U9suC)p5YCW)9u!7xE z96?{HiY4Pn#uf8rk_r^FQ75*k>b=ac+z!fp6m8V#&=8TT(xz}9sMG6bErl0UoRPYc zZUs2)@n+mdBQmIy;fCj|zR3!lux!GRozX}7eJ^OQSEC3F+q)byP?VK* zU6WkRmswN?w4lChBsKDs9%N$2{uAsMDaB%zu%-7g^&YlTvSm(f2!xb>Xqoy*QLlYm|428WeoM(rAl5dy2EIZRru@#-9lA>PCQ7}$9j)7WkF z5;8c72W;qmZs-jegpqZqaGGRvdxf~`EB2X2l=vt_PMTtVxachHdgYWxPWROkHKNlB z{I-yr`rg8cD%t+oT<9_S#5b?sT2JS2Ymq(HSNqqhD=7`MYdWqrd3@_CZZ)78>%N_I z^oSVwvqEpNff|>WrGb2W2sF|c1e0(1#p#QJ;&dmtXguGXwKt_0P0BD?$108VDPxF^ z7FZZlRAC87DH2xULqvfHu>^z?Diy3nc&9kvFK(OZB9UOYf`S4gIm;4&X$@oKwG$D6 z;OKY^sE~CQo$BDCG+$3rB^G0+^Jo)KR!IMq@kf1P|V^-bS>4aBuRWrV}&~P z4w$DvbL`7)W>Q`m3B=sfC8 zPmv<*M>Bb$yWZV3C`d1>*rxW#OLD`eL3jI$SIl|DgvO_?4(FfME5;BAIs-gZk(%|pF z+GiBv|7EZW(faCS1C4|~RltXvRz*{DZeU;l@OPl!RunY3Wwf1TjZbb5KOe(7I1`0iuHxs=T_ zeXUOEAJc05s4!$;RCzRM-%*sd77Xq<1<76LgPG{^g%WCX)0m&CkJN5{>69AG~f z)@d>?H=b6FRTaDIUWAoo1wX&{yd^)r8}iaJ8-6=yNMX9wzAV}m1~x`Iw$Mo4R;N#L z9ItcjzNz=H*RHp`P2Ymoih7E5k)g9NIQeCBUl;wOpYKj~K5}8Nez%>4O^sRS^pd6` z7<*t399otOp$hCE;V!z&Tf*&lc<6l%?@{h)t;XY!V|hj{hd2R<7G zO&Q?HDt2zD@ds+bDkB9Yo^&N`D~)8=O=Zl2Q!*k#Ev2SG%;QhUm9|H3tR+I3)gJl1 zUcD;QYr?#PLnB#cy>R|Ih>cJU-qK*iaa?JhnVV~H-s}UW4nQbm&}KK_`>AQDb9S^s zm>!46Mp1$C4w8|XDIg$_d-~CSsm&-ZnjcmbQP)n!i}v zd2p~Dg$WT0%z> z`un$)8|tY}|HFeL6LI82Uf-yO!ekyty`9ng;76h*y>b`chnJQy617Ix1ps)&P@oq1 zrn-g`?K<~9=y|<@zYP!9BoEu9&(}*P`saJ)dqVcNs_+=COe4(m6*a!%_dW*m^RtTzEd+cLGZqOV8*y zJvT~7g}|18%u9}=Cy<7Dz&v~T(Q$9J6!}@gho_~uiOkk>xl0`l$9GpHb@yJR|JC}1 zK?{`6t5>gpP~FMFJd)0}4_s7o2S`H2YJ*F-%z6mP zA&5QPYS_$rcm*(`MKdQ`g37*iwxDmx9) zE`5i?eyL@n+$SzKgSAr`7n|7L#4d3>wFPAaKMZRhVz4%z!1@n&Kar#%wE_Tve|7$$LrR-k`4p zoQfcxz^NT(Q6$s{3>+M2SSjU+iE&XQqj5k`N27dcu~~GjsAxC$iBF)jQTx%xM!fyY zif0l?LrA{pDEm*D$hGbUFxTwPW?VE!51}Z02q|sO8@0r1#t!;{fLWLFo-3 zwfJ|Bq$%KM76dIKJ2op4Rzt--h(zeyRMj-G%@7xE|LKL@l91E$hOdL07)va%^ABSK zhq&bSr~Z09L_t(!0l9?C;j0MzR%vgbMDejOuk1k!bI{15ryy*XWRx|3YMor2rG~)V ztki%|blNf(NAx_UnAPp4ZJdFb+O-{s? zL8+&fV z^vli4{%KjEW~wo}tRA^xgLj<4$F-$+IjG)_%yvT#zP& zmwWbnw#9&Fr+ES<)T{O3-M)uk#Zo;l#9Kde^W$qbKAd#tas=`-9tb%+@<=B{7E>(R z=PaUKHQsPW=<%-m(f3(d3MOwi4A|&;|kYv#CKQd+t z_;>($?&sFN7{bf@+smyBAioAdqdGB~p8pGI2sy)9upL>O-n*4-U?OvDF2IVEm z+ZIMV+?)aY()32=6S?wlFa5LM&SN>W`R`a7mNe%1Nwa?2-$R65^hBf-ed5Y7^*DMA zYp>Ve#6E2y<9)j4BlSuRe+lG`sa)WOkZHx44vgX(J$~|v9RfDakBVjS zH57fTS-GZ3dyIbhMs;+C;q}SwGYouKbqKH-Qe(ZedW)8Y5W08|l91}`%(Z{nh)b_# z)W40bQVhfBD>IT^*-P}lVd;JC`|Juy3No;FEb1351-VR&_&<9Az19lCZQyuT&MyR- zu?^@7yUz#6{l#s8Ju&mmK}Lc6aFQM{NEF={m{hV*u{Npv*{5u}1D#;0q%W}aOJ587 zU;1HSblsltUX3FqWQEI=3wn*-u6A1z>wcp8&Z1E_o(ZoA5OG`6rAw~l>m^(dwuG!7 z(NoIhH+YVPZv1Y#cs5*Lkw4a(oK8DGAvYS*Wv7N0Ata$@P%R6{^>0BLO3c!&+qXBY z77v&sMkz3!l=If8QOt{$^nRO|~>oeU{XH;&; zC_;*ghAj`b%SqVC&vmuaX}&wm)hLtOGT_cVs1v$76Mj+t0MW2YVp28f`2cHFwlR4K z2;ZF+#L7*wZdf2Ly>D&)c*tQ#eEo@Q2t}I{~l5_FKz3cu0YR zpQJkNPL*f>Vl^eaTz2c(Rix|sFwJ-?E3KhIme1`nR4+2cg207l{M3cw>Jy!sKqyoI zLJ0Lcx4$ES770rye1rcKCQ-N%JRP<@p8jTBMOj91vr{eyr6&3M^P}jH7x*r@;|WEb z6L_o!X7s@rp$a%Xffp#%L-n%~-Mbw*@pmgTp|i%NGzn<0?(apdDr#PM*Sx=co775D zd2sF|&I0*##`T1S_LWHl48an*9_7c*+k=suFr%AJ9muD)sqiDzq?Iw>dbPoDFW<7rQKi7iWx~(F%V% zp6$HdLUjr|8>?p8zLwMf#@Bxihgyo`UFVQ|mf%xmNt;Hn$CpfN^?_wXsdPGH#zy`J zeS}vm9*1A&m-=@+jC6WM!uQWJm)ws?F)`D}IeNodx^wdihs%gb`=iuZ4KCVHaRzdI zk00JjFg15tR8Nk&6M7!ZICA2V(NG2rGB86D$};+&XGca20z}_K&(oA(adiP0epa39eT6hkI#>%rmCS-*n{W)V;aj?$K==3vm|*+LR5ecpdfii_z=iPUF#(w>!(4yk}SNieX|y zoa01Mss1s-a&mXC^%8SQ{F{u!Bt$HKM~`u3&r+C3~h63aH5QIJs@o%tkG={TCTEk3^;2 zl=zMm!DWJ7=us!h7Y))T0E`_ExJ~W@<28nS4sU0FB_?DDo4tu5uiTuyiGQ=4{iRIQ z10oBa!US~8pE9Ex0J(re+@%LY#l}^qH|PKvN{j zs|$gN97VJ({H==x$V%ZP{w2WleKXBqEiWcUb?G5Cw0AvaHD7fSarSB(BRd;&l#<9P z?T=;tDNrBBbUkVQ*x6CCo)Cez0kk=X^bYdEXcUiwuO@ z2)sTeDLHDC`*KsnC&UDAa*?nw2Nqy{?8hfa1a&xRB~nU7LX zh{aJy2Ze-GT|AFYBGF>Y7titKy{#)jR4$zf1SAK#yU1_S`&fiTuwMi$0jzoa$qwtd zEM%M4GB0q;FjD?aM|W`ohf_x?t#t5kyOgM7(rPR~lx%qx3$)mXsx=t&n7L+@>QpMd z62;PqQ4)rEGj`EoJw@70VFNQ|V9{p;8lNW(#o^TLn5n;>BFf;O(maf_0R`MmL@gQV z@;eZuXoKw_MQLP*^k4`5VhHU*7U33Kg_RJ!3l64s&A%#MxeQu1Ggms+@FLq#I5gW@ z#~-Q1;GX0e5&D%tFN`{wRcFj)KYy(7OT_+b(_g2|{9}5v@H#FRlaMDC~jSs7m}_AM2KdIP(v1V;w|kFo89bzBh=;%@sM$%2YXcVt|bDWX-HVEArpNc!0VgN8s9I-2%TS(Zd*e zhe2R~aEBEq0j<#_F^D<}_uWh9#-m}Hlo7MVt@z$UI~BdeF!S$u6yodvuJ+H+a0`UW zD%$Nb=->rl3-JNU*8U_#GfiGQ7l<(gtCe7{@a48aJ1xU&my6)rOF4U^Bpm=oc_K9e zefXyZU||8yUjU9O!Vp9)&x2WC)*nU>Rmsmg9ZH)TOw>jW?LwxxjK!ZYB7h%kVW}i4OtevE zzAY>A)S{o%O(Mb1k@L0 zP@u43hs02#Owvo!m$0O`;WUu zDS(5XEDu>S>~S!l5vnvdV)v8Y(|Q>?p*}vBpobFoN^kY4RxqW*jM7a z13gXzKo54GL1&=+G(;HpC#Wd2HNbUT9OOj8@(k%*EIKgYX=FrXGM&3~@(UWO6L^G< zi3dus1)0glRk$W}3(i9a**x{HwZIXhV+N?Vp6mdv+`HOU?+__MDSQ>Dh!>+`#kAUT z>Af5;I-zZn%MC)ud7yBKUHjA+00W@$!tw}W4|44kbYKVzdF9qz15vMAd&# zS?h6F9ncVA2}FcvGT6XO=0h+$+f|Gc$`}{TkYU8ZN6G+DM3O&aw@>d&I$v> zDr%r<)TeP_rtj1z4MT$Rh-1B8{Mfis92#e0ZBMBKszIq~mjzX0`ryy{_lF}h(z(;r(c z8CQZv3LLHSZ@X%U8831lE)7Qt73s32Et9we(z#2wgEj%o7-deAYxw^htJ95KY_hJq3lfuU?Dlo5UiKTj*e4V)L%h3e-e zI!yg*CGfCRK~4!Mg@Zu})Y_q7*UKZt`$xzVn?)fQoKN?3(3u|NSJ%}pO&zlug_e>3 z9|HGMSlGz2f6y#Fj2O1}I-!hRxZmoIL zKVLqD>FSEe%^e-Xq)E+y()o{J0Qf05ARZ%7b@u=dpUd7ush`a~I{@72bUFU*LC!f$ zYF!i2i0^kU@C&zRMgZ;ogE7TY#}j`Kfy-XPDwpN=e|eTUogkt z8ut{!y6>MCaWk&Kj1p@uf)OFjiu-z#Zh-qcd+(^JVcPxuKgONt!c?*SZruzukf_+2 zGVeW&obId5*;b@j)J(p*qvba9?T!wE|J)M*;}#30fbi2J5FBXYnL1#P58aQL-9o3K zjZ(mZX|?__RSxHM_xI}dG2Ub*fhkkBQj4by$+awyHTH69li!d`M|35>*4LhweV-~R zfAqOHC;g51nq_H2BXbAd3~=3Kqo`81qHY=+Oo=QvaCz0Sq{y>$G z2m_?1QrWCOfOGl1F4zMuZ_hpp8y=5WPd$D2#Bp2Fd(q5{4-1YCK zVbW_O=VT;`hP1)MR<1U7`wfJ!k(}lv>6F7!emL|&yCh;Q5FI1WqZwKGxZ`AI_6#_X zDR7O3>{Gk9`r)GMjolpt>%DnAk7lKty z_&$GNpTGJJKsK8NV@IuZl4Sf&kAiXJ38={DhVvh02t7OS@bK;qeX7{2$$`TLf8zp# zI~dbByrv;-{-i>cz#$DDs#u%GPnItn^jodZ0o?Yh^#N&CaC*C$pPJiQ5dNl*yZ!6E zwMSH+OlZmvz(EXg_=}hG28wacq7;s?*sBH z{xQ*1VO)BpZq~-S(J=Y~ZvI=1s)BCYHBgYM?ND8};x9UL30JM>I<=lXDuz0uYW|k7 zC*%bO1hP2Q3S;RV3Q+~4}bF{XB zsQ(Q!WP!s}IkM@=x^r>ktO%cznT?0+doA;2=Kb#p5SAutQjuaWp4_X$ZL@*LAvsS)J6F`p~GdwfaPM*auv9p5- z4Vt}%Z}#-L-oBT7WT}b-j{QM}PRbrz(T&Hca4;`>va08cPOyZF+hX7NHHS1rnDW?B zZ?5X%y)*opL0Y>UA;OG=%nm1!^VHb!QKNgyo0?XrV$&KAB_n5#RjB8tVNr? z6`${7Ih}5%S-5c+FHZrDSJ_L8)1|Y8>a#|nLVoF!5lZ5Ed&GEnA|keS<7`(&(|0|i zG3b=CxDDHRg`dioguYbbgl**=_gcpLmVe0cnZ|8bV zVRrR*6!@=GO?&nW2`#-n9Jvd%CCAbTNo|fXLe){yu^OTpVc`syu?X$6y1%EXep<+S zV`z*MuQ>K9X1}(`xYnG~!r<)tlLw-xMun}1fP4>*u^67cVM+s`E%;D{m)^^MZru3} z_n=rGM%&r@j0vtrwwNt7w+9hlD@mb^zH9(n>w!UV*M`4 zVpn=Y#sjV=ozYq0Z!uWz7NJi5;fDR(`2T?eojFx!5|3~ZAe`!Ef}U!QIP<vFJ$dffiMkL=(BKp)gvpZK4!E4v?i$SCt9Y>+SjzS9ILPmdw}3ic<6Nqbnoi-nSv_ zt|q{Sijk|*nn7QZ25q|^Oy-!=y_8;Tb&gNIFG;3y(PGC=m`+?*wAq_n%dc*_Sx74^ zwy6*^i^78!(m!-|8=H}OLlDb_G+1%OyHR~c$1;s|MrfFr=<*GoO8?D5z(_$zsqWJT ze}(+$b;3XaN?d+#CZ@^8Fzu6>ebqkVCaH7s7tYcc-)j4YPSdngcpXGDW28=|@=0he z^pGfGW6_N(G(S(4*~zTPPzc?Ki~FM>#jdc`RjwE6Y6^J^N7cENZhW(|r^1kqIM~Zo z%}N0y&z66g&DZ-HB!NlsKI{AIl1jAIGv|Yn!0Z)SuTecYuDw9G9Uw$Z3dP? z;m_*AMZ4;=>_sS*d+uF1`VEEl3wP${+wiWPtQKNn`>*vMo%YI34I0c~_mfLC6`o;W zuJI-RS%ZGAl{^SkNwEuUHma(o0s_Tr{bSM=pky#?d8d_y4JJwaiCTj2a*{chlDU4z zw|RpxK)!go=v$rtsYBI?2W<~cnAP+&?`l^P448aKWn|diIQb2N*;f^cECK#govryA zGd5(~oxbFFw4E#^$%Q`QiIf_{^trF*8a?y8} zHi#aJV32l5d&RkHghK(Ku8V77Nvf`XkLF73n3uIs5rMCj5Fa)xaWow`{+ zHR>NX?;TZmGppVv4*porxy5CvSUuGiiH=&>?fpcn*6IHs7(RN~l%M>J!NgQ7NJv5g zb4n#PdGZyFiQf3fM6O5_#3&f~yGkIi?pR5`^6OddI#N!7k%B@OY(;!d3Tp`N5VarH08c` z4l#@uIh4xVt`v+BS2@Jyxp%;4TUPssk^6Y;4oq^C^i3^?1>{icMGFXPSx*NLGrWu; zS@Cw$Tr#2a(5>2nxCeV4xE`w@t=kro$3>$=Qq3l18q=T>uXqyG_BLg_$q z1~|s_RqNg;1*WnYv=)-Kpf5UwJ-_9^VpByPP4h)byi>N-PMG5FMCkV#J_F;X zFvX6dy43UyI1q^|{Z%MF7A4=S1GSa(86(3)X7%MqS>a{Hm)CwjG)uW)k+ejxvp--; z4;4HG)P`Z-^+w@b_?=7i-W##o310d!;Y9w}X$Wvh*m}ISMdTy+B5l$yPX+M@#g8$! zBC}og*F{EFfIkVCgJZs z`|TBeSNY7_}?p={G7z z9PHQTNJYAvT0-*Z+*3N9*H*}`|xnuZ|E-AF{qfC%f*dpr|7C> z*l&g`P8HYq$B)EWlBMuEBk2?wl~BWueRTCQrVDM7n_)#}I`zqgFx3eh@o#~a0gwGa zL>U7^tL3XiKF3-@$^MhD{|phh2ncRY@qpUv6$w#|+sI>9>#L`W=c~bmrzsU&-0XH! z?=gmPkWlkw?NJUcbF;bi@AZ#QfB(RH}JHCvv%Jku?t-cdhET*R{eXCFr>l_FE76j5;&eiAhzJB2QgIYhfYQWgwI{*XE+Y`R3|o z!ySr^y+KY{|FbBF#Fx5fd2)HV=00j~u5#@Co*7SymUDKr9J{`xTFXOzuyzW5eMZGu zC3)}go`=rsZ7!Qf*rB-s!Mu7ToOFbkh?}&O%d|p7<~v9SDEHeAU2*vIr1?>V-w@#( z1SUhj)^mKa(C}+dquyz~$7jm1oWAbg*N@a|So{yg9@~U*36Zjdu_}!PyY(N#Yms{9tbOul2$sxR6Fw(by`|jXM)!wdM2h$eJ6EaKJjG(1R%eNH zwYb4%#N&kw2W^n5D*2@g_g!AI@gh0^_(L#XNQg%+Prz|?$k!h0AnJogpb6xk+sx;k z1BGa$_wcc2yQ`khdR%Ct33>?GBth*`WLFE_@X(V4qA&Z9hO%6nwWL6+8D2OHX;iSw z58vkV)wUL3;XkfKa}}`b4AhQ6bF1Gr=@7>EP)M4XZEDrjxHeq?hd$JjlS7M;yR-(y zCQG1~QzyqJ$!ZjQ{^-IhTmFHX!c|h&l2wD=#FSjli}Q%*eHg0!YH6wJSCdGpx}N!F zwfqETQ9gNF<14$d;ut|z`*^Q>m!#-{T2b7wme@?)kjFH8&oy*wYTTuu&;1a1{l!<` zZ6c~vhFtQ$OuK*^KA4>$CD$a1!Rh%)I5JcJ7>5^xj>qHxf=!cj^e_=L_-jIJzA!S) z0j;vOjf4JRdI(Huw9I!cvIZveTtCwIM7Q({%|n@Z$GPE`?%x?0VOZ1gJ993ZM6k{i z?I?j)hbnHXj2wl^RM*U=cVTj+3{M+xPDBvSq(9(@>%@{&S=%QiM2+EA!iiIzDCnS| zHlFJ!l$F~@*KtI9vU0mJK38w?cRi&%d<%1X%MayaE}Vo>4tF5&abi8<&46!4!Z3yHZ;*B zwDA$S(!Al53=iq3$xQn=W0``Z6S>du$no)ZyPwbJHe_Wk1yVDg?@d@A&(0{F&mDXw z`>=VSB@Aj8COhj)LxYx>WoEv}D1o_Ft8tLMRl&RtenV;^T1+7=a!c;2!}Af9udZYN zRR$UG@Vfi%_tgp-hMrew{Cp!j9q#?~X)fc_RhSl^j;^eD@3$G}>Ucx_X4An*RYIOD zU4h4ezHIC5p3Dcgp)!femr2oGqYh_nq#_?+Gs9w;jY+;V3}-&*9N(qsHhV5MZznG{ zJD)zdk9@g7YI^OuWK(%fqI=_})4r~f==C&ZqGFa#MhBb#A@9}Uc4DGyuXh_O%P&kG zeOYx@((bcZhF($Me}%U7>hzxpIlu9lJ1HLET$eZo5GT<7UGMv%%{#WhBu6mX3k zJpLj+PYk(u<%d89Hg%1s@;JD%?A;NSZPlo}_<`p%&y(ZCfi(X3rxGDk0 z;dGwk^?7lcYRf1b-p5_T{s}EJ)v>0Erkl=mflcGl(xzN2&Tf-f$^fi?8ISA=!jSLJ z=Rp8U#SCW4a81vbjECO**ovg`(}!7V1`*oxPF3#(dpj)aP8U&0zQvH1bG=L@!(NSk zLBg4$snRgz1Dr=j_K(m{OTE|Ktvk!6vII+HM4OojR1)aPkZ+aWEH))awS0AV9Low9 ztTa8&|GH!@!OWyFTAojLedUC9pKq>QoxH-$RH;7~=IeX%;~;;G6uZDZ+)cj&!_Wrm zpS=K{kz%|;ZR$P?*mCKucPZhh0xx~ePbH-{aPn>ru7-HOlGz`eVaCTN64gZX)m3`0 zoHi5KY%V%DG&_J}4`px5G)rt7+QSlAy)S-@XX%DB`(NR8_VU)(pHKm`di<4M@b~qb zNdZ!dSJAQY4Wpnw9|JT{kZQ{pO%n@MB_!j?AjFF}eyZKhk#L`jjT&;%)7_1d zG<)vV8*C!3T)ipUxDAcme~D^sjN`n&nk5?N5Q?W!VyVm8*<%!+3K6cL3V8Ed`2(5? zT^88JW<>Or0JVz>>r{Pve_A_Q>AEeR`H{hNDVNVuUua<@KgZzfglUB#{&>Iudx4*NZixZvl zB_k7kGXX1Zw7I4jRY)2fogo?5L?Wc9EMl1=etV5!so&0Sq0Hig?(M5<&9);h*~DjI zoHb{u&->EITXX5k$IXkzK8qe7(wJAzklyC{UV~{$-7X!wAxaE61eIxUM1XgHYuN=y zY4&;EVC!=1kEs{D7E^i(nopvx6r$qF?R;dSFesWD_=(7sV2hBuz zyKUiFEMfU~=floD8N$L8#@JCAtP@1Mk{O)8w{rja5;LW+Vpjg7o%S=EMZ3<};BWlU z92}U~`KPr#h}-_4MlfK-pI&XDfa2qOra5&BqSCo_t2T3*6#}YjO@o8o{gPk&Wbk65 zcToIo9TEexzLiF&OriUn3=$y@%$*}LNF)n+V9e9J%1WMpL?o?(!n$5yMz2-_ho2g~0|emB|SeHV~pqu$pSc7GA$cOvY1PXF&%A>#u5 ztj3X{VFtW4d!cS&XJ4y49<=&P*oGWn;3Gs~V{u!N+07};H*x%X8x-Pivi%kbP*qsY z3GC>5KJ#{u5g-x2qfT{3|BvIyemzSmsFiqOZ=hTxk4Aka^0y%Q$Gf}Cfi3(T({)~6 z$D99UZ2sea-gm+hT=t^|Ors?KTW9#yxC<8ablqzQN0YHX1M^R_z~vK5pbBtb>sx(! zh9S)I|Lp=YdURp=TZZYXrfWt?CUmM^A&13w1`heBKM>HpI(lzAgC8H|Qwz6l$OrK9PJZEE~V+&UU zCsa04WoN#~&ZNpNpGQ$)t1gb2ucJ+gijXJ6#=*zM#Mg~P`4G(trfg@pJ=6NGE;_%A zMyUC#MD_;^@u!DdYM}P_)}mZBuiqQ8g``HEZI!8v0zg1GC@U?T5V{e(_ah?3>?llF zqhN$9^df38X-?%bil`)H7!ZDGGv578_;a|Ioqx(%!r_SP(|?*KgI=M47|WMZq!&g( zAvBcWabXw1m@&|5Gs9OS^}?jhDs4d0#uN0Fd+0wu~mW zr%_|@s=8I{Bywrc1(aca!tB<_&=;HCt%j0)Z(G9|U>Q|_>F=NGsKf%e*iR?L zLTg>Po&+VMO2g7isX{8%1~C%=;^GR0tT}+2$ao5( zp-Ao^MJ7~2R)q8~YDYk|tHWXauR_Jo0r{(?h@Qx0t9ym?(P!Y-Q68F!QI{6Ex2<#XXebDxgWoP z2YPo`t+l$U)++KM_LDCtZ%s$nz_TY@l%8bdTE*Pzh5VRBSZ zg6EHjDAN9`1M=T`d4Tf=t>bwMc-d>k#Yg@65?#Cj$*bj`V8c>u~Hw1x%^%Nxp9O?U%ipfbye1aiHB}6FdYddtG8@0Ikton@_ zXNNWE(pJrWovfKBM6Fl5Jmq`oc>bPm*y7GcCy33T)E*PWipdUYZ|8~Km;~rfa4h4b zV@+`Xrxft(kY2#1u(Gn^5}4;F!u#<6x9Kz$QR@ZMp9;P6THin-o$AVik-0_E^6*8mbQS>Ug1UHcSS^y)j1Cfwp*Onz zagqTHRHrqn^Sus_fwffBuKX;Sevjsi|pmI+YKrMtHi~I^WxyFPAOo_Yv{+`VdvkXfy=^0eU+6v(Q?b%Lfc= zYik?vBsh3@Hj9Pm3135!tX6P9BkbQ<^w(?-LJh=!AGB3(%>VhZlH#mGK0wr`=IdVE zN4P2*wO5}~7=EBVBUL;$#$v2C?R%8Bh3Zc}Fa^E^uoL7}0BG#Z;1avLUsF>faR%KkaNlS+oB#|3!1TKW*l(N;N8qAJby;?) z%%)&1*T76h;IPCDes|yB_<(@RX64V@ANdK^P|6h5`TTD2?j~r5_nUvojw67XOaJ2i zkLLL$qz~rnQ3EVdgI2UTf6Gn;>D!NZZ~ZF>mwph@yD{1Hw`ie27RxlGfEV#$LaSo( zSs10H{N$gL;V-RR)XD4L$Lb2~3)s?`${$v+(-WzaybiJg7-lnZY>50tolxuZG3o7D z4o7``efgF5#xwa`KH%cwM&|;=#tbH7nVX~8&seZNiW7~|oq#8YyPP**ToUUhXua|F z{BRXZCX4WivkoAWx~Dk;e44Cp*_x`Vs?qhV5s-^R0SHMK4I#1Nem`8H#gzhGBEq3k_lz% zwO^Wr@Ehao$=}0Z{GcxS%YKZ0&z8E${a<%KK>yz2uYx^*0;ba#mu5B?^UH37@SQOz z3Rt&h=t)arxq4BL#D^+?DI}m4RgK!{$45u~5=c*=#oKDO+8U!lb+SmVv!}}2eA8Sv zc-X4s6YNAru^c982};o5C#jW7u0TUYt#vwI1IV4Q;9nDwI(Z&}Z;JpnE<8?BN=m^T z@jh1c3aW1@U=Zl>aA~L|6x;+zY@iEvOz3HWE#mD*w*gfLBB^s{FczSBzuj8qgjvLL z?MuUwFW@K-`J@B@eC3f;Je%3Si%m`NI|M+jvC|sK`8Txn&nM`P#`lZ%dX5SL_pzoZ zXP4iiD+#+F(g2;72zGf1SOblE?TK7fOSd53Jq%YA=se%OJ(kl?d$$KHb%y2_Ss6q+5!+Ful7c{T(1v&Az-r}0L=t|v<8Tb^l$e^S?}O~ zlOpEve8v)8uQ$h(D*kaeW$L`QTVjVmnqHa^1Rl^fA}~Ks3+uY&VKS!MdTydCC6LHU zt>bXNM0HwFAxp3y^zR)DVK;cydlYfe4VtyDso`Hyx?4L>e!gJO*MWZrprzvK7?JW6ICJf^I-T>nT#}&O$E6qp z;ty|tApgPpsh6i~)^8W*>!7#0^YvdSSXfPZ-H=rmgKKN};bUWC&qhGH>&XQpmd+jl z7dTs}?(XUWE6K^p353UmgplHh>Lja_*&Rw<<~O5X;o?4g?mm;Ugi>Z^Sxtd81cdR% zJ~gd7xwSZnzLY3`YO!jiBI_w>a8u-J&!e`%{pVVe5FO0qmFbWEhaQfSyDw4z%4ji0 zpU?wD9Mm$&62Vu*A+p4T(!n&*JBD;iz1e&G^HKooUJv*f4;TWP1T-MK1C%jA(fjiA;oYi&Fux zccwGn;!-hT** z+QeC^HN9mtV(xr8Ud|8an3ZQdoYg-}q$RaeNyh%EuEr7O-J?-sqS8^`evK!Lv+fic z)~K8r&tVS1$*>H-zAc&2{mIEB)hUGyynbN~eG9?^H*=>U^T59NOg)1l^X`gQ4jlH! zdyaah!{_ueAiU4k+POGDKmqW0d*x~7frnKAR^QRcU|(2CPhmD7`mqH9JN`2${5oIW zl{h@x)E=8t>snT~wGLQF>b|sGR|q47h;K~IRmB&ZElx#?dIdzS;@3ax8b*hfc2NU@ zf(54e;o{=p;QHllY_7 z_+`{6i2Xlj5l8`(QV8fx=~<6eq%f99w;G{8xY-V~6wOfrpu(VmXwjgX#CG^!e>Rcv#Dq;FyxEhFvEF9A2mCY!^tPjwwBGgkiOIM!zI#$ zEd)dG^S0bOP@YCe%EfsilsEqdd5e@1npvRGf1Nrga$itPCU%QMkXTVR$n9TrcNNx99D4FTWCH+YVq6Js&q7 ze_LLqIHWrPp$FFrS}vDg9f^pycK8a(7?OV0!({sIY8oCR>xm6efz8WPd;6 zx6#D9`ASfs%g$~2ZQu37)+;W)r5l#5cj>aX2pR1a@enaDPg94%WZq*%ZUf(TL6$?f zhlKNf*~!am@m1tgze@fqwVR^}|GbMayKL;EK?C)bit061X}P6an7PL45u1dP0c)C|H-DglT-eOe9yVS4g%arIy;lThCByyOGy&M4J+?|p*rD1A*Hr|AG zEhpR+Z+d&!6@zR)<{AD;;r8%k1{qp34rf2=_}AOeJ+dS%X~Iff*gYRo=5%3!n7d~y ztJ8BE)AQ;(LoRFWHIRm#02QfwzYiO0r0zAlOvIJw{}Al$p~YcBHPJEe`64)85Prls zeiE=Y<1#Rw*!HU?zVoHfUN}IG_qvkSRdvvZ-_S8QO*0|4{Eg zXVOcL_6rO*T9Hd!9So5^7)yYJijI~w=#O8GDm3`{xppdumz9@pef-K2=4zH|(dzid ztwS|Zi`}+oKlCmrN)_R*cK1bx&$&!Fsb;)?udHPR7KAd|sMUdgIkUWvcmKA3%#v&C znWI`WIYAL?Y-?JR+D@_FAzt5MP~XR3eY zK*&81w9e)L82D7Ml$o!7SA%W*Nj^=C!g*&sk0HBy#VikRmB;^1`oEPNf#{n)Q5{-s z=6dl16aDFk@=0qHPP0!{aB*jk|L4geh|(_Z$iW0_L;^Qa5f}+A3#@YEOEM4nQVpU@ z)|R)Df!+R`!1BUd(WRE)q z=nO)OAm$MC z2~zg#1qSa&FF`^<*q=IzqLobpT}e-8gh5k1ro=uy;CTf~)xC?$7Ce1uB#|RXBt)DkX*6F&lux>9GKm;4u z3bT4lU)VO@qSRwAE&HiYiqSir-a4eL-65jOI2Gu&uzQ%Q+iBC~k5&2xB^2`2xptC6RZYGzzxoBi)Yu7B52~qHZ&n)POW}g%Ig4dD>^+%My4C`|>w+{R; zR5cap*#EB6VgwvL1}rAVqd}<-Ujx2biym>bvLykOr#IaxoImo?;+=WHma`Jqc3byt7TM0EDJDagQEY7o+Vcx0d0Ow!={9ip-tJj+Yf2`Dn(5UTIg%4h56hHG^w#|jX8SiY`7ZVJ6pGC9 z1)+r-zdk_DhF*4iy>&@id4`SOi1(yhUhTa~uH%>9;!X=t#Xk)7xZH1Vzj&Si7^%5vvXWN%gaObsZMNWX3^ z>^&>@yoIUlmEY^gS<7fzKC4Jz1!+Li>hIQo&_js&zCLcUHOur_gsr@V*qZ7yXFIMy zjJVfF?g8SZU|mYHRFCS|R@Bj#DK~6q+4;yCf%FMreozrPEjsd|VicQo(foMt!&G4J zbl3&x$RfuP$IgFhZ3OTvv1cVK&STr(>4d!Ok_m#y!;V9!20&tR>ClF#!_NxNL)RoM zG-e}CIJZ24w8S+R!8UTy-(qkuS-x`Tg#_F#8Mz2!oqw>ZKHMHv-hR;38FtJ#R1rPK z)=a&;y1T0cksXu!l&-v8&J+h7D)&#p7;v}5Nyr6={E1TU3gpfQ!oT_=!u)@n?PCkX zIbKwr$GL1HXe1As6OrA$D7?@_eR)fsL$X}uef(7z5O#Z1gs*6mR2#~;#T{-wJJI~+ zg7@Og4^{!e5(h{ImkHPT^eCxy3nJkox#d^KwBFuFx=;I%2lr!8P}c0M1p73(IqV%x z9)tQO#(j`s<5f~WGo;i_~E6?%VYv3EDCA_g65E0fK zW*t%|=N9D>glP5jw9!X{UmvR#O31=6Cn}*B^E3IE5baZ+?y{7Wba=k2@OY0}>Gxga z%(^31$Fz$L`VJF)EyC(0QoHq+Fd3Vz+K~fwgCn)C^$KZsvMG{v>tdcDE~lPr4~o}l zMoSc1%VWy3yI9hC9wRsk*rilRA5-{$Hy`+AzIfXMaq5jCS1jwts1#Z#&AhxipC#+j zUhF4@7{Ooz6)QAwT^kDC9!uaQW>!a^Ca1g9Kl)uBRsLRb@pn{PLH;L_7g*IZ?$T&X zHnkb)N<)^z0i8fv$Qdwgd0B>SIZ@BL3)sKU0=BkDOxNeKWNihUt2EqTpycDDEPoB)oi^_*faS7OrrF?g9 zbAp9!(Dr}7;DCh%32C%YBQY2nY~m|9A7K%*^e-9}5#1dKnnrvP?=AyTdR6op6Xg+0 zT7Q0DbORn=+*A3>eVfd;up&<89~_0+(0T;g;U>bZFqAx$7Mnuw5r{}&8ja~6*JW*# zqb6vN>vOp|aaBAI5Tk-tR&yvvlchiJ8Vj#R&NfCx1|$%mSD-Iwk!f=a-VgGVwKojo z|GwHRC>dU~Hr3G9!5V{y{!aBiR)K};A`v@iU2E2SEDPp<5o* zE3}@)-|M=v6)%Cj+^8y)@3&{$Q!y!3hdY!k_mP7#FYT!&t(b+Sn;(1Bvp?7N^}Hr> zKR+37J@#n2l4`4#;VR-?bc^wj5%R@`o*_h!c2Dd9Fjb<~11^M%g*7ZN`5 z8&$uE8J!w$F*;p;Hl+aNlIi6EWE*9{96)}Y9UR#=K9Wx2$-fI%cgk z7CCLp>Sy)?Eq%HFyMg=fjtdIX{U_`Uq#5n+ouM6dEU{Ts_8&QPBPR zih{m$m-_qe*R01U>7viKmHeZxLG2CYxJzyF>aZH0S!gvH%$%ZJ_S;nuBO+4z9__}z z)RQ5WYI{?eG4U3au8N<2HJf(449$4<`hw=}KDK2LVpUde!Z#Pu8plz;_fJ;vJD|18 z_ZdKzka;r}l8kxz@$}{nM9d^px7j4^jGd!PL)IK6XnwUV$ybe`4W-vVbX}?C0H9r5w!`bNZ zLO*Zz^;IbQnWkZFdw+W|mxL_#q3;3L^ps$nE{_jeq`ZK|nAf+0kTfO3a2qscKJQ=+ ze=1yQv%Y%A9(Ffp6ksa(DqCrTSpM==Kir*V??1bRKTj@B2mx@c6}^26EJ(fm{;?zf z_xw)%0bjX(%_cyZ-~nSN{zqXT^r0sDrq}g-Qk=sv=|s>!g|#1_k=+*f3r7BT+W%-k z0&Qr#P$;ib4}6m}?O?g-Js&^V#3W3pp7lJ}^WaqN95;unu1nj9FTHgDVh5 zYx~j!6d#mOv?65}%+3;n?f=_Zphf20--pjG!TkG6`V69GitC$@3RC$F>^F~mYJMrV zh+VxE|GkIEcYn1Aeeh&ESwS{R=51KCvoGug5jxe+i^Pxe(*-T6RR9$5KUfTPnRg!n zE<3>MgfpSECHDoR4EXe2S9qc{nVHreUr;;GqWM)&kzkU9V#7bO z#=~5YMH?)B2z@V|A4G=zAx%wFg)g^Y)NG3#|DXQ|oJeYbv1=3{M~4pf+`4}Jg5yw1 zRji@#-Du#u#ym#}u^Kxy$ovy@R?>_PV%7KUYXHVX?2d=?kGuVALeq(&D+bvYq4#em z*4frBZW&`$aiy=m`37`f?%&LOL^~9`B})ek8ostH{9hLlLMN1ocx7Oe<9U3p{?VWR zD?)%s02~ztpi@|L%?1DMtMEU6Gk^;?KkQY!gqQwbxXlhJ5MEbPYkl@qYRL;!m5@J4HqH4sHw(Fcl&=!mi!f*fNHX*>~x9m zLeX*x0U5IoE{kp=U>XriK(GFAzVq0rZA$*6Tvsw=Zk`lE^pGBc!PwF_fIr31=1|4G$OI+V_Tce$hQ zpr9DrzN-|6Gz}hbA>|MWcgs1z#GtoK(!+fwG|3*Q(ZaTysGw#+P0+h%gq3xt8cv6tkw~&@NFAv#4y;ETdKfUpvk$BS zAEJg$07urKubm-yRim`s#Fp}>^D84QR0fEHIl$^)OFimz{j0H2HQNC1`x&JR4{&lZ}Bz`Fg$~Gw&1E&0u3ZG#_5+qc>ID~qs(TjjVTo;n$uR)P( z!Z`vX!bmF$NGXC?nkt~yGXxLx=B*{(O!`km{hivtfYw5Nmz%Z=Gf)p6@`aq8fTE$P zy%2xG*EoU}#KfsiD+|z~GS4m!)B|8%w0Z*DcEsNbj=^m_|L>)=2?1CO1_`-|B78c} zu-&A_KrvoEvT6=ZsbP&+A>9ccvsHgqwd}Z#QeTfveH{&~F9zo~b;=*=2}|l2t_JED zJv3;ZDM07)3mVKH70!JQgFZM^)L29U-oI$%Km6bQLz4JkW9`Eywt>k^1Fp!T6o~>~ zD8&LzTnDF@E7Wau!qHUzR&>mDi&?HVSCF$kd-~B4F2&j4TwYxb9Qf!oLNY=>fvpZZ5CX$pDx7l~g)-^#xuT<~Y~$K;{&&p4W2ER@7Ab{$e3;jnJ5pW|U@aPJoD+J0Aczy~$AT5B9l zG|k1ttpX{*!;ipZ1RXJ9XNXe;F)TaX6#!daULJ(-2_{1*5UyCI zdY&4M#MS*Vulr4Nsdod!C7yk2v!L5;vzP0h~-y|V`NZ=KFopfjQYja$eJxeY+< z{YEq#>-{d9^_uq!pyekQxU;$WKK19%pK^iVqk4Y{m%@fm#QXTXMKK067En zf&tXVEg|o6y?Nner~lVtg?yv&4ETC@9A+CQr;i`k_#(6jv)lnC=|<<@TmDw`n$eXL zAAlBu9@0n~ZqW)LynVTQy#o`F1N7Q~=D1p|5uihDDH@6Q0D60&D{|#S38uOau63em3ZhvcJndq0fr6w^>7Yd331kL4fczpVnG7{xO3)Puj6V1#OxGna_`t7QoqrRV75>0__wHYM0W(Vr3sM=}%?`(N z_Io46I_;ePmcNo5!K9x~m)Wp-XJ=Wm$;9Oh3=FWqP>PP5C@+G5_HiN*G)pDQROE$B z=^XZZfXX}4;psv(V4ncEB8WxeeKlTAJ19^nu3UG$zwTZ3j}4NhFPS;=7p4AJS>jJX z?)3S440eRUu;=TPy3LvZ#rZ6xYH$Hqj`&R-L8iH6po78{CCGg3 zr_VHfdC&7`rLIyPAEs!Y=&6}7bGkmeuyQ?lILrkp+irhNT}JSozAhl`RzyvP#5@a5 z`A~{jG#v182Yfyt2U`G>ycvxUVInLDG=oZ=_RIZouZxXeK+d7j>2PPi#V>pWcSc?M z?AQY6mdnbH`-_r4Jv{il`U_rySF7YJZ~)jMEM^x=91I?w_67BceIRQJH`8EChB)Hh zLBMii%utj3c}DwRQ#R25DdE7;CG}tLuvccEaB~gUVtVwBrJ*ml)9^0|edzRGU1UJb z_rEP(=?3r#U=6mn!NI`*glw)@k!%b_^&JbB;ZR%zE}JhuMEfV>H`Dh<2`v+Jftz~0T1^H}A|mh)rn&jyVzWDYges!eTyGsv5N}l>|)iucl}; znBE{nf~qA-{5VuV8UaGY{q{t?Yp=OpYb-m@e)bZeb8F5A zAOB+=3G6nsz!q>(#Kj4>Q!oHq%KEIYp9_X+`~%3TERX_Mcs$LpM~t zXU?V{rVVu8`a9~~oDQBq53KQ@URT|}jSn;<%IbiJ4>p#Ob(ey~NrYz~fQ;GRf5 zxCSKwLVgHZW1_Z3q6zD1*{Lir~x(IbR>yk1MU%nT5cmYDhe@Jid=}QDhdbCWr*f4}(S8GdIQUA!-L ze|>gY`-n4Fq6`Z#i2u951C}U%{Xhu+2f;7kZ1s~Q^nr-PA|#st%%3zoIXAU7qD`QY#!lzTHHlEI{wh!Z`&9goP{6_q zC4rQ=2F4XFFqlS>Vz>r}(j34B(VLSzx}s~c6fM+bsFl3PlhbBNE(;QDKyzY%)BC7Q zAa9;3ZB3Q0-vdqntKry8p1FS1mKwm=;^ICNs4E&o{?~-^?}y{p00%Gt5Rm@J_ESn9 zIMAyJr38AW;H!`l@~4<-gMOMOKUuqVBF9;+079oVN*y)ALQM@bs6&DtU_zacf6)Dm zqVL-OzonxNNwk18)tD@}0_+9fKb9+p&x@6m2%9QK6}29~BO5D~-t$q?DYz6HBE zHPp_12`p$F_uZ(&@eqN)q8{jN|5<|ZiM)II%WM(QUAygl7|@s|y8GBU7$YMMM+RUN zfwaf|1J}VuN~1S$#u!S=$`|RHN`u%Os$mYY)cCT* z2y2-=LQljgJjNeX3!H`!Mxn^LgQ}h9mQXz>`7#JH8O_(*C$vW1Cj$64eifu>vD!@r ze{wzQxwrJKYawNJw14m2{!EkH^iiU5e5Qc6U=Mm;G3)%0MgnR+HLM^e8WrqsH4JNs(N68NXh?h-6lMCvmtF`8>cV?HnA)IpR4L(~Y zX82Fl#;0{uSR}ti;bv&B8lO9VLZrW(9P>Pzp5qH0OL!13lbEN%s&YBH*MX&dCReWx zS8o^r`}o2FHYwX6?Wbxu#q7G@UZi_WUxAJ>CCy*_xb9n}kr8@sOA~iwkg=KHFOq>^ zv~AH`o2B$-&t3B7dqFAGJrn`!w2WeZ60aeHRe0MctBU17H-wbGSE4#HGJJG#&(>B( zoPEE=WVkUvVf+CNx?jnCiNP>$Ikc4z1t%Nt#$xv%`_wqyD{(;c;qWB%_H3H9eJtT_ z|3H=vK{lDb*<(Dre3dLptL^Gywa47Y)Ibm{S>RpAY6hQ$$^1hiZ!i9v4_iZ1b5!cN zUyzp3#i%m@z#0+$J|-^7Am~A>DqAb&aGN6Y*t@j`qX-eudPDVdnL_I8s zu#6Kt^o3f8$wWjrA>0#!Xhdun$Yndm_q~a@k_8nj?sP5U((`(Lt&QXquKV`jV6JQ( z#{FLQG|ONHsw)kSxEx zvctE=&@IeDw)Guhi-TI?kN6ayw4T^CB|Sk-C!e?fq%E{wc)GeF5-~lP{E&$u;LM0a zsUHFf2O!mq1rB^&NvSd84S%6t)2PlNIeYUZ3W;WoR0*35nSBqJcQE_K_eV*c+}FdA zpre?Y%VM*x`6Z>kOm*C2pozs^YuJBv#r+!nB_q|dk;iVp>T$MV>uI$&SFDAmn+J?BV&$PcD}^Af~wj zNy~onkqqe<8+Tzn!Ret;Z|!BjeP;ZXv6BPAy!BiHYLsvDxWhf9$JcoubC3J`;H_!B z`&*Awp``e&o8LdrVpYwEGxhEoMy*aewni`yVuc?cs55#!PFL+sp7d&s@tyP2;YP$h zqPY9f+Y?3vHR3mX+dFH`)X%m2sf&N6hKoz7dvbNXhrxEg$E%0ae*RVIx;0Ew6k$8X zUiT=|1;5Y7H-O?prta3e$P-Sz-p8;?PaE`NUkSs;0#+U@LRJbsZ7qRZm}>ju##FMj zOK_-9!Kw87>z*A^Z(%dH+I^~byM0>}OCGB&`vafN=}ar>yoC(s#9eJ#Wbr{;O}ER~ zoT#Ti;mjXwF(bQ4$qsC>_GkJk)5Fs4cBY=;E>Y70L3p@`xeeE-rcCXdfmvsl{Hd`as0J3;G1}ESa?Y zNdpR6cdQOnqblp-Pg(3;c$&Ap7T8t{<{qYR3!AG>rU63<@iH-I)1wm-H3U$^Wg zmFLnaZgwF_`EY9a{eH(7r$|CAuz~lfOEN0F9g$V4xtl3xPTVSnxO>@kNT>5UD}uG! z+Ik?N{R?e-giJUymX_>NNyggBXHi_7usnYcH;NhwUwVfgbM;*Ly3DbCWjjmzbTIuxIb-;XG{K^=T;*7| zSY+yQc^&dw4%bCwYE%s5v}96r#x#Pe?nF3(RRL;DggDa zp)Ai@;0)Grg3ZyYM-ND;Wy_qk(-D$)_X>{vVrzW5IA6=pA-x8^yAu9)7B zTf8Yu<}{}6Lp|ktvY0&(XdUoX598Bd?JV!?Dc-!~)P0T5d3H7kss$Po+M&X}nAp}R5SH5T=bTqNc zHy^ua@}KPrn*2THUF4*JW#&jNVai#%uP{i~=gCej8s zcP70bV1XG(Yn7$y936GYjr46`EIuh0;i~HpGi{l=b~30ptn{ zdiJw|4l=l}5(=lal51$U`5%S#1 zU)a;@ypowhaf(Q{xaGq#nun9c@tBycZlIV~OOy4ivU0pt`muTlv2JDx=<-6+FVy3) zd5-C3z1r?Ha({BA%Je%?1p@CSVr3iJK>Q~0#o``%P-bv?zYNar`Mk569v?c;_hA;> zr9%?0m?R9_!wpUwn>U70*yoGI<_#<|$efH*t=}NxsIL#K?fusdr}E=t4erN>(|u#u zlXY$H2hUebm-4E;BFv49i>|$%pLvSeZB916Y7a|1TUn`Hf@-h3Q@v3%Yjy_m&oLre z8!C)3oE=;DB?!)1)j0j)_~p4?B-=E<4o&AqhP;wMI;M+;Co#>{*HEmxETIw_DSv|| zeobM$t<*suHGzE;6W{U>W9(=t^1joJztw&kPiEC$+HifqCr}^s3iw=2zTV`J+0jnc z%(4Gu=K?J(cs~vj4ih&eK3Wa249e`mcePQYeOT8P5t-+R6&=CWV)I%cdpjTcaT}*_ zo@@o%TD@#P*sPi-nCmloiWWsjt+sjN?{;WQOwpTQQ)JUR=*>hj5Od;G0m+;k%(WmI zZmK1W_vYEDjDq59updWSsFR}dX`xa*xkxNk)oOPQ}sB~{|R|8nCYLz}ee zZiKetTyI7I$#1ESWD`1aKJBIEBP|_*-1I*q1a{^G`PQ+Uksao^5LZYI&9~#Q< zdC;Xim`kTzardjt4RosGJHFZDVbUm7`s3h4|H7<)Qp_j&Jo2O? zyJ(_A3_>vn&hv7sz2^J$SA!?SQZp3iS@Svl*B1fogIe>s+tPD5s@nsN+WR{+iz zi!hJ*>D%PzuRX~qAk#4T%lNW|9P>9*1GgEbYrfXgD#VwL!7TB3QIC}tS)9qm#f_WD z_*V9iu6h|3$zpqylUmDTUcN9#zs+g)i%yuG_Dnwa-1IC&!|x__zC9~kPKlJtMNl3N zw=p0E>{sH$QANEwgfq@d(RdpIvPY#*SFbl|=bwA+g%PJ~O>)@X6e}I2rD3-{bhC)-KQd5AGCg5}Xx$w{Z>XF; zaT_bV$sj;?B$HB{z3gazseK+Rl&Tr4Sp&KQ2}ri@eQv~wm`Tb~phmHNQk1?RdJ^Kp zE+s&u!yYC0%vMo%^Vnj?cMy8k8{S`_q%g$@3V##qd4QP94Q_f@*Xa*#$N64FX#+9e z^F6M4t}qn?xx$nn-lt0%jVI)+;7h(5tK-F@P=n&E*%pZ&3}s5r*|K@h%j;?nyn)zS z-d7mZRu~ZyU0uHH{f|S|bZc)&%kgyJWHXSrqfb%gg0xo4=U3Vgr(SIxRYx07Tb7Se z#ijz{3&WC5>&bI?yiGjtXm`h2J(06*Y(;#R-Rq z=rdt9n=$DTo>2n}SwPPvD)P?pp5giiVrzBk_sPo2@_w_ovbr4|NljkIcY6Xgy6JSF z1%5Udu0ihW~oohMK8x8KC`MlVCw*@?M^=0~y0~ zZ!RCu#o>CW)c>`-bGjKnUxcs4ixnf6KRxjv)arQ1;yjnMCxa+-mzF4mVHTf4F^YFI zTbRtXm~=RBp}tqMK3HZ%Sx{wbyKUVdQQ*$@Q$AJcE3yD6fVX1C4(5&6lF8lTt`Ymt z2Z~d2Q`&_7HReW%hr4mVtwpC&)?=B)bhhHDN=A7hVgk0sx~>Mth|ac)<5sY%{_1C$ z>s3@c&V){d>S_$z;M(D=C8_br($AVqZ0WPyvJ~{fQ3H3TZb&N_I@NBwg0k>(`CQIW zQDyiDgV|-;un5j1nOoMgJxk8odc7r@n?-PSV;J<+@V27l)SLtwzMF4SMMo7EX5Y9y zi+b;9;PJIoK5bqqSJ^Y+PxUqV6%O8?4M9>9lgIQMEHdH47>%fD#F?!{{xBdDpg@%x zg9`no%oE|}MrmRNZvkP5fH;_}x~0xR)*brec})Ihrl7i5Pl!!~IHftB`>Id_?W2&L z9T8Kh#`51b!yUG_zcH2;FlkWA20Sy*D4!`*)s(^ zpVbtf&bFr~s-jlD=PfU-0gj%jlJX(;o})vxeDR?QZ6FHJM9>3t}q z)SV~rU27Q~gfAu)2Mb^dWTrA&q9MOYy|6p?mt@6J?iNe*)9e?<_=4D0Qk`8rSRF^o z8f2n`A~Uug)6mB>lCC#~M{M0=Pb%pZRW7bi_fmfB&lx1LcIYUCt8lqm5p;y_?#J;T z3wSEibJhntKbDv3ADRW^D>|?tI?dx;H_W$*uB}{4hTa z^OJ8Iep?llTL{trBI!j^lB@0-F0SiZz=t+%px#H!@Pa%Xj5@uoChD8?vy&0EH(WR& zncCF#ZJP^*a!!cH zD=A4_t}{;G5v^CljS(u&WT=mRsFg{?+gwSY*%vD+^O7noxjtN*=0n}Aqu?asx!811 z9%y)o-q~$)O2?zP@CkUl-S>?1p5G7de+sIEb5D|42gE?Ll?D?rBNI+O>|3_P(k|8| zbKYK$gLG=Ia5hd&Xcy!55LiR~Q}?Y6-&j>k+~SkFYFySoqjATb`=qVZHZZ@&-1dp#E!gI3Q>1C&O20wr+!X+WO3O)!4oG*V>p}YpyWKNxOg(O2%=eo*Fp7-r%Df(xMQ%X~kw57wA4%hMS z8(p^74Tr3*r@x#Vqqro`i}F%G&Qas-aK)VPQVDI(P?$Z8_Dm6bJ+v-6eGP>v*I`%{wRgvnT0agkMieJpK)TPrA=NKa1iEo3GDqhoB39Ub4Ik%PQ%OX-0g)TuvD=oemrr00GP3Mg*)RT0at;A71U^5u+ z&x52(lt-mT%hTK1Ru|&4qA!9K1@wkAXi}A`>g4I;GvHiV>~{;VLyh6$@m-D*c@Wbc z-FFTNy$q@9M~^>D_SJ5`3;n((UbJ{BMAusQLWx(>I!`az;YiHM!11{B!AN&~G-TYH z;g0A*JoaEZhE~986yBjWqeK3xg!#3Va@g(m_qWeag2Y=^^3ijPtr0=! zk`hx-fkdy5a|Co$?Yt)ntJkKO&FTjSdwW@t9i7&@vZx%?j%!!!JlmUvqpxeqs(FiA}(ZZ7`B}B?3J>ZtHu>I+|V>Pv)kD}f6HT@RhQh9 zE{GGP{g`OMc4t25_!%py4#DJ5@;&*-u8Evlo1<_6`MPu6I+Qy2SSGj8keC&#-T!0j zt;3>PzxQE9kOrkgx*JL9P`bNAIz{PDF-RG@bATbGJEVu990rgU>28pIx5wi-=kxu& z*EN64z|7uHuDzc7Uh7_&U65n6SJ^^^UdOJ!7{-~Zl=Y@h9j6*Ru-(G_<#lxJc!r8b zmKSv|KfQ|M`|Ok~*48zL$n~Y5)Gbl@0u??rX6JwZM#pJvtz3@snI|caMd9KjGu)e; z_yxGBd0tbw7Q+=3JHa^KtwG$;*A;g#KA(!7dDz+Q9ZuHM`&$Wgt770M*!=0EuPeCA zr;fEkH>VnW#ComoPUT!m5P}c9F5ee#du*$jvHkRL<+n|1cFy4M{Hd>t~$PRfCyVp(5hLo(><>cNOzV3)iwv@;?%sEM=Ws^wYw`*GMgJR@1 zZ*elSGPkdp$SQtTW%$zB`O+O1$GPXdi(^4M!f*t^my)kHic4NIKK}krO}ObJW4tjm z#XU9kdR$j@f2yR_M(*`{IF+CHS!k+UgZOS4C&yLjHH=Ju`*xzeu(yzFCi~@dkCj!X zv8qghHR1J-*~d29mn;rsVzxHJ5`3#uB(dDH%JxzAf^thj6vc+yyi2-UCuZZ(+a#5P zi~0%V*f)Q$07N2Wx|@4qhCBECec#@ZV3ZX<@7DZmqpp=<@*DJm3cn}BZtclKjTgKt95H2jeWA__r($GHsLSSlB&@+Q(>->nd*sOO0BCA_-ty}$J z!n)XZ)}nXSesez;DZkFuw5T)nf_WW_d`&&r_cF!3SvRt+iqf znt&sCNal#u)^;}Zv*<$eR>9A=^fn5MS}RZ3r`ob>G)!lG0tZ(na({lqju_SE#(%`j zfV?x;T9V$EA?$0|JS1zXZSiwcY+Y+-TMz>II7lYc=#?$hrRCu}+qIia35%{?MQ>oH zcU;|hL8iaCGch?YdX31^Dyo1`khjbZ77ct%4l-$8t@b&-y=I>rnuM*7i*stE6DfMl zFmq%YvrinN4~>*(u_HOQOqAsaU1+khJL;|vj^zg?mXMKCrMEMR-WYw(Q#g+`*)%pf ze_8aIW&gXm&4s{}P+J@9FsXL~64Q1j>8#aa-NNW0S`Y~-XkvL{{A4(u4(t-n@Las+ z+2tg4?_BSfzBvS>6}+`@n*PRB&ByDR@c3TNJ{|(S$nCxiNA^s4lUl6d78vzqh#ttf zWV^lOQ%S;TS}=mvD5<|4Hu-MV#RH@8vlnD{X`!>!#A~r$b!VY`U}a_FKwo#HCbEI) z&M>zbyoX8L7geh#H3iXYE6XxbG0UdHs)QFM7d?=1a^Gk4wbgB?6DWnJwuh0xMa`IO zr-?NRj1)zfY-PIYUaOD@9ez1=Jj5v4x+e3O=pOrYWy4=fGq*GD?a*<&wUS;G>cYc> zOWfA+^i@$2@^JS!te0=ow8!$oT}b?>>p=vT2*{@X^=Vf1bvjkYt;N@sr-2JNJUSS+ z&(gs?J?Rr;*D~YTpKH#xIiR^B21gCVLr)xaKl4>0yiZ6j8M`Ko{hFZ|+i?;SYP93e zRS4sSNetFz76v=#RlXL-biszXXD>|7`ugf0>ZnZ5Bj-v{ETqf`y7E^0-A44FHt^7< zNgDm)vAx;)P*wpjy5`;GrT{4f{ zXfcl369k5DNgebBG&r?h#qLem4nD#?X1i)wJJW?;9#}VJRULe^7x&pb*xS>cP`z_Z z1~zlaw@*1nB^a-C%3UeC3Io`?-YVL)=Uj(mMpZ7(;V2s0= z^|xbjIXM)LN!KoyTvKJD{vL6f?Z$MdqkDm3r7uteI}UQzO2u@J%EPXZ!lXwj^zUv; z9_dy(AD67PLR12{DqX*Z%s!{ov%B^b+WblAWj}t|9miRI<1f0)@PM}xZY`g^W|J&f zj@u03DP5nhrfg|-`jWQ4(K4CS8SNML(`Dn0?Wlj+#O6XhM#q6BleAq3TKZHOVUkW6VeIo*N>PtZ>5WrIczG{kvM_L4ch&No)A*UQ+xNJfP72g8{tu8n zNI|=o@4CwunlD8H71(G|mGIu#;dcfT+jE6k!ib>V+?+8bDT!A%d#!nga?V={Eny8HfxOQ%>OuzI_d#~mU=8>9JOd^Ws`WiPoE8xh~GT) zp2%&8m#J4&NuTVcsv4e+G#Dyt+V`s>>mN zy_()y&J8g10X?ku4-k>sn3?Z^u~I#qXw|dbDc;%VoD)sE-fT`V`C>nd19lQk&c#m^ zx&lYq#un}h7hQ^RTMu!OdhYd=Kfz{a0b4nV6kOhbgg1Qq9?a*)3isQ-Gu6wcxhfxG z+Wav;aB}B9MVL;8ZJ%lqUCMiQ>=%}3cFIfRGxvS-%05-S6s+LF^yYk~XU`ENn58)D z!RH*r=cjm1s_nsR-k^OPs4!2M(7da;0LvvMlF_W`Uz*ws-~?|Icda_^8)#maW9BB) z)2+h2o*qJ#U(yHkm%M%jFEj}__jI18C~$_?vU)_6Fc&5_s71~=`==+j)wyimt(DDs z(?5GFt{_;MS}*?0a2)KktQuXaI6h8t6zKEh5>`T8m#p@lQAPN~#mU|GIEF6GOV-zY zW2szfU0RjGu>Q!7FJN46F)3AV_b9IAB9Q`CpN)Zzy-*YAs9x=u9lIqe5p{7QC9(&P z8E%P1Hp_!jU0;laTWP&_OT@EoZC%*>n%H&%p+ZeET{L~vYKjZ$W87y<{a!SLZe60 zoVL7nwafyp`{$+78Zcn1-RC|<$Ue#<>qdH~-{CQdY}b{aeHZpro7%x{(^sJV#sNpY z4Xe#b6^vFU>qH%^4ysYs*6&48E0?FXW3`n*ROS!CvBA~S_#LTq;uYZbM?YcJb+ZB# z9pJLNrR&t2^cB$-{?h6CY?lDfmsj;-aF<=4!kBh{@6E2d(g*n&Gl9Z=Fb%iQJeBal zbPK~m{?;vdGae?hZw<@xt=qv;6pmZkM46{EK7j(oO&8HO)Yd3h7-LZ{h33hXQWs5BFS%q0%x0?c1Oyk8h#Fc^cj}Qe9iHC`~-Yoq%y@9cXO&Y z5p^ihg{CpELX0EWvUSZMny=(zh`s+YF(LqMe)`|fMkHD zFU+vI5+kCna?iY*W>e++W?rHkm5c3V!BpwTJKM#t>8qkw-gb-Md_8*e?Q|>G2cD{Y zi^Fy-;+pp~obGW!zWK@7Bf7a%^%M}9E@s~S+?$(P@kd!it)5!@oM2iM^PY(u9 zTuF0@j@@)*~?Ll_in!eIC!Vou@Yc_mYxP?hEb>utt;@+69ITY~ z1HU`+`hY(FnfB1o7T-SJhOl~8p|iEnzFRXQ*gZL!={1kmvacm-~<$c*LSjkJ|km2PEV1>S~ zFS5P+J)g_|+#JC>ZCS5BU-dl&JXs<*6n^gKQc$|TogB+G|Kv%zZ>}2Yw8zr{?1(Q< zxKSQ4ha)F=dOTE4X}Nmu60~aHn^xt#W#A~WG_)OM&~6bOdlFCuuey25(DCYIn={jl zb$ITfvOe{xVfDA7m}s8Js8CWC*u*P2Gjz9f1F>w1Z#d4^>j2Hx4h0Ro_Vzr!2;BDs@FVH=^L7V$CY>f zF1?l5HB+)aq`=fiRiT9A+ZHQdDz{l6YG8}ssj;|VAdPTG{b$%WQn<+R>@Fy?ld0xn0zzFtuw;{zd zK1X}2VTJ)L3V*Nw{&nTGnDTcHYiFf*Si^oi>D~T2D96Ix$(8yN33n6Y&-^Q$Gji|x zW%_8;tLQl3$qb4&4&T;Q3siZmUG%(R0pH1DT3!9)Es@@Am3QYadubJJXdV z3H|s_;1IfNI0gA=(rMYE6_LIOTJXKUUj&r*y;(VsbL^F1Sv|svEcYjF%0#IHWUB!>QsJr>9-!R>OL&n!1zyrb)HYn>^P(^86N%d8S6X zF3Bn@4Xwk}Ypyk5H<7IilqN^EuhYgjoEUW60nPKaDM9#H=1bXn8osz0v+QO#HrrL= zPSxssYt$}xC>nEG0)NB*R6!cJ<*;(CX7p0MyhMYa*KX#Tj?IJPB0Pt!RuG4vdxE7P z47BIEF(uT!Lp9v1JTu0v89#$hO2gOY6jwMKQk496c+Ypg#H<- z1a73US_Y^0n}v}`{|?}vfAeuHJOF3k(?vs~zW1M(x*@vcc+#X;q(?|+kRvef4?RGZy!Ypo^XyS@AqS4%eYamf34tr$bA0g6Z$t9v?x`5L zJ1vp^{dEl4d*#4Ie*YXp@m^YePR|(SpKEKm;(jF3KjZ%UO~?*=bqzv$8DG3ac@aHj&enf@*;L{i~e~1&>B+WgOPIRoU9Z!LdtjK;}`N{uw z^1BW`^XEbp+aDbz1!?cBNwq$J#8+vP3d-cQh-;vF7TBxnC0<(>|@~Y zJQKT=+%Qv%f!0u|_><&!Z0cZ!(EqMo$)!i!%*E+7TW?(-7CQ8;vYk%Y=`e2PRab|* zmr%cc3|nQx_u)J;E)bt%=Lr#2@3S%}#gj35zT7c^t{sc~*JS4~1nd20K0|CDGp7_r zk7$cQ3(QMGm2`c1G%y-@Lg+aabgQjaeIFZ^B=1DA87#$Rku;eCp=Mo_=?fNoYZe%?!XO6XZ3(#g zJ}=X)l@QUdj6>{L3J_exbR%J$oADXF8 z@hWKbYH10%WaoIK0k{fhN#K}1B{ zyZ$wao!h@!UTR_Sju`|ZY<&Jgfcwb6J)Pj0P@SFAkrh?mL9aJ^x( za+P7&XDv$ZuxTre7YkM+sV7__SW_wRCC4-hc3LrHE@LSn@HxdcUZ=`Kp80 z-t4H0Iyr93+nilTrV88`S^Dx1O~fI79w!&eMa$9Oy1$F9TSj(D82`J&Bws%EcDo_a zAIB)rO=bS{!MYl0)jFbb!S9JkVE4=+c}ENJ)hG0wg=IPN2e{EYW7hgts*87l8&c9w zpn5zpW_R<%&KAkfX{>(%fC9 zdSIo)2UUSuY01$dRPHpU<;`9WX_W*W6aro|YvwH8rGZbH{YHAwO;{?nMSSKW=4o*G zG}?P$MyPQb$%Ux0cG_=_hI1&!i($d&%Sjt@D9d33cUZlaY zw@a!$+iR6g*n^kNHzfl`AJ54_!LNA+@qN^4ju>diL~?nTo%Sp^7A$z&B+@kz8#V=n z?F$7$OXv*fwp1E7B1?*MI*kMt<^#6bDju3l1+c|sn(oA*So)2i!x1G^yO|;}mDb;y zKRrv!6~1)+4j1C}#UWwgSh=)BQe11?_M5CE5sJ`aaK{Y9nyc{{9(YODaygRHD85k= zr9oI_c`3iAxbSsG@Zs)w!SSqkqUU&H*ke|)67AESCA+(`Cv~sC#IEzzfK#deHc-G0 zltgDzH&?&fm#$dA8 zXti7TX{BU=>KszpcxKdDd-?^=MJVP6QU=id<-u~|9q|nQt`>)jnQq3|RIW;mwCii= zjbWl*N{hGW=EdR0iX^TUIWU8UsGcE%TifI?UuSSLvWqi{5(&pW5gR@4#RVprHg!DZ<>#Jc$DJ=T3(() zdR6ylo1SW$)M!zex%6-3P?Vk>R^p|=>$AN2Zy#J;oH{$X?Qe7?$}zBESEy?{sQUTb zt~~8df5r;UQ5mI-@$t<50no8(`IuMjW`$SpUd$3#{_85LOQQoe1SF6T#xVAe2$kdl zFKWG1l4>lYqRZET56EL)Ln5FzwzxXA_NMuhnTr3 zS1=2}A`uA!FMQjbG$GnR?SOXI)j`2U|8XE|GmcIU(0xeC02R&y>A}Qi{#8MDfr5e! z(0Hbxi`8VSq8HBcm$&;tcXZ1@Iv^@8rE*_FLV{&~Oxz^c{2+!x1n0>!Zof09YFir{ z(5zYDMR;?A{rE3kb07npt|fzqhX>HXmof?bxrEA?{z*dSyYA2V(w7a{JiI)b6XRzf z2Mq|7M5E8v_ZXd!uVwy;CAt_kdpi>qD#To)x|vs42cM(b{aIvt*^Nb8yv|;&8WbtS zGoB8TvJh5-tWI>MWMw=2=9idKUDi9o+h^aK80!y3%d=!S>W-JHoa?Hz8hTLN zYET^eC097e@Q38J8CTXD={Tamd_`>=OHSv-=EP>tcNV~SEk5F!muEDkyo&$NV&nsZ zkBnpL6v>q}!St_L5QE4`S#drLw5|Tr)u2?JS`M#GRquBxsZ(OLRz*p!W=H3sk3H*v z?g5Z=e)m<5DlU{Eyvc1{HB&8O4)o*n{5<=qWuMn#05KKS-NDjx2T|LR48XpfZcn)Y zV^v_TKms$_0_s96`0ckHkBG#?#5{cXL{D9PtmE#s1;|)l>VD6q|2gbg7X-eu|J!qfl`^*PN2gXbQbj ztWdl2I(9#2ShJtL(v9mV;_H`|B9)A>#H5SqDUtnxQV{6)G5zrT6s957TNG1;H?MYN zkyN2g_T(E&5<0cob#Qrj)8s9rp9pB6K(hkz) zj(2ck@{SJTs}Hz?V(PWJh$I#(K&bXCQi4S~Ju7Q(XNO%r7SII&68ZP-y?`PSDhdkd zI5_Q|yJRRmzUO-!{KVonCt7&5xRiE#;{JCx=TOrsi{9A=msnEXch?zWev@CmEX{i@ zf_WGsrV9%TK~$_-%|UnV<>efNS*ih-Cp3C4ZKsn7ELs+piyMpSZ_0HcadK_EG{o}# zgE_^L=~nLLh6?ow2XpcoZQ$(14;S(M{xwdAXQ=_LtjsB_0(QrfbhuAiut=YdyL_m8 z52kmw%f(>YS6f%3eClIxM67@s>oBoj8vB&lr4dC-WjcD+lTm)8s8dG*8P z>(=|^SmQY9A5ZR62pl~PpOcgTGZ037T62Q5lQxb^yfCRWx=W3h`xUOW9$ibPxm?tG zAY6T%>@-?Leza-p7>fPxQIGixG8Trg7iDf@&~}QiE6Sh@q|7$EGDs(`eRSWV6^zkE<$~P99TtIXeF*f!o3hug*SZ+`wTiH+L z3Do!;{01nb09pH&fOthRn_kQcC#eEA?7k7}HXbQN`KzJk0O0rJ9F1?nxH_<~uy!U& zrvSO0j*GSQBJx&^q~^L3z`Rf>IV9l`+QmnKABHv&c05cmqj0b-G)NFWn|V;DvYWJ< zhB$ofRr)d+Jf7e=a_TT;58vt*r?igWGYL|bYAzTU*TZu%-u|}!p*c-Ro5S|x=gZ~? z9kLBLrzLtVB{lB%x0cDj6j7z=K&;uqefTX0xsC{XDYHx;_|G7Cm12B8vCo<@t2KHs zL>LH(q^3?cK4Xoi^D$2n(UfR^!jfrhlHrSQR3XfT|Ol%%wCKarw! z==>NQ_P&BdIBM>)b-&I1;8C?dJoLS=9u{f+kQcK75e|v=mp<7?jU=-U(JfFK_yx)g`)aAKzHXJSD2|x#0RoJfJ5?$6iIc=;D_u%NfD#J_ zy^R2`Hpq5>&SuvtKSsE2e=6s_jSh^#tVKDxyP~gj;!WIC*Rqaczvu2&%HmJ!nJyK- z(9qZ?b8UxcEZr;VQby}#qLf-AH31wKir<~sb++D?3J#1mJ-CW7l^3XKs2S4DjK%){ zjaV7V4SXMKf`?PF*v#}34#}Z_dCENV_OM&cGjCD@*;C2lWX<3B>VCwz4qTGjbrEvh zUeN<5mWLU1g)ibz(Xi{ilIer4=_Qx$nPFhr^0ylKHo?rEAPx_JM8h7M%{~YwE@IGi z?{pAs_N~rx6rx1)C3%2$bf{~jF2X>1ELOx58D&?9#Ge;hV!AGHipafn#6<}=#khR4 z?X^xAE#aUwYW(VUXKv_AFKAw(j_$x1tqt`RywgLbt3P95Zs0`;CjzI_r=a^w^fpV~Ma0)qXN3+0v2$OS1 zs5YaYq+};hWo~Y6u9yh&s(dS2Y+EBwdb23^|BtNyVjOq<(^PxF#b}+~SjhIc=|ys1 zyLi?hc}K+zaZ(SSs*9OO04M)#;C{6G*}+LQ$Ct0H;bD3mECKV0fY)62R78U&0ZD`K<#9SO7gJ(Xmpa&u8(o*$i_^s3 zW4TzQcR<-ne7|N{6g3>2cb4SnUv1$Ch_0xe;gqv7+#S!>ThGR3<4jG}?l8QAEf$O^ zG6w&HjOILh3?M#<49uf4ajtPh-47~gmw6I-WUG_VhhF4fukM(YoVa`VUUC(wk+Bgd z7Ze&_@@Q5dlIsU(&l72DtLYh!l^8La0a34Hq|bqYfdvu@F@630+x`n}e!xMfy+9t& zBm1TAGp)Mi1qi~h>6UE(DqZ$dB3^r+<`IYl+Im1Gj6P1(ZB1D-*Kx9priB_!;^rhi zIvRVr1yBTQ^E)TywfPhPEZzc}Uyro*lb{Yr;J58II z|IgPYGPFn@4!Zd-!r}1=07q8&jb~Cz(`!1(dg%wh%`M0*=;zrKRg#l|xaFZdmn}F^ zt}>1-iEH|%yP@S~y&?tP(FTYS0gTKdt3#pEBKy`#4)%WPgp;8Ajck*{mxx@IjA3V^ z=!{lxD{@?saM3I{csL>&lhOMqr98|w`vSHq)iK}hf5c9uhRRU$dcPxZIcn4xT$OUI z{;c76c25EhQ=Q@SB5(KaCCe@;K-d}CuL+oUA*Im|`&X$^kWVWTPI`!^(~6i?y|c-y zsVQPq&{^~7+wfA|8YiM0_!tGBG_Yoy}@FN)@w-O~ZvHghoJd-}~X; zIDa0K`fC*>>4Y~7gX@euQkr=Q@d=5p)o5P?ySnz~1Flz~BOR)*Bm&uKgjQ$f2R@|> zHkN^9Po&$5B}RSTCM9qR@-8H=?jKH>1v$?(YIKyh_l}IjgjVq}C|XV3WZ~BVf=rh{ z8P0)rKxqt6kE>Sa;p3y1D%CB81_Jt3@CK_g{i+{SLDz8!2?d&v+uN)C?4aA}`T5M9 zgtGE-po*Y;G)tT;Klhk@uA<7raJw4O24Zhl?3$xodDss3k zx65{m=Z5gL>+HZNHPt);e|C+*VsaTfAB~7TP%XnKoRQ~|cRczx#MU!w<@1J`8*Wfu z$$1ek>fxj9bmfPRsDC5<50QV}_!A%@#$V2?xTMp!A(OyU{b>wbP5sFV`{(k9rYcv% z{q_f~65IlsY3V5^$FKOy^;|5&X}`xx;7;xG+4)uFU#(y@i6i~eUmr1<#YxUbiN57y51UFgxQhlY}` zaCX0z387f|aA_0-ispYSJCP<8V#F;Qpadk+m=qYf>HlB>cl&MUrjMf!CXHO08XH$$ zFXYK!Iy!DYk#+hPMgEHrA)rG_QB+_A5P!!(EG+vv&?P~wP;$QJ+az{+G78wtx1_3s zaK~Ms_N&fo3+*pGuDVG$lasEg zPsv0AY5pr^f&#-qQp*HKWDd((sa5wRh3DLxA%8I*|1|UWn=F+a^R)VRaR%P9cs?tx z+VnC?A^IQ)ffpe|FDnMpR2d?eRle{jL*PZ(G7klz$B{zzWUcMc z=mC=VhvdD#*xo;+81NUhoX)h#PgQFe>E@?&QUmltiZptl!YF!9d={oRFl10=9`%8u ztWf-5f)e*Y#pBvqmIkXiqB7M3p8BO>Xv|;y9Ye%D#{ahVpcxGS8{sctq|BG8NqUi+ zUsIv7?Bn{6xm8|-i!J@<1RcQ$?#eio@Zqg|FW!#Pwp#|{Q9U!1u)g{ z2DPd@X~x%F0+i@~zVls$F8CDKnyvRjq{SbPW{Uu^1aG8E1ydwZjM#u#`gd|#(K>OE zgpn#`_$0^MiFQZ`{#@cWWBomvE*OOv1-MOK4o3F>U4{3MxKyd{#B%MAM=?15U)nl? z_!p60C&B%nuKj)MkZb(l!eI%vTI7G4^5+e+DG*T*Id$9Vq=)geuaJT#=NN0h zS?0fXCqwGJwZCE$Dr4^P?Uq_b$Ni6Kpcc9B1laCYcHo}L3?FX)X~pk1GHUnef&pGR z$KGuniS5t&`OCTjy-H9F8Qwon|Pd zXOs6SRaMRAWmgn($deLHQp#T=rml_ro%lcVoWq9)_}UB_mp?=F`#_O;8Y_dkeO+|* z#@!%qhA??9tH;QkuHYy`8#bl7l^0gZ+yey8gJ^GXp?wFx7pM0yGPmfzolSUxgfdwh zYw-g76rWci2K36BUV*eN;$$U4H%G6H=cB1gx#VL*jSlt(E2PsOu7bSJ`S^(_#c~9& zaR1(D%%sTNN`E$8$kearf&hOwWV|trVN<~&fst!0K91R%z%r4YmM(FyF?x%A$;_;{gu=j#f(QlqwyS4CKOX-!I-R`e z-=CrXUf^Bma{(E6$MlJ+!JB;gnQ1IQ&EID6J0V_9ys7YM9iL$CxVbRti21|o zo@aE&gsL>>xfq_DSrs z+T`KdaAc(3*kD#MF;<$1k|>A@>G%&pks-8ySKAR|Fxew!CnSNSLU#*)F7ZTF5az7c zmuo`haT^;RjA}(Xb^kpiD3aGsHi+loHD?XAoHH#H?lxX;oY>8E#HVGYZ#DclZIe>|WM!<#y2&u+`CRUw> zA}7kYN&hU$zih8}CUQX)%pkp=5wiK#V8$2QAcVhMzB(SkY)S9f^m)}}Es8BPPV zcn^<`j*gEbBO_rhwzUsJ{PAhJguV#vk0U5ks3b?zJw^p~ zv{q%#mFg8HVjQ*fy!?D}0Vi)jBKg&Pv-5QIYNpo$IvSeYWZ5*J8JzVB3lpss>%NEV zJJzrz%9-SsAKL$GmBA^&(O`SSck)HUmDbUKH6SQrpisn1cw1b-Zp1vQew_U&?W$;d z&hk~lsK}bYzM7s;cF<6?Zc1)p1#LX11Q9Y`tyO*oJ?Cl^rVY;uT{I~#qma%ZXZIg34VWGm>ifbk85OP!iA>E^lwRs8jJnb& zT8F%Vuxo*@?4i=IoSz(ZxkwD~R>a#hbfh*AO@p7EjDu>IKEXy}nkZNJ`}ajfMN_4E zTyoE==K$8`aJl~%!2(cs>swn6=H`+pia0np+Nw%Qu&=8Cb4L)6$!j~3BNYZz78kUK z(`&+56Iu0eg)S|Q!_fdC9RqOeyFUX($?0N%w?9PNB%8arL)cuEK7Mh^46G| zf~}zd$r<#u&VgZCQ`z;hMR{~Un~X-)NZC^!J>_BHf1*VHnh9OoginsKEDzc2R+x8L z@QP=Q2}nQcC?v?5Dy06P5P^L9Yix5WqE6EE<(lc|xg&vL(y}1}^~B>)SEEZ`0Gz zGvi|bb={k(iwy0|my5;0!Wyc>jv8f9Z_wq}{9ItEFszvebmOpz!Ym+6IgXT!=;v&< zo`hNy8WKayJ;pzgpw#LPXk+NSnF1Y2s{}ulP0Wq`c|h5;VyA;h=-P1(q?VqEQK%fA zM<#uAwF$pw!adGShzUhU0}-hKKy&oLGJDbylSgDy--X1o)0vfLfN&L{K16>{&j#5d z5D!z79e4=9v+7A_t%g=-r{Ce!jSPL)wXYdGCPGDWf_E zLXXxr%d)1!=0TkI|HBaYzar-Q?KS~1ufLsHzzh0B9D?L%7>!KW#5}>Z{iA^o1b@NJ zhu0W>D4lp|qeGsOVt7z0h{C8~7UIgP!Kp~pq-=uXyT-%;u+a&&-S4oARMP7K(P?yi z#$T~ziL5$#!?s?PCM^OVHQn4gnW<_2U;%DTsbKKxKpdUI4z(AYLk z)VnP@NfGvN@bzs@Pd5TuK8hOxuv~&?WpW=eF6?6k{$BhCPDsVSqb9w_(OQEG8E6KP zg$4(!2Sc@O5_moD-VFxTo<#O1#C~ifPEy=WW#+kk1YwtPw13XZtFiUM`c zVCqAL)$1>)RJAUPw?7Y;wF;Ge0NCY}Jm(q-c?(e{yNM#4hxy0<>x4a$H2d|KWTrqi zl^l2IDWX3%2r^sX`vsn{ zT{Zb%@N61QtNP&J(pxJCXu(!itl+hPFn*x`plM%-jwm-u9{l_K`g>5pvG;U=Gl+Ty zx;$AeH9o<~eoMXUwV{_&yox#9v145tG|+7 zb--3G<>xM)>@2u6N=Q#jBjwp*L$?fx!&*}!g5FO|J+bos2W$EJjU)?G@G2ou2=Q30 z@duDU5Fq@bcpycRNa2U8Gix#_i-}bGy6!;vP;r~n)CzrUDgsphzo)3*=Tk|>gPm6M zw8^ngaq5X#^omXXV4m0(j8=9uQ6|jf7EJ^5Ia;&?t&i*MMsEeS0}UYz_*lqfp-cDw z=iK;v1TUz61*-BbRmVr_gNpNHCo$;VfOu4TgY4=9Z+3LO5^$6Hu9i@*81tdk)9ngQQWwJCbbA^@=)@s`nsGx+< zmkuDSq&n0L7WndeHYL^9aX>psJfhVI?0*4W39Lx^SbrAs@ADoY?*!mRI?So5La-dD zoyBK*YwO49gg}^|5i(#H4l~$k^(uv6NE4A!8be80QQ(hxso=lCxCM12eS!bE96{8t zDBFvAP9}QBrw`~jEl7zg$PC!*_DaBvb9uzMi5v;XYobX?YBP8nEJslao)3t!hsvCP zpWE&sT~G%z{`Ya1AqhB~)Sq2f!&Bbp+2uSgpf^Ja={HA_ZDRg4hput#Kv?!BqjAYg zxE66PVTz&oIpxQ*Rg`})Jp!KljsGMVFc1G)z3A_%&`XV7a_v8n0>_>t>2u`aw5`anmc9|3@?`tM;J=?54 z3ylu@^s*CAvj_E%omDr=7s#|ezKZ?Urmr!wFJ|FoDRXnZN9QS_y5gW~K8b_WF(|Zi2;%Bjv>E0`o6yY{@+?I*No1b zx%b?2_SyT{&$Bl@fGW(CnXpj(cZdIO@%J$G$J4+=MF)f*|4!qd5sm>3M{0#n%~f1{l9}o;Q;cBY$JJnBG|%Fz(V+e`Cot($PHY}&n9mczF%>T zZ^Y{dCx3R63lV^*=pi}={|=7<_mS=4A5aZB3{Z_MmwlrCFCe1PhCBT2Zyxdkzd1tw z$?d=Ygn^n5*nzQKlmTr_bG|$A&OiB<-;oqM(z_|xqyjTqavL!9=h^>$fraz%k`@W3 zn`zf=C;Y$m18~Y+JncW`czW)#vi;xt_h}t?PUD(zzBV1S`1jWN{W{wpCVrWXl`loW z`RihTT@wui_JbF9UE9af5BB~%hTkuw$Y3yIU;geQypw?T%|@Wh)$2A4$Mn$2h9-jb#YmZ2o6V8bJhIg$d)pUAZWi>*l!dJ{j3h<qo!^tYryza9(e!zQ-N-{G|c=#MST&6o}s%)Gy{biEh zdn*p3wer8a{Lux2i;a!TznF%%7iSsJY7WGanyF%x1S`g~c8f6>sI0$^;li7UTaEe9 zoA+9aDumw77My{#zmSXik9ldOfB6;XcE;ILt4X<8yrG#sRANP|OC7FB;j!<3N+C}e zSmc}`s%-F5;G-ymq_SiRn{2#pZxw@#tDKwKc!TD1`l<~ajLL*^(q5yNvW#?CaQQ~Z zKEL5Z;NF$U(Sl#pueN4Wn<3Sp4Zh&puW1kyAiMe4T1f5l{P$v6M1XrVQ7In*k|Jms zkCRrCrBG8V$MQ4^Mp5bJaKb25S*=T}_=>P@na4fTpdvf2P7PL`=&Yp<_In3Ai1|~6 z+XKuNjRt0-lrzmtR!+7t>^+p|Wh=^ua#MRNbaZduGfN^U84T|w@Kr0*A0%)BLi3Pg z&V)Md`)?DiW$f^wOJgYAIbGUF?rB(}cLOkaJrz1GYnX zk>08P+NyRiZH%}87UQ5~P6Q35YyYPWaZ^{77}3&&6uY|8C~y~JpJulha}#n76~p>- zP6ODLVxjp?(l3P)G^{Hvzxo)fFH5?<;HS7}UVlN*c--12?QDRda%?eyK`g#d>vmiN zKR|uSl{ag(D2jF}(3~=ah8zIRz8$6`Wl- zPc(G6{p4L%EKIqR7~aRp7}7IEGq6UiDcKhxvj(R+FK#$T!<4Tj-Xz-eq?o23CqE>P z>9$6Aw@R=XV7I~e1k<$dY@X2|z>Rqip2XXbo#L>FoT*H@l3^r9C*q6yVwh&|I;k6m-FlHsg! z*kTCmDQ&KEjO;f;h}o1^TpJ=7KMIg<+mGw zv&{TCa#{McCDL^i!STYxCy|Su7dm#)gKUHr0XWf+2JCij0No zgZ1A}RZD4?U$-8Lqh5!c2tD^$L7I^PO#Hpk&_?25*z5Yt+mBmMS-Pp*_}$EY z=EjI7{x{o^fOmJ&Z@C1hy?BZQY3%82*E1T4A4986TdYWSKf(}{ff;NUU$@iEbc_m9@pbX;;u z(clrr%gF$U(4H>4wV!;d?Eur-VmzN@lij;(kWST_`$~@Em~wIBqm=(vu0lUd8DU2p z5lH!2$|%L2l0HC*N-$vL`|X>~$>$q)ukauxT3uVxKncR_yEgwdGyCpd`)jYp#Amt2 z6ajr7TbXrmR@o#$cEUL26*q!F$GZ#v#Y_Ongzg16eU^E!ABgQ+iSm%0>NW?eL$gwI z?I~2)q~#QSR*;iuqhDgZgXHUqaIVspNF90`;IE6~C|D4bNbN+@#Fwa9U9@SIxGjW8SZw`x&W;|z%9R!Yd9GYP2Hl_UB5btBzj1P94)OB|_MGJ)Qv4HJ7WPo|>Jd#b#@I=<4i+zrNh zEG}Lo_M*pZVB7QX{byxwehro*ve-6FTKZ_t=bE}Wz3;su|J5CF2(3eb253N&#)+K2 zR7RYNFX#r7cqS$$DgZqaz(Z;FysozT20#*CH%C1H5Xt9ta~X(D4+BzxS3nqD_fX6S z04r%?$;rrecXz2|;z+F{FmG*a2VxkF+<|WZXcJ>>_(z`@;qaDjy#)@lGAr8O+a{-Qug`*AMC$-1EFU7-65|i}a&v<1)DHS0GMY zLmhCb-s5qey@_UbulCmBCYc(;riZtWbcm7l;JznJ+lY+as2V!r6F1^_KTWKDcej2P zgd1jhke`Td@Z3Eo47D}`T9G>@OE(SPfs|Wbr$bTgIOEmxb{VG{{7_6N}r0+Q!$ z5EjY*CimL`E1rwEvXu>=BBC91xro8I_Zi7E!>I6jgl6>`*x?&^o9O43&EneRzu z8vv>rbMvJ>fEig?SpmTN-SGgkQ4NKt$xwpWYnSd|d_b}T7;Afg_@fFiVZ0Ao?!5q5 zlheuB`2c{)0T8Vopis&s^BNf+C;H}x_&zj=PDufPlY4*k3OOaSDHWj4on|1Q0i+|x z{?a=2Z9WQl@=?eM#WQcKj!)5Z1KI=@=mV1YGXwvF5Wo``%4hI{9EqEBQ70?reI;b#eXKu8_5CYdx{%qd1$j*6bo7b2DV-aQqjT54KYYs@=yI7^b9R zENGY4AEA25QUKV|nn37T(Cn(;vE8^6WXbP$P^oe213M4n7Q`#ntQ(Vx%JydO9 zsM!a0mu%VmODO+Y!e^%v&UJ-Xgjzmj3%UkC$cdyUPxgR$rUpj7DU>7k~iEY@rB+Fz&(!eKl< zJA(ii)n^pkP(q&9@Fkj6{QzxVWgmddfsTgsss%t9`aGc1B#D4q)F)QXGz#z>&{Xv6 zspn2{O)pt)B?mF3*?1O`q>+S##OxRTR0Jkn=)r2deN^7p5hl|ZZr@KW@Wu?65|rHE z4%o~j!)BboMmItY7fWBM+jp1lEle?szfdMhiXC_f2vF{I$8ERksUvUH>lOOFi5=N2 z2qF_FUh>|07!u=Leqymx(nJB3lnG9GHP|5k&|JydDzW;ql|AQcPT&S2dSA9G4`@*8 z1$1OwX+k9eJwHe?p0MUvN-d@9{!C}dillnKRXI2JfO}o`@K22Sz&An);JU=%^mi4g zeGsHna1{`^7d$!y)MT`M_+Xq*pLOK&)~veR!yg!*PWI|Z&LeB02iw{XAm5GwAUz;e z`|;zQ(zk$s03u$8ul|Rprw&d|cRQsmrtBOXlk@ZQ-Q9lu^^@gB13)S$Rlr@XT0!&z z=+_HaJ6)j3EzqymB8#7iDbx-O2KU=%0W2<*55k#GiFi*>wL-IjMt(*KSCu1cPTm87(UlPi zknaNEqi~Ch2OD4)155)-)Eu+KE72=I*^2D@2m%rUk8SfqA%4KyHcn?$^$x~R?iT&y zph&%d0pUDyh2fbQ3<^kr6ta)n2HRP9SR>m@3pi{yat>z=hL^%*h*|TEjnwVCKV?yy zo0A4;nUh6`l@68~8;c#LJz#Ln_MJ56#9pzs5G4Fc^*F;3iq7!ku-12qyQ#n+Y z-klG^`GaBky@PHBmjt)P2jS)?Y0v*bAflea0^2No$+2)^N>wT8EVdEK5a~5LG%D7y ze3@qnjd~^5!np8n-cL@>4XX~~b-jzf{Na^A)G`tJq0w+u6l@eeXz#06KZtxS;ufLJ zWjdM$q=hL2<&$2CBu16!wGcmlzP!ILXH*~n3d$bCXQ- zx;>kzlw{TFU#kTAIpZ*D;t>$^CtlS7DP+Dpb$EZWR zW0%fOb64-So7n3< zyJ7@wM4lKm?RjV`FI>Zo9l$3S%D^6M2^4Hb100)!Gavw2Tq|_TkuQ zMc6K(?At50MP0*%klxFW8xhIYSpD{pdPkrU_#B`z05oEP_cteiaCUZfRyLYg2zUc% zXJN@dprLG-&|RD#kPg={HZ}&%%kzV!)URKKmAFVr(_p@jR`qULlNt{lojH(11hOjG z=XQaip;Xi@H^&2`>2HjrL;3mnZvc5VzsKdFALo!w+}U*hSx=`N@gkQ!V)1LRC9 z+18?Utq9wviQFZ1Z$uhqITIUn?`r_(rhn;Rf1Ne7EV^Q!;NAN63!9xg)jRvJI+L?{Z*v$Fvd-3fUgYixE!D0pVhtL~4mwRUaFa+Z3>Zbjldd2>) zT~L8!F9Ec~c!e$#N9MGedssO&L1p)w%{AH*9W#GHKvRRsbm~}Sr28<=4cvOt$CEcs zaxbc31|#j;lU8)t0>={c{Q%Y!X9Y#1eP9sD<}X}W^}PNbSGgjgU%m?$psQ5c9?+q9 z6gCyISYcoo-d@hX@-s$_Qo^(kJsO1?@|%Q@MGj=+x5l%jjdHWB`^JG}B)Z_GaK4Jt zm#J1C%si!RLF>l{26q2dkx5geK{}6Jn>WH#; zWHf2VAhTMSlImw$ymjNGN5(EBV(Tdcw@79#RYe86>S89j9rZkVSd+ySj6aifz5|lH zK`ikILyYGL|)$ts(4#HhM=Nqqo45f|Jh#u>ktNc<_*m*L6Yxx_813*@O zfcLf<`#{|RYDr&3{*uo0GmV&@Bb;hI7RaX9a;&#-VSmUubU$o3qDtn{bEL^rNSw?3 zz4}z~)0!Q!%GFTOa$P3Wc7givr8 zTsD%O0ofKztyz=qF_gdwn4oNcK~Vqv`E!m@!1V$2AP=P+`g;^ z>wX0uo34-WS;>SW+4iG)Tr1pbzoz*urhL^$*VomTrk7a<=ZJTX=bd^c@aX$@PC($iB67f8_fplyD=Wbvn)e3C!3h{_Yu=)wdBW~k{#4Dv(u2#kH-7v` zC#KgZ7sz}Pyp$S`lHtdt0D-eOHo42UeZr@rx*xx2fm%=W-wzIkT!rMVvo|KBKR2j< z!Wi3$wUFIhp9D)a9%dl)I}&lf))Q^YOKsmanYCEBF_SH4N(+Hf+YFuBLWH(wpqX9} zMA@WWZ!!iE$Bl7FYyeyiB8?SIrl(>uumebYt?#H-z>1DN#I$#{z7R(C3o@Zq6l1Asp zVcS!M6Hk|bvmMtS8w;xvpf%y{1nH6j+;5F$ZvEHufu-Qng`O&N7Pp~#vje02%-lq= zgrD*db4j2;xKctzRYx&N-}ek zKUF`)=doD5ed4yd{3Vfb=S-{IxygEl7ohC_`Shu1_evQD4SF4$WdAxD*!4wOQSx}V+RK{vbJxbS42ATOmy^u&Pk}^l z3^&dDd{Tuc2nA0Gp&rjwpR8a_e)jAbn}-{*Ony}<-BB-hWhcF*oxAKK8H8TEb%r72 zrd`rx-LiO~Iwtx)WT3VgVzCK#Z{NbawO-J$5NB+mz12b4GyJ$HX|lpu>!N;Yz-&$# zRe4UmbhZ)(8W_tQ9I-`2T#pL~c=n(U*1NfxhDl*J+~3Y&9dB{D9vB|+}|kg zn;K)a*X`-OdO+X8oHCu6ZgOUK?zTf=5+kR|Kkr1uX@9q94Rlag=&YNHNOiVOnXR~; zUvr=d*(<2r9kW)^y1n=KLP-8coZ{08{v`)7ZVwKo$)OuBsw0g4L~l?omdLI+s)@%r zXx@QWqfEtemv(+5hJ0n-kNha}B_1(ghaTcpJpX3FMXzubvQQYdPm)vu^@Lb3uA)ZP zrxG>GT4p(T7*Cgy@i{|WW!V;6uHG&UH_SR}ozzT215^)obi@b1_!Z{OtF_e!RX&2l z-Q_$r3$^3dw;RPsPp+;Tr(Zhqlekg5>+3~3cx8gb?C&I9GA@(l;3$i@)xW%Ovt`k} z#_t}iRkioSGJha*-aB=+#Y(qjJ=zY%IpG!eF1y`&0qXq6(A3e&jizBefxCfbRO$7Q z-L<`fQJ)f)a6v70eY?r&zKCVgieHSAxbtll(_ zm>Z=!b_vcq)WXHCHrdzZTF4vt*As~|qrdXF=~RUbN2}Rh11+4n2UG7rGsgAN36lg( zdJUEHEx{#;p46IC+lRA*jMwrDvGo%w2dP4}_RuWBgE^yA^XlcYznBiCDL}fuxQ_Ob zmRSUaNS!7nC{f_GG=Z8yuDHrT?H6o(^v%FvAs41uS`GSGO8PC$@j5d0X9$7_HOoNK z^biAK6#KtqD{we00x`ivi)`qBP3Z^at{CsslXfhedK%rJwWF(WwewW5| zO13uX7nl_#IZE)vjBc!%Az!QS(=W}8?!$*q|GGj_g$P)hC;_jcJVwT>Gqb3!SCdIw za^P5#Di(m9n5>N4nRq@sOZFxt*oc5Lyhn)sNs_01f7UAcU%D^t@>ebgs$Pk!G!7J> zS5%8Aol6S%z@UEuIOT9>MvbVMi0ZW;*40B@PhW7hJFA3gG9RY)SkQy`)M@2_ZuPT6I-4XmWKA*LM1v40Xa6yH_fBlkG_77D8u+6I? z4~&0hbbS||G=9mU6vEOjUZqiJonH8qRTP(_-uV&14(fl_&*m zI{?|%33d&)`nYg_2$aL2uZB}pUm;x5`?5~#e~JCEls+&J(Ha9*zL1TK9n%Z3C^6{J zi80-_3Ft`lnuz{8s~ws9o4@cW80L5=h4hZ)84VOcS85{WX3gL~oyI?itD3Fb|4eYX}N6c^H;L}H|q(2Zvf&! z_3B;)ZX&DO|2OOwtX}2SIj!1hIl}1gEc3620(&%RSum~xtvm7wK+k{s!2W;dVMZF@ zGn^gwY{Di3`C-vtoCV=D8h|B$^GNmbH;Uw93%B_%Ljm|Slp0`3c&nNI`%hg#4~+k4 zUf!iC<&ygfZ;|@6nEZ2}y+IHDDRz<_{orS1w&RGt&Oeg|n^-c0-@Fhh9DpeiQPskt z_1FCP{sj0Ez)aAf0Zf6Q4&7G5|27ot7CA6m=Y-QXVV6s!^{>A47q{Toync8tyz>DA zm<1Zv%0Eh(ebt<{=3g#-({BmfjV9p9)1z)-Ed^&n=S;@A_SBAy!^9! zVRuLB3}^i{M^;k0!Iqxi`RO-ULRgsgrH|2{i}Pts6ia($K1W-D<9Kao8tU-lFx7fG zrOo{JIDs(_8vk5Z)ML0V#R-fV#g51OSMNiZI8QBv#sA2yd}l-+82m$Y5k8_+km0n{ zZB|J_Oz`l;n18H`Qrxq__9$UKAoR zA9U^X(Zo7ao%==eK`(R5-Fm}joWEf%R_bBaMeDtyh@8;P>A<1w#46j`4%clS2~&(` ziOzk;upXKMkQh_QAzyH+pkhnbl}5otKQJ_Iq%(C&NO$Vo?adfly%UlF$h^-;Z|uEhIfVpdXYLC zepo*%Wq;`p7Y63aiXD_G(>t)jVp@FuO^S{54?zpI)Ue=eesMoOzX2{mQ?ruv2@cNs zz{S90GgzTMJBfpX30uDhQqBgcf9H*aXR0DL^IT9$;qqJVAae1Dirx==l+Ps zZ1n+_&Ip;pF-P&8`S!Gvw6rRug~a~0yI7O6-~~Q@UsV;j9w^8o*2CZENIl*?*WcEh zWHGaLwmn&oah}>3PaCN6z3D*VBnP!ny;#ObC!@9W^XGUgW%bLm(J`ykr)Nh*6^32) z_P8aRyMOt{zswbkV+NI_0BlmRFgm=5Ay)X*f@)$F`lFcmaN12KhT(!Al-oUel_QAg zB)6`|G9x8KRgZ_jGBOsfi0(svi_#U{DMHrJ^LZnCh;|{9UQ>$SOrhw%2gaWr9LVE4 z&fXMJY-T{*8Ii(pV0!RV`)K>@#n#r=aY~&Br_6gpLu+fTI;E~2+oOw2eZvMO^d_6S z9Iz^6J>j6nVP{e^f6yuZ=%atx@^k0H+E+UXTgcODFlSLT+$=K7xv|LeI2CJ6UUR6c&(e$+C2z9}^5 zyc&DHX3^k0^;WrM?9E*R{+;5|$h9Ze^h$BPrB>C~SN9Y*x^tRA2MdxcsOM4-4a%6v;!Ag@)_7b?UNG4i@OZblMpB;SGQ^!3bp@_@&sC0F zPd6!AFlMc7t|?D%W**|GocBJftpS9<7zd50j>p( zoOfCC<|DYSKw$t~1w3P-u|Pm+70(^?Kn(@%vuJB|k?Kt(1u$wv3qNG^*(o@m6dW_Az|Eu_pG zcJ1`>p!$+;1YwHG1CFb{_z!GCo}k&lR8At(Ig>FFq9<5y;2ex|u8^GElw`O&zOT`2j6wDKo-*dU_61{pI?<;FIh+j#z3;0cxxoWpT0 zi`(>llJ-qbF#fM0QV=$M#Qm%I3sLev_@(*Y8(%E{iv=L}fmm%m(gLSUO78Xrv*)0mYrgUeMqZ{0yrR-DQ#i$gn@4z^7s)dpH$6ya2rLWgV_r8m^;{*KZ|l zcK8FL(ZH)-(1&l!m9+?a3^M;4hXe*cAp9uY2UFs*UA!>>kfMfS+ z4|VWgy44@UD23^pp@+g@ImX`oR2=quo3st#^2J zSE}{sx9Dk?`QRpCRWw?I08ukXKmc1CZTb6RrL@;1t! ziFH?HVap#~yyqR3IBok)wgVw#oL|_MWxp{ERk7?0xOuFZDJNqNSmbmh+}FhxTLB3oaJ!GS2b>)!g?NA}g_$LYT6ca;QT1hswQG z6%Aa;O_BXS<*(5%tiJ1y$~))%*6SiC!=%<7lPW>;_xSiMZ`iZn=ghH?>-6@f#Rrr# zMcd^w^zy3GNoT00CC!Uc5f~a1{;>vPCbxwDtt^KnV zTzV7&)=HW4KcnAVg`{$qMkY#{-&8drh9Hw@VS!GGQT13mDglsXI4M38Q>y+@*1jr&#rd^?9C(t!4`O~-j8MQp z%3{T+>XudiyeKOlA}im7|Eitye&8*tQ2mw-LWMc6^_b6NO40uQLTOY8ORovE%*9x{ zWoN-hpl!yAO8nOSNTao2HuJ_qAUj)w^Dw@~OYR_|ipkXx#*338gnV=m&ch=(xy!7|J>=QF#2g?+wfWLbd-Iwk(sQ1~jrZmo; z?w}}|a6L7LWRTUdm2tA=D-^%qup*x(M9IZ`lPrYeXgvRYzcHjvdgYv)Yjf(Di(}#V zIV5p9@13D)w%kse0XLW$(^=ob^LW<9LV@49N5g!Rz?z`f=rDz*J4I(8zPM9;E8y?IoGjG=1m?>2aqzoRwh9Q z`g3}_%v6qO${36_lJ)fMb$Ui4PAUzHW8an*K* zX6Sj*{6JiMPw!AAPc)=dYW=f^d!Bbi{!?oFT3f?tI-7gO%IaB?zk=X^c8c@)Ajl;S zW$q>7c}e1ECI}vv9&<;E^MxbcaaZNtzFK3Ca*tLw2HJHqrS~(uEh1^xl_F}QW{#pj z=tFjJKMm{w!^2=QKiWR=0uJ(+K8i9aJJn}2SkLQZY zDZu$n>AbSxQE%U1!85?>^aFh^%xcgNcs;oMcNci`W!7!hQ`}` zKc@=SIYSH&rdKNUna{S@+hnzZFO8SFOpVPjh@4y?F4oMcYbKkMVGUBKOF~7;v9>#* zDFNknwuUnwoV-`&>*TFoN7XPTn5c|qp%t6?y{wT<(vi_0-kpEdST#aX{B@XsozrdP z%dqVA(A}1WXu-z{1M}}?9n>qATNXE4rJjw~jQ6xO3{zvXyxTvQha&kL5*n$K>T|jU zBIV5;4i}qV&io9~*~ZijOHe!Nabmcy6x(=DP?djB_b$cE0#<6~!}BjeVYw})nDk(% z@P)(1B%i~x!_AjO2t^DlrKwNj<}%GTKs}e-68W|>WS2W<@Jp701PSIwT^N@Si}k`p z5;=tozq;*ho-Z+r$G@7fdE4N0-s-G;?a4v;)%pF=vOhYZAW3)*PouMyfU-(g zJayJmS7XJt&w!geXQr}UzNulj(DWUgdmq&7s$cET8pKlxHN;9D%+~#W+EvssHkdw< z@gq;`UZ)`f%bDG#ACYL?LJ;5K(r{G%M03I{(l+Sm;rROElt9v21yv!s+Tz=$Pn7m#Go>6k4!F5$|PL zZ4WrImC_sMz3C2v%!RF;d$9pZk-TK<@aFDE-t1nMrU{-V_sV6<8+Rxz_>CF)wwk?j zJPjon&zjOR(MAXw_Vp8NA@{eZ%+~ls*DMY?BLr0W>GM=0JowfN4oC5cWi!K&kh=^2 z{qxj~E&r3lId|8hTX1tc1{M^i`zze30 zEe@sv=S!gbVKj!l!7=tZdO;3Zydb^`kKMp$f?o~U^2gk7-+P_D+FF`VW?NAq)O1#skvHY+2tn7cx8UN??Vx@!Gg6)p1JEBnIghsPT3PySIi#qH|pMyDPNVn z1H{*vN~OetHla73Ke$I`A`u@H?VP2uhYU}Bhi1B$bXDX9&3lKvE3z7C8**VZnBLcM z=io3NYwKy>qM#>%7tEEM+w%l>U!hqo^_h%ba?X#4?uh1;=q*&~xDT_hkK6SkT2U>S zD^)li;HWX&&GmtAIHD4>Ois&)BxsK{J52T~hoiG%2It25KV|Ep&N=di@Ko+Yvi-2F z&6M)RE^^RD7n7f5dScn9E$ z`ZsWFwHvMfoGQ+Zb@;-PKe-;1Uc8lObGvG`)zZpZR-yuOUv&gb#}_y8F43dWZ>vJ| z(oJquEF1}C1diZi+e&N>`l~tHZNE{D864eV%^iEa%rNK(!TLm#XKq_Zjs>46;v%8I z&lPBTDB9UjC;WQkItj$%gEfFM-plQ6Ek% z`NsN?`AS1kR*+nI z^_OdvwG2FX=dxhgVzJD=9@Cgvso(}f|SjlC+{WmXU5 zWg(}$qPiDD8QotxjyUdjHxlw$(`WSYDx5FuhP9=4P7N zKEIJ+owtDcIpUD)38=0#Q@19H}5bP4L|*5yU|cYE&v8Qiqc)jQB8?;50fir++Tn%1EhL@p;XP^47PW zVzV3P92Z|!O!}F}6xyJ{Di^QSKokg9k#dkZ8usOKiCx%(tBBz29CLK|;GgAsjV5hI z@4M=6y`Gv3-*%&0M(x=|+E|?wfkcovAIqPC-)8oIGk zCU%btm3M0@D!L@iKeBaGPT#HtBjPY=3c8BDbD4hHm*g%bJ%ys5)snc{M=+1P1WeWU1&67U!-zxp~9>!zqmkH_xv*o%y6=22qeBk9jF} zJFRaDq#iQ;iv`f!PEH7bG1ROQ8mcR~gC&zIXDh%EiCtGbXYON})`k6&8wpvpUfhS~ zd^@_u{8u5pTn~XJhLAII3hiU*;)-=jOLO*>E1mmTPb7PZ>Zp$+b5!*+xtDkiPQ)^q z=+Gi}X=g+n5{~Q0aL|3np|q=$>AmMBVrAwUhUo-Q# zoMm+M-ao$B-WBs-`|@C^tv;1FO)cM~CM400V=;ZFk~sl1=HwM=-;#PKE7Rn9bl5*a zpvmTBI}w<9m9CBnR!6jp#c|r*dS>P2|INH?vvQqY$7nmXCX)@o|Fz-F`R@uzZGA0U}69=P{jMGG)s)i*T zMlw;@1x~Ug=$0r)g~gutc1s1{G;>0Yp+{-L97waFRxQWwvI}Tayb=kxUHh7cs)3Rk z^L&~hp4#uqJ$c}pc4N9jEFvdA3F;z39T^!yx~Z>*sc&)>Pu687q~CDP937*T+^X+K z@3ZoG*q!9zI1KlO)NfRPw-_e+J3BkanmRu5cqMN&GV<@5pQC&&)}cG1WG}>N_Hx6F z<2ndh3^|jxC{BhzHTBy|#SCM&yP5W*FSBH}&l59RKAB;9Bp8Y1I-X=dumQH{R!U~i zvqk5{?IAumZ-TX9jaMyEW8c@-1QIoPHRD-!q!>MNhR%wm3+^;cL!rOgP<;`eoQ3$8 zu&@7sOcY{Ru1Co1f?s{58gzR01*OF$vBxQyUJJxGohQ*#aS3i)o}=eb%4AMLF&X?m z3lV8_bD1e~SsxW3J)T?Eq2FMHx~aUVA^eD^zRwXA`dV78WX|z2_bhoAq}jVjI#hbW z8u-&{(S>TUZYi)%fKzBXHq%``T~1_< zVR(Nd*NUW)Xlp4oUvS{%^1I7*J$Xm`H?GF|$kvgR;CyZ~4aKhrERL8)BMV7O8zJua zs1kxnIENH1M5AcHp6^1+%060p-8Z{bFMiF18Ui}qFI(YGn%2E7^tRL_U8>NBzQh=`VyrW-Dw$t{SMS#M zN?-%Kt9>CAf;UGTz5r`aCfo4dvz3*vn;3u~mk~QJDlRiCfU|2TmquMc0MTE3T&LV* zT_&OOqQ3eiC*UhhRh3~&^EG&k2V!a(Gt6UucEE_|BXKRVa5ZnlT4iO;Iq7acO(MV~ zCVoQ>($Z3dRf7B)BE0Z=?uT~+Q@{jHP52_!;e*kjNwvW47#T~E~xHCSEu-!=`jvSd7 zF+Os7gYIt{>Qcv$|A~Yp_05B+(x3<3p2|-ES}&VYPEsh)M2U=?Qwqmz&Gl;K(|z-- zQ~AW^mpy+v^t*3;BSDL|uHged!{I{2ywK&id$s#4H!NmJy>Pp286IeQ60fqHk=oZD zbcslyN?nV8Ru}aV5>^)d9DuZ~Ci*yNiev14$30LjT*}B--^pnPLvJg~;lc7PJYI}N z8kfySLv-qu#bd40ozvB43HDi!*B-mBZOpjM%*kU6KDhqGWvokQ}um@+abuJ%Hg z?L+%VR`(WD<>B<0V#mlZHC-8l;oJ46mTj47XqGvHx4{%^XCy+lrRMwNX$jJg$Rh)Z zSL98_40Ko4CQ_V?!mp-+>K}r_%^) zl33O1PAVxO$+ULIvSCzfMdp&qp5X7xrjZ0qxFco^HsODSv&syS#WANyG{itdgKs2M^`B0LUmQ+}M1> z44a*YwYCCWrpD$Z*V-jfvBR@8l__^4ys9U9GucU!#e(iDV5d};p@E35)TD*_>N;uc zc>)0(C1(Hgi5!=Sx$_T5F*1$j+b)1+WNfN6(mI+ZJr~8 zok$muADtfxJR1qtacHo9vY_?mQUx zLw0Jv6HMWi`GeOiilqTRZyp(-l2ZaHtrQPfJ>rN0otkSlzJpR}DYW}O?h|YNl<>q~asFQZfgdA6RH;Jw zDyobF*Xx>ZW6QpR6`l4|p>+Am3a+Xllw5_4vmHW7{+*Xkhj+pE}|+vYp7`#`jD{P)$19(^X+lnruo)qZ58$#Ih=&!?IZr9&9CeQyT=L(Q}5Gnl@la4l9>17K{Md7xlBL!NCAI8tvY9d z3`(%yG1Yy*ETdgr`&hwsIJ zstL2Mfuk0BO2hr3RI!Pm$VK?XRl^B6n&s$dlo0h8cbqOG1hT8V_U0D)Wanz{_U7V_ zWn7uJar1&Jf7W2CZ`7yj<2<)r1$PWMcn`8=b1KGtk*mp9opNE{nn$c#Lbd#UCW8?? zS;Ot>_L_=v+lQ7JAE<#Vd_)SXLT;x<5g)rktf}~w>7`naKt7M9P4?m*f&nFN3E6C& z1}BFi?}eGVd;hz$Oa$Knb&OW51nfr{q{nQQhd_n1uOp`e`IE@ienUHS4V>(^Yo$pE zYFM*r)yDLGT4x?3DjO_Rp(tY{aGcv50w4GIQ(jl0pCJ@HEdEpmEZh0}RaKQB6;TAM z#d_KNFG(Gi%}8+^arO)XoLo*4+*`zo0D@klC~`5bd_Z*Q7%BIqh~T=27oS*~G23Bh ze6|A-$LJREBNb<(MDfCNjNyibCMSkb?|1O|FAUHGoV8yH`H~w6Y2F8eI0?@>X6Yqw zW<>NOhpmaDWnb}B;?*%xXtHaMLy1l_rSHc+m()~g#WJfsN||wJalbn(VWto>fmrmp zZacaK#ESdH*P^2ahsoxqA$5rYNNf?oWeGCBJCj-h1|$2{+~OH|6Icqx)}m>fY4)Qy zc&1B6JBv~;lXBuq4b!7Bimf75ZZXTY&h)a8N*$4i`Az%S4_qUWrSOJSp}I}6yRU9i z8wWS-U;5)-OeU=#H@hC&T5!ETS(FA{|6KI;pBXwiippX;=+&KMFE(8a?TEdU%feQy z$0#?@y%!(P;5hK7*Mi;`P=tLTL|C+e>t<9-lFI66pP=nI=+>IqX*p&Q@_Ea6&&Mx+ z&zyYs4(vqSWjmxpAlReN7Dr&VP;zBsWE8ZYMAyC zXQ*bF$)txLDi1t>CHJ~Mz%nDg#!UToQ5zX=Got72y$Xo+5&L=Fvy$lf)i9$j$CdPMW)ny@%N zE?m){%*$!-TKvjj=XOIeF+Bc5O7yCQ+hxTwSNT!?&oRsr$80io7NF*BE+W5~w)9Ia zU3uL(2~?EpgC*}_#f;Zxdi2wX|8k;!=O2Nxw?LT`yNCU6YmR|x+90^-J{-ZBypPle z`}`3pafH0airT%Z^HgW9(z+e1=h`xX6#8`}mhln}*;FGV!%I?O9$#m-84b)en~Ox6 z`o-PljXs-`ytP$NWaClCO{Gw)WWPDoi418uQP^8=T^*TAOiX-Y8vsh+B9APdixmZ^ z`It;`eJx2`#Bx@zBJ@W1&l?bCKiqsq`Wh3zpO`0}eB^FJ9QAo<*y zC`FpP?JkHY`6U7)`V$RM0njjg1_9{~iGd-N8gfQJ z8l-dR?xAZK=0EtnPkg^`ty!#LO`ZFkeeb=`KG${acjZ7{>LmUAc}aR7(UI#BgBJfc z%dw^0>@&(@WND|gsX}ywPr?hDDvg4Y_?X%mtN?zn?C>&l-RHIysg)FN_6O({gL&>x;*%_a!cVBkH3NRyiEU zy4+K_mKH?Sw5A%=xqZw6s;S|li9$;j9Y|ZL%C5r$S&gcBw9@uT788@A0P9Oru=2We z{n?Krn;I6i`cQ4aQS-hm;t-9w*@Pt8VtQ@IEOW(VXaT!kwQKu8M*@S(?iTwGW z%F1b;GAHobYihjhF3WxFK;8U2U?1)&+cI8ZoIF~(6M$DO*Rj7ZRCx!}R01D61?S&W zS`5tc#;3Ey;n3YlqmyUq=_vr4^Sf38_pQQGvXm=pB_K&kXRQ407jW~jziRE87VjNrXvH%nbu)cJ)hpl|sw6JWh_oV&>)FV$18VS7E}_U27ld8C>^iG942 zn(>87%B7?I+9ZN#l+=Erdo;FWiK$!6Sn-ZaI*3T=0>N1o9rb0PoN*lxi}p=um6g>x zs8PKw9|%ZKP2VR~BLxrQYPvX=8#PalICkrT*zdPoKG)> zavh_P7FR?qry4Q7)>kHCn~0bcwx1dgE4#;AnG{s=)6r@AY`!O(+3mQp7$NOJCfjp| zY2CjrIQILKqWzibk728q2Unp>C;F#e^9km~c?8BoX=pt)y<}?*$NB^OZD-2#UJFC0 zN5a@K^lDF!#7A;#X+)kl-(k7My`t2Ku#Z)!G=7b5+VUh}v`@4#cic|;QgVUFzU$2okU)!i=? zJ)E1#Q3U{L!b+>&0%)Za4^J*t(U-rJr2Yn}U?LmcCoIr;!ws(9G9@MKZb)tyZ2t`C`N_O^fOc?9?g=Y{N$2fLhC#udO*L-5-%K?DC#{4QoPmQ@(;HeyZtEZ`e@wxf) z^nEsMptcU{FFyINx*zjGQifXE< z)ED0pdo+8=)gl#x)w{Z6S*&Dk`fg<5aIpM;#~ZLDeIpw{YZGC1C-6MzK`>{#kzATQ z338Iz9aQ+!*-1A1f!3J7>5rx#$!8sQzQt6usgq1=2T0gS8n zPO|Mm0ax4T>k-*h6H_9DcDjpE@L$aozF9k{~PKP$8CP|wm*+x zNi3uP`NoBQs(p2gdSFXX;y*WUf;_hFlRvHqg9yTak%rG+tr7m4PE~xy>bMy}z>*vW zg5i)_n$fXb4`o@ z?ES18bW~FprqRYf1ODF=)frsjGMh-`7fvzE2dTfNBz*pJ`xb;?QH&eCW#+B>{^;f# zUtw1)eAiPC!SudJ6$ysE+Mm9!o03j_GZJwy)xPaRP{Cc2XMd2??-s^h2q^qw9IU1@ zwI4@-o-~amouzknw~=WVuY^up}1C zUr@8ZR_fyj?ki;^2zL9sKW5ta1F^LKCMaNjtN;TsbJ(1z(EW>)`ZJP9{O0QZJZ^Aq zX|=SwtbKn&_%OiDe?WOgVmB}{7$FA+hWNkt4=ZDB|AiQ5WX7-rq@Az7$Jeq5t{&&IuTKSw; zIPymN7?uQNfWz$X;runIo4=_)w@0cE&;KKg^^d_UNZn{cGS=%%5&mCWx!K!G=SyVlIcl6G;vx=NXCp zqaqLf4iji|KHUHLAFLkc+Y@}T+m%PA6It{jweZEfPK(;)@*oj8#bRTKwr^`Z28%wX zQi6i0rjL$R>lw2mhJfdtqHXm3x^?Rl^W5Cr-O8I2fdQk?vmCS^s^3#>h_Fk-1`$9L zD5LmFs36w3ukOPp8R=@Z<4BD8Xu+2+4=M`_t**|GpeAO8>dS^cKw_!bFFdI)Q8KD; zm8}8?lu~PC*D1Km@&xwT@1@2~%uX zRB-RaL~insREYDQs@G$X4bj^OVFzgA#mcX~{~36uG)VMZ#tbhi>a|i3;I<7AM$~ zY4@$N3{(f_a1|^AGetgZ#83r#v+Hy8_w^l@(3NzD{dEgRVU7QX&r*>j?mSwJVGMjI z*Uidjx+67!lWm7?K@M0_-~SvOTptkd_Gz;GZLy1w=*7Iz*alsFJ@u!Xi{q^6^HAc{ zlmta-R6;_E1cm!Eckc#?Z?QR*u?-n-D7d-`3mx>*BcAqpBBmG5!SCz0Nb3V`O;q0! z+uIt3)~JIM^woVQ3qASMzFCk)&QW^eA`u=22A>Ur|7uRSphWwL_a6ewle+;+MK(5u zZFiA7Vs6JV%Y~({%a}DkyiyR=n4NaC0T(0B%!*LgZNTUY7iB~MI-SG8AA@toP%%iE z9AcKfUV(N%e7uG?!3()vCX7)q%K79ud3y`$ ztsIXH^Sby54D>x=H*S1PiOyFDB{auhjXlc+_3KeXFcw-TU!eT)Flgsrx$6O{Pk+N# zyVAuu$EsH;cJ+PujT`;#3Qt*&vV7TipQJo}fD;>jhLCZZsJiMF#xnRe=BTFP_s=PL%_`c#`d&$&ugJJ&ORo*J)x z4nE-}$EPG#%-eCU?T1WYFowtEo^c>IKQdU=l3}ylt!&fYx{2{zIiEAI$JyBI z%;=Kg5dWBQDSxPOO^$|-(^S}htnsgqHunZQ7_xwwW_%}`{r_wZ=z>0N9kkE$4P@;X z#2{p|agmNC@?F)ON;kod@h*-$48(f(E9ZasJYDHO^SJRt2q~KOCxDvc?&Lf>gP`&< zE<{JsU&%q2a?UTi=@-ejtc)pY@uac-jmC#^uXcypDdDs}#DCWUtbkKB8judw#+og3 z!Thi!3FT^)U9_cKAz#@%rB)}R@uV@?U%;eJr6NhIXT|#SpK)OYG~p(ER7yV^#h@qzS1YaK#VQYgL`Bj7RD zy0x40x>_qSP~ndX2l@_M0^Uv!%!-lgr~NOvE49+Ic9ANE-_J}--A3$pGJ)*$T+bT3 z_GLuKJ;}K2Ps=sb)PtE1&+Zu4I?>c$TCZ%}0SKA>V9<7R=-w@>%eGT_V?4IoTr~|L ztv}u|BimRijx|C}TuC}o8X9cDtHy#PAzEMD>aw3`IbIFv!n7D1HCPc{x~40f=n7F( zQ6UM0vY8F81;O_9@xE|ebB#|I5#(OYbKEV=3QOcCc0xfT&TMBay9zba_o| zxC=#m$+ySK8dS@~A?jXwS2q2vsK%KMNM7s4K|AqbQaFAewAl&fpZ0L9HB3^fN_{_H z3e|{qak)s!Y+|;UJq3U+k%r`ec`=`3(_GX&V#_ikE_d7X2>Iajfdp_#av#}jpWtrC zHzs1fotVn)1^8KDrKcx5()QFT)<*G!mYH5H^M!|uA>=G)h?QjyZPpt!1#^ii^xhw+ z-!7guv>G7Wp6C<28cgCOuI<7b$@S*WZn<5kOv+hzOQ_binkem$X^w2WAsc-<05RQmd#3_X_rS*odkdD^u?2c(zRfs0jd3MJpm^;R(TvQnNN%f=#cKd!ELR} zy^UPIrrS-!;M&io@*#em(bshrp)vO^PRjEde3vNka*N}vspOCH&BU^Ep0g`7K~d}a z@~(JW9fP|0TNvG4*Im?VCGM>EMYKL&V~xV-l%cPq9LX649t-k12v?M1x^{=(a`2vo znR51*d^VL`cCDRoR(zm>i#uODeP;^urd)0sQ{NsX>cs5{>%zfiw#p2@j;zO1AGfpP zDB9#C!^T?Q?cEUfZ9!(9=Bz{f+n79nToyy(A(+|J{Y%OHC;2-p1y*eA2yCRL2-KfO zTCdr}P)072X?Nan>sM}hXgA3v7ac0zm$`SsgJoc;HP5AkuXn;xx09M_2d`Ua3`Lxd z@(r!Fohox)4^KyH6sqlLZuRv*dF>?z4%ch@<~((t`k78OC?q0dD8~Dw%M}}4O*eyL zhie)|F~?M@;L#_}T2iyn%miQW#ldGQWfm1iCG2$c?d|l%T~^dpjx&vU@XR*&fC$vj zbb@o-`UAYD=U4u_ry8^MPs%I(kre$-dQ;j?nvhZ+{;}nKA?M<-wl={dg*vEYPfYw}N%W78sLd^8G%Q%qCyA5x+kZ8s}Odilt??Y6cmLfk&6 zs%FxIO_kBU8$?wl%k~|8yM`2#?UJEhgNel#B0udsWVCkZj2q#j0H+sK9f1t54Y}-U z=%aR2<+}6o`kH)CLduF6GDY1?(cj>;1nFb$99G433_SNbhP$jz^YwFv>rX~2+~zD< zcZ?_ad=xquGa6Bz+=JF)gj1u2{=m@F`cm+lL^6Rvu)GYL(pVa}UN+p(? zT{g^44#t#NWVeWkeYO0y{RLBT{7J5av7)Fsl}F_g(L) zI9~lg+8bPiux?v|c^oH%6ZzN@OPQLykg@h*`1nyK7A1AMx|7p`2~bw!Zc#jHXCyKJf??EVm%FF$BkMUCuqlzgG1j zpcHEQ7FB7V*`jfe*Z+7s2;9h~o}uy7RYcwp`c`JQrjZOSF9YdW+d{_lZ}Sx)Yw5Lq z(8;CCwrB+pw}Pb#A(NEke8#ni!S4R?&&Ifl&VT~5)t;WZNPZp|`q%oY?4o)v^viHZ zSwqd1+5=a&5$_WHGjL7OOXKNl_%c1zFa6CHlbse3*uo6oZo;x`HuoVroJ8X+&yvkT zZlpMS@avaEXEzrnJMC*!06sL0qXAq~ZT_cN^b@l)cftFg?E6ikE)K<=gpi4LDR?>7 zBHq9X8c)$4jPF}U{o5c{8mFis)Vwz{J(CYFu+ej%qnH?vA?FjBa!UX-jd?_NGHzKTG9H*{D2TmErxM7EVXmV9+ z?%VBW(QCr_eWNzaiOvN{fpF~y@M_bkIqpK`7l7L13FH|3furR>idUvG#k}RZrOLVO z=5Jycx|aR@wpw{n!NrDE&oqS}+4P2fN`x_fnI?0urgw>*q@CrFcIaK&xc**_#E7Np zodZP4_|};x;kJZ_M>)n28yv6n<=G z31XbM_MqM9-NY9q752W48#6)ACPl5Y8&a(DN4`)eJHH@-y?l_cJDPJNs&Inxoz9?J zXEUHO>w=LKMfp!Rn6Xb$cD7fX&T}ms9mHGt`K=*b&0{q%(c0e(Kr)4?g6Nb^@wgqE z7jKGnkf5|$W)&e)NBJMYtHzYRlT1hKMr!h%oqk#N&jw% zDV`H{|7%ftvu&};?XgWieM@$O#>+u>i#BM94uQ>L%KE2Ki>)0f8-J}L%H?#_!E^gk zIb|^J-77QsLPrf5kMHN6CmD43Kxn?bp!rmg<*J2NPYUzF-kuhIN8c3DuQ@W2v2_PL z>|{T?{r&Mo#FZejcd8BKh?dd&;mB)OurY%eSnLRy4z-Q)QJ!E*om3|nM!RIjR#rMYT1KLOf zB`w`9ta}v&voADw(heaXEjUfEt<$DbFan!;g<|OG4)b*`zpL4=MSvF-+%2Pr7+s2$ zrW(&93u7e~opH-?onGSjxbCcd+8_3MEQfM7Yb%^^k3Bk8d5=Q8Xw1HC@4oI>iO>3K z$wYj^>Bo|nHQ&rlOrYM~_RPnda{@FpX46d;V&|fi3ju9Fb#i&k2K`!6CSF6mTg*Y7 z2nR}uvB7o!W@ZtZz}Np)J*4D+P9Bsk;*Z~@m~~Gp+=W|t`ZSh8h-bM~kOJbAXbm*fEp3*=djftyeH#y!-ZAH150RI0cm2dPG(3I(6d2kjQPL#J{G$SJR1m3>eAN zlXM%d?JHIjC9MT`DtMsk+-pOV5&g7_~NNv1=BYbX>wlns`e2 zW$0M2($*SZ>3wR&XsrqVE*Au`rZrRKN0c=6HdOnI4P!-nQ+H4ej|0EU=A_FM^aNku zl5kFtPruHoxAOO?g)N5DTPHkp_2M=r~iuP{g zGit~$S>0DL9&1WB$!2yqQo48(FxJ@K2+Uj~N+T;8+w3W%_dOV{NitHB-B!PiO8EM9 zvh>ILCJbF5@D*jhU%#bgU`=&^o8}}+kgxSZ_=mYXPrVP)XrWMK{p z9tQ|LK6~BQ&#e6+Vf|h4a2a6Lj^D8-J-i!i(YMNeWgbWmd+AYyaeN||F)5->n>Quk zZH(=?VWex${M+P2_#9T=c6>)W@)zmHBoPrWq=J@?0RszJ-B53DzsMep zWcDACtxY>;Q0WoE>;ca*i3`!72%1i1|CxfaM2pm*Ae`y^cWTCXuPM(_1GFL{pZ=}| zEJ9J%#Q%8Dzbol;kFe>aM2k1#di{!>n z4|1O~^_#b+5g_>dts>FGPR|rwoy)}ypZBs7w@V{-cw;A7qQ{Y789nc)7W?n4jVWs|9-3WUwT`D4$C1u9}-Utd5l)V2auj~CPb%Sjk$$Z>Zx{NhzcNK^9Y07EMDfz6VJR*5FGc^`rM!t0NB#?_ z<~s-C+9b4w9Da^qFXXAgxv4qMt}c10H&VvF4{L@sNhpNTA5JpBAs z)zxpVC-e-pjP9H@@RpUm#zb|uvpp0;xEvMQC?_@kmk8PML;=f$=tr1Wbo5R7p$^uE z9QT;0$SHC1a#AhdL-02Gu&0^AG%;jnNZvxWe@Yq-08vyLy5Ruz;1w3>BN4@<)#M~T zzo&wf(z(0%=2>Nt>g;=_hi za9#KKCdlq)Rnfk9TViF-*7W^2-7A4Yj5>Yl$nj-uH+^zP~aW&~D<4 z(N3w@)K<#El`_>~&7wqAYg=$`M`+fz3amRXWuD{?q)lYnL zK?(Ab45Yu?1AiVD zN?7{igAA1zUyw&)y3OgDF^}9q~ z5uwh>Wol7w!f)2}E_bEwNr*jSti|Er{QCeiU`ZKs{#u8i>LbK4Vz^aOe6pqetHOq) zg-y2E&-*M_z&HwZSTZ$F@x~`+o*d0+4$o&_j~)X}HMVJF834p+dZ~3T{LTjQg7%G{ zZNp&zaw3NLh#dbH4IUi^FfFUR)m`coL4(iYFLB=guOnW-gyfC--G|O1Omouv`LhD& zv-^&_w%X--wTD7`WtRlmjYtV$C63+J84n8<;Q6kUq5bJ%?c4s|qzb)SUzGAK{`!Yz zgx3#KuANIPS6N^qMes={w72+de!>S6A&3r}ah1zaR`%~%c7X)j!>(NPG>^^u0qK)% zS9C-A$K?w9OunWQp_AT;{XHHx=l4OD^x(&xuoLn*uvS%%@9+L5ZE*~Qd z(7V}hZhwxlK|xZ}zi@pYaf-Nf^qzm%-;-RSS2ecq13qvd6@NQxc<+je8*E&q1+&*W z;P>pOm}|HY!uh5K2`87x+F!fl1Cj~dncLU5KT*DIsrYhhWRw#n$ILWX`LcQ4k9QHM zz;AK70yZ>M>>VZLF*}T_pdX;no$u)Ax8h=FzuMWY#3LJMl0I9+hb|@28T$$R zYD!~FB4zdYA1%)nJR_h}FNO)>mxkTwK|=BdLGr3m z7V?l&@T&nwtK%%D4MwT8=T9^MF91n;H)pceBrjgRimdRr`2NYg&cp-j6$i->d5eX_Zk%AZG=N`Ywh zV*m#3MgNGh!TuoNeqnj~nbUlw?^;v$@?B^zBCFr5`$i!)MbvBfxI5eZ=({3;(D(Ni zMF&3I9#>7aV~1KowaWHA5)-AuEH*l3kgWK%{xlxH@hgPqozg9JdTQEz(>bw+rKG>> zY!S{Y8G_N<3-&Ki@SZzBkeBk|JjA3MJ=I8DSJZ<7F2uAx2;|tQykE(<5b`-cEIch@ zDY06$(OT!&GR`PD-CD=KMZWY`y7k0rg-zNd`>Ii*I;S&%#2v0Xl2YP&IC|z*pY+7h z1F75?wY#v_RleStq`$p>SNUe2eT!uuNHv+r`i^$U&IKYjPOI!4<@7(uu;%lM;ms0z zxFDa5MC5bxr-+S6S+k)sz9CigP7h>^9j8uUft1lB)TsIM9U(zG@4C*3fE6ROWWyv& zlh4Zb{tA@)6#e{qmj9dBRUN`_qK8|E(2$+Mtp^VLy^HP`PZ=@k19x#F=NCp)jjZD} z*DSRT?MsDNViL)lDqjgy)XsmuMN`J>ide0L8GaQi``TDjqkJT5&B@J!_cG%mLuu18C#JsOM7Ik zCw|Vsc|qlT9vKsA)B7|_1Mm?ES;4zb2-bMvrO0Z8KBx+H#vh5tOHKbIH3hRbT-Y?} zohcHw=pIPS&&|yMk6p`19gZbPh$LT(gnoD0sPT92sDmz5i@8jV>0U%1@6NucW*!-) zBoajqbLEr{qs)*lrZ4+t0 zx1#+HC!qGeO!J~8YbFLLi!U~YcZVpqd)R2Lz@)i<~bPpGtS~yr%6x zwtG3>Tg>~?-eK736Q@^7TERKmdpM{T6f!#2%#lmPTU6pBzaCbt9nPlLDB0i5@!cM|8H;GPjO!rI%E^uz7?0c^Db9D zZN%ne)vkFTM+%dIxTup-`GoGir)ea$s|c6Mjc|F)1iM_-M^Bzv0ka1w+mx^CPEbGk zD0Tf?9y9k+>U@m|sv*uu^_(1@ne=k_Wky|Glyi$8A#bb_sVq+WEcTSJf87Qnvfu4J zvNZDY-7pM5TinH3@yaF?wY!niw!a!caZ>Y|+G~tKfvM1w2 z(JdtizenfZVxonpGIHAbPzMb z`89?v-@cA`;Iaq?f2zE1oeD^^jctV!Zd{t{bB??#7rkv>Y%PV7u3FUP} zBbpa4pMsN#hr^C4YgnvQT#izB{3A4sLG6(ubv$ZxfWTxF%r7dFl2EA0qiKp8HRxLo z-MJG2Is!Y5t&}8X;VJ=?3V|QbKc>tK8uvpcmQ&L<;v)`|k%7`Lps7qUUy)(u<9wuN z7MM=q-GmV=lv#whm((09$;i)#$3k~_+2J-M5S`tp059RyZ19!+cVmE&To#e5hMB53 z7WN}+*r)o`gZM%fXJQv*`?N8!fCI8jl^C0u@#nUX|7popYqpsFL3{9MYv+{Cz>E4c z_>!>A-4c~|!7-`shP9u;+vkhkOFM2$`^D)pZR6(wF3)Pva@N8)8Twfs^a%QIWtL2_9%Dre2L&%ucCp-MWQ$1KG9Vq#uujTaqhs1A0PH21J3EvyA z7*S&OM{Sh}u%u{^L#JJ9Zlk#l?2UbT5l>B4_>C*{(ES0Ls3BsCs5kjR7szTVbiKO4 z#X_>uTVosQ-(v_c;x>tu*JFPrmHiBsss-i{Sze6k z^cQehvX|EGg+*=cn~%ISUw`^NyHWb(su<|DdmYP|9pjS-ucn7h1rjH;Mjq1Egty#@ z2iI)I?hBzIU$;8WcYI?Wb`#mDMD_P)t@`nx^jWCiQfs z%l*(@(Y9VQ81B`F)nu89cq(pR5eh)#6r`KO<=!P*@58-m4nxG{z~cPi^;u^9N16iF zJ>SU2Os?vabmJcfKv>LgmYs#Epl!mbJGKgluiw#r@3`k8`@nuy<&m#DmB{8{B9Wa+ zt*cYsO*Pk5CvHma3JX^g1;AdJ%QKrP7=N!YH!!;v8h)CS`ZmBR%Kkje!Xcf1g3I07 z)dRV}uAQ{!pIwn@Qo(B1_9N@6g+T#yJd!}M9LbC~IyPn)rIO21<7AXwM72moD<)oE8uyfYPLCCdvU)wUlOecXDU8}Q<6DBSbAr507sIQshQ z2=nNwILD(6s#`|JojNnZM()m|KE4MYY@EAxJ+wA}HnHmh+M`0?o9;NZDxJ09mlt&0 z>;)@x?Peu2$2Q-E6%bJ-a@9doj&xFc-ksq#a$$2H<|}^B$}@diO@%QS-bb4(H!UjO zo(8p-UFh1=Wo@31-D6)HQr<`+C3pQ$7Ftb=(t*kMG`jaCgXV`LP=3*~3gPpN1mK!) zUbp82oJ&?9F_SODpuL48>W9j&O~tBHQ@s5>S?DZcJW=WHt4jk4-B+x>$?Qi=ihb{! zZfR)mMsz1AM@hRQmcXo{mC7k2AKfCvrG|9olIJ6fO#LM#gq~=Hur>&@SC@X4B@#tC z^zAg_o&bwv-S{2mg6xocWkd{;)t2jGx~QG_F-Sc z*!-XD*4L(s4XaB^w%PTRq@|JBe^SY=G;X}A*Qqcv6uo;F6E|NCs@c7xNkIReVxetwJm{9z;cqyzn8tLbKx*t4wr`CN2XN7r$erKeMi+b-;L zDB-5F){4-J2k$FIoYgMM`vp7;x*g-EWAHuwGRPDjkoXJwb{5uZ9Lv|THj^gNQURtV z6=l`rqujz8?k(aH3lk5>BC<)ev@M?4Oiwx2Sj#+JQh@JecJIc*-X&xmaJ;^9Q*%z$ zGtPs3j9&i0)7i8%+IZFrO5+B34~Ey&4?TvL2IAf10Izb+v6+dfTmXsn2`Tq+1etTB z-fjMnISux!V&_uoT}4pIpdrppZoJib6t&~ZA2GdC-cM1knOsXNw_PX1lxtUy%TD$B zoOn<1wll%Bo{BKX zD4DpJs>SAnmF(J6qaYeFLf%2v=yk%l24v%ze@EK}3s9D}#_D(HGhsGNE$8s$pt1@K zbNFTw!VXy$acJ`Ni(rAFU7B-wF~Q&_V?4T(k7o1qha8HSQer<+HNVw7gxD2yUo@4s zl$V<;%f~nQhHtoqfbH&l_qx3n8q|$)&j>-4^@jZLeC>G}hBufU5`x{_$E?Xg0eds! z@2B&6aUQSP^B|RXI5+4XrJsR$z4@esm7YZJgSLqSJ+uCpW{B9^U$h{_$5gq+`LsW} zt*ct1=6$Arb061}7BERQvu4)FIeM`vX;UV5issg{$c2}czH(0_EM`7-d##kRYAnH% zNg~+99k9!ha}sZZ(nfPbT`CTrv#kO!c&J2& zkp1iFR(sIfK(+e`$qyyk%p=TAlKCjkz5FX#6#RmGCgJSD>oz2B|lUtPpa*V z2=IUv?p_u+uO>d~f9xOaPv34gkK|r@iwcz(8t>~Mz=xEizuc*b$}O?#}me(Q>Aul9sA~nQl3}fZVwDqa69yId4h( zi6%XgmuW*Mp0BLdSB$S&zbyvlSW5^w9O`mwn9)BJ{@)eYz8=(%T8{=xiYwu8DBWkw z{FIbbfXmdt;?r4LRK&IUc&N(W1z46;FqK9pC}-jYS#i7?tKce9GB|qo4hiza#Plw=aK0ZbqR?JhfpP_b^uV9ODl0T$vu-$GFEM>@e}SIMtUQ z`v$>Rt8;7ntwBLo`-6SDt>{RZDs%NVmyS=tznkSo4Ad0{x`3fa61~HN6)#sS6)I2S zhsjK9mXwVA+*;HUIddOy;1R4t%}~>Z)ru9q)01fyuTy&#mjVg$e=TLIFhC%;9F`S<~I^vHNLs-DQvt(i>MA zh23RC&ieh{|NJUX0E0?C0!^2X$rQ4PXUod^zYAcf&=pLuK;~DL%q_9#evh&&8U3&&XRsmL;bX~r2>7j zdtzE!na{{{xS^Bn06S|9N6iK2{5?v=q-G~=^CtIEeg7@o$F!*9k<^_K{;&8f%)vFmOvxHOlk#z`E4@rwyonO@-H8cw6ha=L zU;cAqI!;%eb{%KRK=M?%cyl=mHOugp40lSz4B2^$FiG6`2xL9Qr8abJpp`2e)XhS? zL)SeqGD)i*2iyigr#95Ih1Cr;6snb8e6e*^H{bMhw^0rU)n~@qOIJg-W>$E@6GQRi z+lJe;`IQVqNfip{w@C;m9BKe?hL5!)YYsEjrzlcwy5wjIrG&=p`rTR#-1NMnS@%b-raN#aCun8!6Mt3)ap!T4c3#6SCW(Swy$lWbs`a>F%+q4iKmB;&#C;jh%=P1 z)>I@BHX~2w2Te`zt&~&`fYRSlCs=Qh5xiLaJ#fJrtH)gayWu6nkIWTQ(|jdcW;?of z6XWeoYyRH1MqC}F9Akftjw?3)NKPB(!kvEy%|DnqI%9TK3Gx3Cr&nKqKapK=wbE!z ziJLwD`BA?pD6sPZ-^54~b~Jz2Mf1z=Wl3)cG1C+*?o<#)^i~3s@chZx39voJQFGpA z%>B9gGi$#O^Pe_QJs2a+t$pKRd_Vou9s6)a785IN{S22yc$qQUZg;&z40)}XB(5$Q zFMg_-J|JAxqMb3UXj9&$nKZiAY1~tt#)o>UVe`2+0hh%#EHx6zlC}vHCX#1%xn|@9 zI+QjWm3;?D&?a8o2|n{bmq>c%U(F8AiDR;w?iM+=-|457N-bb5jI7~p1+T_pr`Jca=XE%Q^NA!pg`$snSiax5tq%<9ab%1OY+ zOCIq@13M)={TZC<5l9*zC{pZ#Xh#wYJCj~jW8dcr)e6ccfZJs9yJ>2CSoQTS&QS)a z>Uf;luAJnCq_5-$_h~qIbzD^OR|1U7ABjMLtCnwhHO?+#8Y+?D&Z%R^4B+(%JOA3~ zavoYx(syS*vGC>JB!flhu!7$RK#R9#b}I98-+|CPo1I0t9$f3J`QtVBh>1n)h5a0Y& zVr)}&N<#H~MY3+go972_Y9tzz6}CSphF$;x*~G)u`&IS7cdWh*xkjaf=tDV5nxg2U ze2CJ9ZI3p>yaQzjs5X;MAeP4y*&GOVJ2gQ& z-0l#;ABXdqdGqm6!oEyg$q|PoAt7e}F>+_?okhXw5=bti=+%k5i{x)6CTRLOvdx1w zuB=nrFhRess(LVyp2Pifsf>!E!!fz2aqYKE5Ht}v*^<-{bpLQ^i8~^@znX5feKi-< z!dLBBNmKqPVXPYEsua)H_twzD%d7s~X{@l~t(S&OgOPAvAPU4{wx>Ifsewjc6zQ|b zDXHOdQgRO$6LPy|fk5;}HO(>85g3>DEismFL|i@X>ZpJ#v|G7@2WF0!PnhOBet2B% z)e&gWhi4XJTtTsDIwuqVP*a}sQnsWhqjfDa8#sRmxI_i z(G{$^WjhY(EKLB(DnDK{G~c_fC~mk=aCEbusT`vmxs22)MOvP<>}1GP<2KUGD-q09 zE;}h`1BseWASJl=RDPgTv9kH^6c1x^g5C05eSx#mwoAyfL`wf>>e@zc@ttOsz3dhv zI;Gm(vS)uAh3TEok$H&m?RkIb0#5qjJ+HQ5>FrHg(3{2Cvh9gf2<}5;4W~|MCM1uI z{y)aPIv}d=i5E~&Ktu#YNs&?-DQN`h1_5aS=@M8vRXPQvV`)T6x)-E7md>TSn}ywd z7ySCG_s4tx!QOk%nLFpqoQcoOZD_Tv$Ul0;h-)Q3p_rP-+|@;$b1QV&8yWSWMZoSH z?zyhWR^cd0H*6xauVjuc-={Y<^|oT1jf*p$*8;j{83XwqKNE8AQ#tN=*19_O5%QogVc zK$Lh}%mPq&Mw~9t`KfcTA}UtzoicUjKzDE6w}vKJhC`IpMX zncL^D9u;o<`&T7n1}L=aT`Y_E`14BjPgTV8{SzGl@EWK3R{?2A127Ytl<8d z)aa-_;N)NBDc@V-DXiNV&6vjfD@$VV%9Og9qim>9DyS|-TRk}`L4A`KA99l z2bN~aXo%D@z)C4Bc%)lTBsKoSGDOu&&@Hdi0yGSu*?%rvTge3&4Mc4Fn%)U+hjBR1 zOXAy|xRAALmP;-ICgK4Qnbh+}!R^ZR9o}Q6S+fe^y)24}ij~FyCwL_06YM- zuXU~GgP-G}_U3oJ@hJITgVwyXM62qrzHFotnA0DRkj|wVNQMuKI=LS%Z!}+&ZRDZ+ zb_`|LkANN8-QE3FShLLQ1S-5YgClI0_*lq$Yc!v@@LQbzIau&+jm{+AE+?@dfurlj z;>ENW_whz%122fDkh(EDYtGrdEg>9&$j3dsWn~7}V(xPfk?rQTK@OntZ=tL%K*^Us zP}{tqH9fxR{jTBMcmCYzNdru*mHR`PUjX12W|1BoCRW$n2unzbrjLZ=4EM&;Ed#x7 zyVWzJ!$ND{=~91GbL|Gm4A@5bcpyKN2sLe-r_J>1bdy zad=9-$0?oeJdp{)iT63grvd1Ms&p*UN%^5U`jrfYX-t%t2^`c_nRD$?cXsx4Jon=D zVB)UH3cpu60B(qExl%gHDiYvX-S!LY%x~-wjjE)3tK)_`ob17;XO%?8Ceqg>XvRAq zF%WpS))>h(Im(UlNxNz-CUo}TM-HvouByrO1Xj~rRP`)?a`1^2^s*hOvRs#arEXVw zH+XC>*X#%OtnJ1AQvJa9ks_+Tj;CKQRPd=Q@1fh90|ZP_uP;;hHI!pCA?)(_;WW-Y zGmF#B;ap;Haj7;~=q&-(4vvT94{CW=_L9U_#AB=F&qPuYr=zKG?_9{Em}ED*q>;dL_i!h|SJ%sbRDT7EWt&cQTc zl@jG$Cj|evwfdEKkwn-?I-bD6ss%o93v%A5?GbTjc!INHyT77Zm}HCXmUMhw$W~*? zNx@8RHC_x06zTxd!6FCm4#`h@ghrca$rKhw*KjUni{mEc9CY%)^yf1Y$ZGgOmQ7Ow zw~z!HMjwsai}zylewYhQ9TD|?|C$c-fP;q{XH8Y~bE;$RcJvz03D7?}5dt5|Go~n{Uvs);n-NU5dgb}s>??PZIR}u|^f|ou!cc+VV?IN$XQpdO=tj;Fs0b@&RFu%CZu#HCqSj0o@E-bAnr*f^NYkp2Ktz1HJwD?@EL{ zpd6)zGD>2k-4E`iv;HQ7%glU|yJ!7~^sK{BSl@_ROjb6e%A?-9&PjLIqo=OHorBkU zVu--DH@>~Fu`IkO1>Ogiryg0_>IYv+Od)zpUzuFIgW$LYQ*3T*xG93Ih8tlk6E1Ep z3-$#``A4uhx3BH{ad`wVHwVlWJV= zgo&dgE|qT)^YrxO6O#2fjn29HPXCn1n3R3V#oi6o;*0sm##|PB^$Z@|NiV5v*al%0CdG?aF8iul*?XLPwyJ>YDuPN|2E*F zr>UV^=hs+j^pi5V<1fXBxe0&zT!&w%FkCY(d|t3XUYL*YCw-W~4?=e1)faxOiJhBo zvy77~`$!Dd{EX2S_741Cu9iQuu)6on!nL=5+i)qACx^cN*L zs(KoAhsTG#xdq)7dKJXT#YOG(^r#96TzAKPPLfs|j|Q4>^#xrIvvMS)a5hetPzwFX z=~7-Cp&UD&(E0uHn(|WrH^P>x(gu1pzpj*B!?Iqim>BAKbbloYuk=5*zC}W!L!Mf0 zNZErv<`Jhq(?(~K{p5q2n7#gpq>F742oRIbaOk9yfA)dzu*MS+IZmi=H5SU|pHn?FtXSOW* zBhVKSJ}~a5_XCsw9L5S8PE``(*D*v^x+dh?b3^Oe+|zhvYDY&dev-aqPeJNatmi<)o^-pKZq^V)5?M+?f2+2LuEt&)!C|jP<8M{YZ&HZO$H5B_Ai?+! z!(TNevUvag$;M%!oK*i#XtTe~q?SCjX-}e%ECXfS_fgKLsp|8a$5cdq#;+?Mj^;*R#UgFFn`LmA;KJnJC$BOnC7b0kq|3CwLaV9d;ObjV)y3Dd z+=*8xiE=G``s<_)=!?jaTrokdM-9t*?P4^&BIOG4F24&1sm;L^pZ$&7t)Q?_(3>~5 zl7Z#rr8f*Qe^g7{_ko$YuZ%*-?KrSYL)#M7(YG80eI<)iR)5v33!^~hNALt7KEUCa z0;#caYpu4YWOC9Cinr?A_q^U1C?mSm8|UPuy-j~>_bD_k2y$JW=UE=`{QPOTYx>dH zWQ{Xl1kaXcHU}}BEC6UgCz-^xEW7e=3TsX>o0L4LtV@vR$?;?e&f4WQU?I51?Q&PJ zmPWQ`rD`z>3X~)1Udf?xHIrCVI7l9hj0@OP5`{k95!E)gJg|6Ms$HrI-BnE7|CybA zhq)tX6+?@zlADH_;jp=+GhaFa{ABX|nJWm98%_MYAC(~HefKa6{`+JiFnaBQWUJ{0 z9>pYBL)#uDQ0M_XA^TM8!L7pbd&%GOU6{_Fvu1Jl43=CRdy};>E(1Rpvy=3SL3_={eaV1|^w`WwzFpCZh zF;#ipZ?t`%QwogiPo;)`qna=vo8-yZxa|vx9~oc zY{^E2!Wk)gUedXzNC&MEAaIq{faENXRctj1M?qvYcI!=GpNmXl*dy202^HFi$L!20 zSe!}fQfPg={>kq>^l5Uqv+Nb?ykd~VXD_NN*$IOUN;gO)LpYU*wz zDuqnI?Ai3M$-uoU>mqsY{0Je`87#ISrzZ(SUaje8is!jjuW)IlE@X1t+1T%e5O!}o zJHk6Z+?w^K<6&vw9w{jJIk(?dd3{uioex-QFfVLv4yu;tr!}d;yu5we>yc&5j90`^ z7nNZSR&jmpMyHyRNOZtMOnL1(<~~Jp>+5QxSz*kGeYK93L)Ou+U$$bC`j0hk1jZ8PQXjd!{R=k75L)XWw0ovoOWOv)doay!T7 z4vZ|w_04&bwY!}6Ca#`Uo-u8NK@ufy<+`~;u^mk1ljqH{#Nqcntfyu)n5C2zr~+8B zEgr)4bshV~(#^dy{q-j-N1gedH$Rbzc^c{BKF9TW`enaB!nOA#-BTfPxpRDzzqg~K zrAtaIzj*0bb2$F9N6v*p9Hy8%9SLS-ORmCM^43vYW>-G*w_2D%&MhNHa zjG+#b<#o-uRER?ZN~p*0!H9r8E@b$7P-fq2s9u7nb8WFTx6N32-mS}r7iDs|B+IQ; zYp*iT;cl0quZ9e<4}3%hus(de$-w*gXkj0#mup6N8Mg+ZrX7}>yjS}YUQ#AOC{REM zfcyKP@xTfaXQE}Ufs5O#esy92B}s}j>iVMB;8wEY086%WfpKd|ReeS6!7$-+i9DA6 zYgMR=;Ml<(VQnGu6}~U(dSwz^UTico7wgf+2T|vbOTYFmY!H%VSq}tOkxJ2gURQxBKt9+rbNgp@NRGQgnyKK7Clb(@cMet0M?114{k$~I25ga`gmq|m} z@22W21z6XDhR_JiYo#KB*w*-Tx3d{b0MA}AuZ-MG!NEL-42YnjVd%2@;NQrbh~I5O zmRvO|ZMi!bKVJ-b6dv+AEKk<+MQYA{S0CcEPZn~leyQQsBrqhdP&*;3VYtC<*DNCB zKzTFOv54dD;z>@iwP7%q+ zkic{^CWA34G=E+L4a0)vgZbQ9S9C5OCDFTk zKWSWS3lqJ0KENNk6rp(rrLhv?IpCxU(IR@~Q?-fd`2jFS<=0PUV-)B&)+TTk{`l#W zEemKGm6aATU9TUA^*y+|Q|C`DG{N|F1*8c{eXZ;tN{nUfubgF-m z0NhlojkW|_?7RJKnETf6|GM-n4I3l=YvR3UxoXikVdj5xSJzYkqX7u^JlV)$hLaVs z{f91^=x@|;Z!8w_$1aoO&&mUCHtD_kauJ@ja#nIyK430BH4zO-Qc__0&kt}wn>dg7 zzW%uj^cIcRT5_Z|8yEAMPyfvDhkx7vWtHf@!`;t(o&fNNe{&X{3)qSIIm8sh>Kf?1 zr2okV23ntF^=uY;x?6w=l!^xQ&;8e+N*DlZt#z_88^=7ni&nc-4-bBKC!Nt+kF=X# zkG=WAhZo2^{j+!!1WK*RW8T`6tXR)oql&}tIbG?{>O-wBQ>iNqk%TphpZHJVl@_Zma)o&&3mE z_BtQ3lK``}e*4NRR7w$YdR0Z5IlZvG_@yD>8udr30bf-ZB)90Oscn`kg*= zVL_djjol z>%pfcwKT`oAJ(uvhvE3{!wXpW(w(OSYK$hEzXa!>{^x$|rt@*3O5?okOyh?9C=NGgP_o1ZS# zUb?4@t2aj)Lk>9C{w)lEguPQhBiJu|!kcl0J(rQL5%s`;-o)=RM@1xLH6KTKD zPx_VC`As%+gDHtP@_!;OEhdgfU*x+*MY38dIE+kdRc{qOHWpgeWO+;M(APY55w zkH`460(B?VA9_FZKeW_TAU(=;LDZ|Gf(LSOj_rdtkw?+nnLpn?QlWO+vtRx~NhX&-ra3N$J%pPIXPzTd9=X*Sf@!z9o7{#%Ug`fI%90)VLYTw2uLJ2hj+ z=&ZOxF|hmDb7k*9JGhv7jA?rP#%Ab~>7zm%LPyrW8M2{-YnIKIDR*J*UirMGSB4=Z-PTbuN z^K(FIPJ5SdJCs4fn~*(MjqSNFpxEoH(X_4) zA|*9+yZ#{}$ZoVL59~@Y>y@{Gl3H$<>$N^s(gC!6u)FocrvMDl5koOmC}w0Vh_*to zdI-(zN!Au!P%2=26g`|zRKT66<_9h9_Az?G9Req_()yq+P14-wzMVyAlHhBNKJ`c` zGkFY0VwvS{EZ`e#tJ^8MQsff_Fq0>GqV(9A?aS7HIfsJ1QR!BTH+o2GaCQ^ z@kJY-@cNb?LNH4f3OF22@gUf!9{t|?Z)?e6YqD9&*t>p(`ziC@@tXBSGxrl%?0b2clyegODo)%r0!oMa7D6#^Y!P* zO6$jG`-T|JGn8u)Y^6_Tnz@m~6NkjxOw5Z%XTk#Kl5Gx2YFWs`ox}_8r&jzEoleJ3 z_Gm4g-nKptHX~4OTiWgrpTraIedD_L8`n|@+j~&_f?4-jHZ?$rE5`S&o(CDl|3noctoHO!#9sl|aO$2Jb)XH$eH$+ABd^#w1 z>kbhyI2)DQxctnbavlBe=>%uy_sr!ZRv4=)^i#bSI=#K?Smc$oix@rjmtIkxwWY&g z549B&56*aI;L)K3K)s)LXI9CWt%u{TM=NTqcAemPfmG0aVTS`Je20t`h|;y8C!%~u z#wK7VWKBU|!1hOYhX2G+_27eRdPK1SdOCZ)q&*vy$8c+bdF%~G2xn-|i}I*8JH|uo zzaD=&X+9XM@5dEAHk}Btys0bHu#+YpAis}`Fc~lD3`vkS=+PT8l2|-(1d$kyb$xwB zUUj5=FuyrhcwIl!CJ99EAi6YEZx3HABq>7DXiImJWNSvnhw8X{9*mEJ;oIKc>e$FD zyE>1HT;aKB=J&FPtWY{Id5z{&zlahpumLST|6EpGSnG-(JqlRBgTFlS^O&3;0=DM5 z1Rw;nfnn*-(yTC=%W=T0N8}u4zjoGnh^+$U3L8l^&*TPW>&c;&Q8{uIGz`M zsfgB;g@9k9b*^3b6RVF~>;}kyyTz-Jb@`qsNew)I+K~q*SXbwWGf#VtzE>ACp7}_f^J{5Mid<|~THGgfmYkK@0 zba}P&1}c{#B~zvcrs+Pfe?5&y{X**91YuF~*wsL4RlP};gHZ$m1)NLkowviE;SvI-%PT6Y{W4@JQ* zPmk9s+o!*i=UhStW*X`bQw->=O1n3|=jvBSDUi`!guXJynerMV;TCtJE=OH@lQ++N zo6!>R9sFD_cUSR1w|YD5_p(ImRF%fI`I2=*p9JwtqkU$pTeHW&XA=+IGV~TYh+*Dr zfy`YzOGe5$R(3MJHszzClrR1xjbBsJ0kxHOA7duH__F3HgIHD|ARbEG=&jSifF-Z~ zLFqoaBk_-F2sP*P4x7o}zl_`=Q;sy-{K7ruU}p;H$C1G^TN{QA<3jL-59@KH!f^YZ zHCukJ<#M`AWbL8q>h8*!Nn>-7YB!mmpExLHd?XmAq~?@y!a7#Wg8i{p>oTJ8{(R)v zQo3M#II5$4pz-QFleKZudsEVz{&0SglC|`mwrc93lo@9lC0Oiob4LD~V_p2P?clsY zd(^hOA6LqBjm)vS_GNi3+}t?3+h%k$E4B!p-`dtpGezB0a-1MM8H+3`7K~8_Alugt zf>@egawSKtI3*x;Q8?d)t6iuydPW@}miilV@Nl=`OyMpBM?>JcX87hn;ko0MF?8x z9ms&w6SUqA338IlF#E_pVWV&^7WqSm=FuT$FUn+`*fw4VWnVb%dq5CJ4sZBnjhPAw z5~A|kAV<7dT5F~D`1C0OHC2{jN4YKFDzNQM#X&apAlDpMUf#M-EBzZ?a$;;T^M&EX zy4O^qyk+^Clqyi4x7TQ*KQjme#f4bzC|K|W_lBgawj_-5v9+~dAuyo)AAnYj}k+RHk~Jn z2ZGk@plzfvh}`1)I_nz;Kc}muZ4gN_C%u*4yJeLSdHueq?Ztiw*ZcP_^!e}h=Rb84 zTYiCrc)W1?o~Ra>rH)kjaf)5&*8k3HY~mkp6ci$2d&~L@F2+x)L1t7BsN)$nyFVm5 zAfNVSFY_LMJYDcfQb=Z=PNg~D@=k=XyXljca^6ZWXaqbVLij{NMOM6pT#l)z9P%1+ z{70$p=f>{4YI%4vtLVLOHgeED2z<+GUuJiNb|2I2{>mC{tH8sDD%z@Adc!XhOy%wD zD+f*BbyQGAQRHGnWKPT(RMs*HFWl%}eX@@dO;Mg}!X7F%z#D$Nk#JN3L+lgGdewaL zqo~xu%f99`;54T`ZsN06)JG4+L%&0`&fgF7ekBce>2G!(_q@0u?yXFbm+T>^WYsP) zxusfaG8y1*L!f$zo+FT9yT{wF=dlt(B%5_og*r?#x6fZIIn2j3>dIDJ<8|*z^gcdm zTYj8t%h!6T=Cv>Yz5ohCpTehMrGCsEEm<9&DIK^=&~Di|)M*Dee0S20t}vrb0j%+Z z=fjk{?bNcwwq}{oN7c6_eU>)2F8(>g&d=uyq0o`9`W_{#z*#oXb$x*E(yeGP0efNkHuq`O*dn--T# z>}I+r__{3O0u#Z_^W;*V_;WmyU ztv#d!TQ??Ko=$~M7N4$gfyN-@4R503iV!03Gm|*x<6lG6zKF|mxvtfSgtaqz?b3~x zJKuz@?B=^KzLH=Lkt0tnavo?q9Cc{VIdGA)U3^uXOMogytDAD~e6}srZD`hwU3^75 zd)Z|6lU_+f!u{=M4priJ#@bX#1+#1Nr#A%~vwr!x zHg=Hd@Mkw}`+xkWmNPoF*7;z9fyZ-7yew?oxqMF&mQvk0l0N#%Xo+T zrK}X|9iiun=S4#x!z%F$PA6sKiHshg8iyf}W}yt$-U~@mYJALEo5XF~T;b`w75Kvn zR^JoS%#bZl|^tjvqUeNlYR5oOQl4qO)(7q|Fjv4w@j zFEK&SZm*rgH6Z5gc=6=PwM`Dl|O_5SbzzfeU=hDNFNM&Bah0?D(c0r#12%kstUP(_Rr{m5 zx1e}PU!cS8b)u1;-RA72v1;E_Rlz9^bUs5duI+0#2_V-^2MDu8=wsXlY#>k-P}abD zndwb0F_RyMac4N_XtTD+E$KctcTfYVTgmDqQ_Q#88JNnrKX$IiM*XM2ZFRe%pk1@5 zGTw5j#8~dzbkY;xQ=E;nm2m|e&)(eLUk50tBO>r8BAplS-ax-X*{dpv+Eqq{i^8Al z%C1(}9Em@qlv+ofxFeC%c^%|}qUETgyVB5^s&rTptOk6*2JfbPB)tPDzdI4Ka`K@b zp7q;Sd>3=K_so|Xwp4X45Jg~cceqc`jYA|tj3tHA-OYduF<)x~Kf=L5rL;I9KWqsq z)^UzEc9$o*CBEK_$8&9_V^SfHC_IksB3Ggea8iu1n1>UKm&)1`DcxdkUWkg?`VNi|wDHsS=2z%a7~Bs-gq(6YuM0jE%{1=W4G+Kz`>Nl0gcJ+6gmui2G7%F3 zExHnEwMx?Qq8PxP!QvI-F}}8WwEEGu&7;pNK(4XEA{}paVpM2cJs5@kY-7;HcU)TTbJfD#to2OkcC(UBMGB=PRu&^xOOomBi5H zfT&g)kc)VU0fc%*c5a)|bq$To+jF{q%0wSz8v!7i1doGAH^)kF3UDvzHDsra+C=JL z!%m3inMXSMiVnWuOtAF9)EP3=MG2LzRO*n7&Vk81!Z=f(|Nivz%-;$}ru=uBG>`4f zYy9UqqXAklE*KT+gb#v;I(xwR+K z-`~}Er7hZW_sx*6)6{Z_Nlv>Qnaj=o7tzLeUEB;%uXes@XmQQ_@9#upd!W9AvoQ@u z>hInq90#s*Az#v(sB6WVSjMi?_^r%F)g5T`K+W17tP#<*fg7FcE^>Ly4`BCyt#+*H zhyWjb`5O!9{l+qCu~A)P=U{}RLXtF2lk$=nZ{1Qd&fxM;5HmV-qMqYr!)(s}r51^N z34#9AhO!m@cuURXbGDAjaf9F=&$d;Ju=`ubyYLbR^#a3frObc?i8#TO*QzJK>l4t~ z7mVzc7`#&Zy_ueBM|$#`Ao}A!jX_>87JK|Aj!!Kp0vS=~s@2N+`&>u9e$@M@Q${@H zi)oyhCew@m_KlJv@u}>&_kmfgoW=Y8C%*=3c+3-JEjFHB?0wQR(xh>7 zzb|x&*3eJkIG4{K66dA#1hFnwJvaG2@JKjfGI0|MRb-Tdvempn2bJ#{ zw>bS$ZvFen{tv6aHtq~^931V*65DRM+qhK{gxgaPNfBsG!Zy>fc1Ff$A_twmZ1*@u zMr*wIQM6%cwa)en^*@Ofabq<{8y?i}syO!`)uJ)M_+bWO!VJF~GiaA!@X7w_KCAk^ zLyJx0+1xCc;Y9e#?fkxM*y@ty(<|ek1oB2#_8|_Vit zp*ilai^EF;RR&7W`r}m?3c04yXvsXuzS(jhCm|c?zhXvU%JOvHfDZBSB`!ggSEjs_ zFptBA!4dvH#g0kD&fVQsv-Z{XLBnwXd z9{+lywTjwfb^^~~vD%Xx+1&4iTQze^zDM{}c+5KxbLiE+FyF?Ys8CWA)Z=6tXQ?qc z!oBa;I5x7q)R*R%4KUCX62(?tSgh%$4C}Gy|CL1 z;*zjZo%&?jJA$L1SSn_zIpsmhVH4)ynON9%hH!%V6|Qb;PSqb({w-WA{;$HtQP!88 zdu5S7E*#8VXeiHm-Tb?ueWS|D|_)YFS|^H=Z13jrrBI=ZJ| z3beHQ0q5K3HK0|BCj_rwRK)KN8yBF8%x}A$JWnO)0EvlOrlGbQX5_z56%1xo22$k*HoYumCD2$=i40TZX(F0-W!=jEv+@V!_xd#WXz2 z$x(}SL5;!%MZ%Mj#iQaiZ3415y5<n;msA@+=OUm6{7iKPgc#qH2^SzjC98B`-H@>c( zVg~!$8(GUQ< z*LYQ0oZOJ8^Sm!_iy@k|9f^Fu3t3FOK2@lxS+7Aq`z7ylNL17eYa7Kr>#n+t3st0+_p|hg^U2?%R6FHT~W^RUdd2Thp{Zpr9xcJO$&>_zI=i; zw_&mA+B%*h;YZNy@#W``OVB_~8J#?(d4{;lDs^%PE;rQB@F#&lH~yC9>8QyADfzCi zD&g|Nx~rxhMaX**(&gYhu~5#o70qli`iLN*If9PKgsCS&t~%WxTPwJ-Bf#rg8xC1v z=8KyDH-x)Xc=l!fvvE`TRd8dRw%lRr>K2DVvVkkqI!Ce)60X`{o~&wef6V1u;y6@4 zFq&|#A(Ey%6=;W9u#rjbduC+T&Adgf|4)W_^QDibm`FMxw+zQCZ$3R-S3tKW;FzsF zB(A26&$k_JbT%+?O^KXD(^H-q9U+^{6~Slrq*mp|&(3ec13#H2kv`IHt}lr-GH8R8 zRF2jhz^67tC?3BX!?#m@lO3Mmg-BxAh_a1U8gDPai+)r!l`Kg0()*nr^-GzWgeSz{ z!!-ZQLS@Oalg%$9N2ZwrNH@V%r^qy!X2OzD($p=6qr=qq@1M%tT0O3KmDkh5xRLCh zMcUr<;M(AI{rm-tpbx)%Rw)PBHa_*6ROaWVka+}=qcp<-towIpJ8mL?wU3u(Bz5ma z4qDO+XlpTI!JJJEJYv3%_f*(qMnpluL$1~KsjBN0= zj#_qWZ7;Kg_u7&5cWFmy?>zeIbKEh$7-Vn9?2g><0DZ{?peH@FXTtU`~1kPQV zoUC0H&FBIEqa$3c0ura-?O9iElq<^nqHF2h8;J8_li@k4?zBU()MpbApf z@~#U;8+BhMjaXpq8P0kS95P=~MRo9slRSQmi_>OBBybHOSdaH%V?0fY@mi9&KeTXC z26DGNXjG(m6;cM@&9B@&b;x3MYA)a)Y%Wmppb_Af;Oe02;}*chlKZ7qOl_=OP@eNadRy4elbvirk$Z z^el=zB2<{# z7Por*-ejRh1*!NRQ)4EXu}hXdFxM`Ge^^x@w=w!*Taf?8-9GV^UHQ{oKxqC4+eeU2 zbRV)$)$RA29^ESC@+14McRFd)Af( zT^wTxgJXtPlWi*mCVs7DJ5rjxl1n+(iXS6<{gjig^nlVCqt#dawwD8E6DoX<0XHuV z=T4<(8NYC&h!>jMd0#k+UjGZC=;8V-QA&p5y&n)XlZi^7eLIsHCvOgJ`U2*G9#=!o zCf{L`x~aqM__8=^mRS~#vI>Kvg?8>{GLxWl3|%upC!y?qr!){z)dA<}wK9J3Lj-xU z@50QAdRbY|jj_y&5`0xwt^QtzsLbkA-`U63o%VNb-Z{o27uc1$vaO&u@iqkX z_m??(eh%#5(q9`JFTVKvx-vj#cdU$@b2~Id4~lw#8V&9!n1Qxw*G{sAnq7)zx#SQa zOsc2XNhdm`_(iSCd>>D}wG|xJ2tG($+X8%a8&Ckn12VI-+A0l= z@KDGKEEw}o>U&)iJ@f(KLqzznU9RD&`?hk{$d_bKTJl~ZcqBXjOqd;TQC>4Koki&o z5X7DF-Th8Asu~OD!Lz|hjMY_>A>x7iPd>;Vy^k2r84lYWY|&>;&dKF-=R6*Ni?&rR z|N0Z~LV(HEP37}~D(xMH00L=}#r9GbxwmzX!xjHOB8&5dwNQ^RJSv>~XRi0Eu)& z=jSJ_{V)x8P2TtjusY>_@a{h*4Y0>UFzVlwi4D+>bqnpkTyp9~o^=c+tHUf!kK4R) zd(@^ZQ0qc0PCI=X3H^NgjUakTnIo-J1=vjmuxO#G5|M&!j>~wplooXk% zupEI(G*ob3&}=+7>AGC$?T}HM<#%4(a-KjQ{3rBSxGW}WX ze?JFwcLYp>y1Dgx|5}QFMy=HZY#yGkMz1B%Zos&IR|>eC@*E&R^~n&{?OGW$#DC8= zfDd3=$;grcoZxq9w37e0_#+*lj;nq>{uPjk-NlF(1`3y6VE{nYsHv&A4RmYZT~C0v zwdBWl-U_bGWtT}POlQ}xlikquT^nskY+e(cB7%`H7|bkr-B0H88qUZ)@hO4AwejDR z4}g^44jM_~UzQB&hG%p#J>b|n}kU=I@G%H!hR^3>%@cGpmR%4@BGlj;4J@9*TBp!Iv# zl^{Y4KOVl5-k+N)s;^%s#pq_aLA18D%zVjJlooa%Fb0PkwnrqZvlruJ`~^?~#xfH# z{Lm3jNF0|t>+Q0oz{h>>xEc*ZN$yXt<9|@JT;#mg!ibe=m{~0v__4*PMSLd1>^w+35aUObY_`I33yRe{M;#mLD$=Ap>V7M}I zwH#r&+yAqa%|PHr?OfIujYuC2|3AbGcrU?gA_C^wnQo7$qLl#=nZHZyBa#a+e&?M6 z=%%T5+3mr9W2k*Z_<`4|yoIH9bGJz3orl+v(Hkve!33;H7^_eYaC`#eZ_@c({4*nf zdE_nZ)>V=Ft3N)+5sTp6@Fk4~*fcTAqEvGKVs2VIM&M0`KH{1TWv}~x#`|--5XOy| z-T|JfLnG4t?^j}__NjbmRs}4ilWO|&zjOf+^e@ZbE+9fwJd7Jcbulydb7-fd5~8lo z=f$rcwErt&9_M*Y8)~O2>7USgX)At6hr{t3q*>QiPkberpK>NEl(vEJw zT`aBl2#P!^AKecdExd zbKG49bnA_$-C#&#JLN7{<}oY1_lX|%0~V+@g7sI$<3FvjvU^?MC>%rj_WBP}*i8Fs zb>md-$R)fG_R?-r$(dT7Obz)WG)bKFl9~QXXy%)IlfhMJpF>-C=P^SLx@WzTFi4Hp zDFAP}DZcNr(wdyLH=}KjotY<-w zVYn~mb}*|+J7bRwE6vgz)?|HTY9d28F4hCZoQ++aGcnMP;8kor!EskNEenmChLltR z=Wi4LCLmVg<70RYLo3)y_aFMueY4tV=%a)WHCD1=0wtDf$ht?Q#M(wS+GT`m?a4B< znQ^-h^aR}D%aaZbI(;=DLGI`2-J{-pn>EoJKlf@cT3VeAZNLB0-Ixfc;23MM6yIOn zaj*(8Qj|0u{usyG#^Vffb|Be$)!Q}Y^NF|o$1Q|eLPRp+RBo>;dhLRBzp|(n;m#6k zkwUV|XyOpTM;rjOcBzsnsdENXz;}@pg<@6 z>SU|8Y2D6r%6;3H{CYm@Yv6x6%iS;6dU$Xa;|UOrbumCMO3&oYr4i&+bHZbLsnD39 zKH6cJmS@EtD;s*3ueLTUp~0{(ipm&&+AFZA_@cf9#GKMAt*#=0mGoIA-@cFB+L6XJ zn@@p7p{TTPH(@%ytVPIZ#O?WweytcvFL+z&6ARl1%ZV=8$V+Zk zyjmTBPlu22R5ktlS!=-%dZvvj=ie#@9_`N5N5=QsbOBgtb6zT)o;(K$dvDl< zP1A#^oghlZWGSZ6Qm3O6woX2XtK)u9r)&wmmw*Rnr4mh{g4AT#(n4ejPiDjp?v(TN z#L`L7Y3a&T_ti+X?=mS?+$m*n-}9UY63N6nl0BVJQQ!ys1d+^!6m`+fyD?#5tk;r2 z2$;f!i#j-OF>d7bI<6Q4#)KKa*{2^SlPTJsgK(TniIyP#4_{v$SJm>p4G2o7fJ!&g zB`q96kVYwKX^`&j25IR=y1PT^Zt0K)=@t-p_o1%$et)0$KRug0Gka#%nl;a}qWtGi z7)jdMkG)l=N<2NRy9X#5wz-sn9}a#u?}V-xvKCL*3Um#lP-p6`w^zh8e(JGcE2xV$ zs8T*j4(=&LM{Dt?_VB0|AECQOt$%6N6Xu0;7PMK8oLBwu$x}y0)%FP#M+wFub_f=L{6HXtz(fUT2`FqdnftTl&gvelfP$aqvQYAF zV1Y&a_n{7WMx#o9OQ;O;Gk@{lCxqXCGgAle%h7X5f`fH~5J0TR4Z%izy`4IKBCzVr}2V16Y9 zA1a3I;k|WqunE>2AbDrR;9-KeGSDb#i=09u9oN*_3%EA^4(fWNXrD1$U;a`f1uzBn z(unS&Bq5-mxhFX-FJr>z8lJzv;Y8fx)y%$)(x!zU1RJvN6y*}*ud6B4%VZsl0HEF3 zo{{5zMQTBA4w!Kg-r18Ei|U-PXNumkOa7m^7YjR3*C8f95U?5r5vgNA`u)A!iDDI=R!1wb{w=7t$x=t?&lq%6J3#M?CujJggXB0Zp$ng9HuqJ;k z4{)A(z-F6E<`F7DX#DpPNEqCMtYpEIM(Mxa0aVR3 zXJLU9zqcC{cumS$bcepQ6~;1{?{{tKw)JYbY|Tj_w?{J8Z9CNKU)op)h=RME!U9&S z67AF7XUWFIF&W%r0n!jMzdk`~XdLAPimasRwZD|&uw|rcD)|s&{hErrg6D}b&F+Mn zOLHvgr8$PNozbDLuaU+Q^T6n&@t3k#9-`(y>4EP=R*)sFU6swiHw192` z3irYRQBg-n1?L66*=W+%?){1ClgaZY@Eox}LSMrlYBiqetCy;TUob6UwkC_R#JwCMpMQ+9M7q#qTx+R$ zLk~}y3}c&#jh5HbL^n~OR&{`dYeLcCc0c{u{vgGvx!6Z6_U)XWnSED3-)gov%JcwL zUBh0Evp7<72P(lbU$2=CFlWB-fK;pSZR@bH; zhep?2x&^WL>!YX(>MM#DV|It8i6V;(HdNL%SC011xwHv4-jMi?Nz_jpHe^SNE z|2pZ_j^~Gyx3Wop2(Aqt^_`b!u=PiukWG8VuAR^%ZJ6|aUOYH)Ei-^^&JQHID)Wgw zX2xgS+;$aadNxGbMeTK?eo*I_GFwnT5&_FU7t=s z*d>AV&C?>G>;HspvS9pFbacKne5Yu#(}jdl)~L8&L32v-xF|o+MVgwXkoI?S5t4CB znX{of=j*3f^H&Z}r9M1Mmgd>tOH|S@*{Pv#fNwmDzYcpE_h&_Y=HNJzFFApR%JGY% zN!~7@bMpur!7@wdkZe?Q_<`fv)w0C#Ga9ZaUYd}(a_xPMp?p{2p;cF>ZL8hUHkv64 zyn2nLSjmgiSCAO(vyVo4^-H2AtC6yHV7u{ECK>CD<~s-ywb50T=6;cr>W)B>MC{C6 z?_N~G;as0|y`VT$Qd1omPmXX} z^k+JAQ{0Ef>Dh4;_2WF`dF<8I1jqTGf7(MN_nmBo*5^Wkh1b?;+4topB7OnW|wniy|@B zPZ{{yAU4f?>Yv3sG4#1(qzaE&YXiE#ki84YYzKO zE@EuIcrE!w0v2BNl@0@vM~8SS&BEI+W+yw&dGltKHn9~Br@@oWmd6ElN~^46kG=GE zxV1LKv%Z_~n2Hy(G7#)kXb0GTKVF5i-+Z@#2t6tWqSXsbkf){RBEP?AgHGZ1dVB4f zeOLOTgr+e(C$s%oG5xFHy;kwBkC-oun&uB&3H(i7W>D8zlP9e)1_H?l>mqq+dTL!l z*k%m98jr-EB$f9*-atTrpC)K@U#jLK6 z=zHeZ<@r`g^H3^xcsR>$g^4?f&(&GOUhzU8^%6|i$ttCIaukThf3&#Q0HBlz7(2lb zx*!`Gw56daadv?5I#K7Y(a=2eU%^mQp8FHh9hH?(Cn+S3Pb2m`9&h-KI&Ef%q}@6i zF?!`|jLP;h*Y0csX#U#YGv!`b#S$xlI#5Ax2ILL6eF0P%1P)iWIfLndc<2x$=_c~d zJE$g!MfGb(fsR4*RytI}chBDRW7q+w>fOwi4&Ds{=ij0cT(LdFlH{R`Wj;Ocr!sxH znV*!EmVa5@Ot#<~N{AMb!)f_sA$j!;q@G8^r9P@uU7D+-=sJU;#1+5U6TE?)bd|#A zpvZXOTH&Y1lg(RWOO|tmwem+fdIt{g@pQ3ehH)|Yx(!5ga~MwxWe*ucJ-b60QqG|s zUnUw;rJ*E?^wPie50RiDSq(0FHp7LE9}$;)tY^i2`0ktFhi8}b%tudOie1`|MCq5E zA1G)wf%pu8v(z=0vwHB4mEadY*I?5sD+(y}f57WFMP#>3cb$O-x0P z%33%H|3+sR$IDwW4CmTfklpx75Qo3Ja96d4l{C{0)fv0V_A!~$pPeVdi>2@fyO*&s zWGu;*Td&Kgahe+6u95YI%$9Bh#9lKMohyf}__Wc14O4lrVJhm00j_1y3dV21QHCE+ z+9|}0HRXd#@y-LT=hpKr=3>q^GvV0!Ul_hxFCxIZk~!xPZ~hZwTHhD+s;`4i((L?T z^Nfz0nC9(;{fK%2;^$XLLWLrDrz_+H%BhshtD3TisxFwBttwPFj9;&Ua{7=ri1RCU zn_3#JsQ(P)r`E2j5hO-rwn{+Td(OkFbaF9u*k@mshoF!R^28^YaQ{S7uU$eY@-WSe zd2Sddp<>z7Yxv^udk?oWz^EAXB+|aJZ+|p@uJ(JZee8PQl{Ogl*S{%JS0#wkEg`wO&W~f57Nj2zR~(DQ?X^K(FMP-VV$AUYa|9W%Kej>q zn7}@cg+b*4Pg4>a!?WX+n)N}rQg4~Lm><|$l@21ih^t5rYpo57N*d-r3R-r#M&NbT z)RXhVuh0^yxf)`*L-n@nn5m*)zN8C28y0h*ryI}}U9YJt$DG|szBmZt<8CffJ8EjZ z@NMYxHW*@D=^sgmskEx>LpFe$MZ|Sx+inVf)6w@^YYkEPk&JU3SN9VG2C6-k$J_Ol zgy(L_U%#i=_LFY83XGAM7GGaqv2(}2UPL;$I&fXviN+qsBE2%-*^4g2HIQnZA=#5n zu)=DqfxDh=_!K}ZBkEUk>aJ`%@LOzi@GD&2K(S>L_T^IUyU)Hg9nq!sIx6V~4AY`K z49%8`)(0WZ@1Msdi9I^h5lB6326jny1K5}68Vdq!`vaz_6JUk_&YE_+qOvt3I3~JA zfBKMhypOA35q4E)N;eSAamac&CP(bRcZHO4z$S`3874Bjv53|=AU`7lMH5hU+f`_a zW0{01ttPiZgUShiJ)*};Dj^^EVB6gOvo%5cxB(>c{Cy)UqVO}dX zO6t8;nj#7n1LR=^j4La!U&fQc!N0K46bcvyaH@yDlSSNFbZ&0Ba36X8n=In~c9voc zIr`sZ5%*>=u&Jc8-vJcLO}(bOHz;e}GJSl~E9Hm23OWHc`6Aq4H1auAnw|MeXF>R+ z5vm4y@`s)S;P&iPQl;}XBbu#%!I_|DqXhu&bF&PgwMgy>@;Zg=C zIa!;Ix6ixZNL?YkqBtxU({}~z&iXQ`)Du}T{MzaUCq6H)uL=W4CWzF_20QQ3Jzk! z^E9ELPZeGWL;Xcv=)Z&T2BRB~oEsA*no>Qtgb*wKRofBq=r@pEDl2pZSnkkh7`_{* z6}Txv-q%z?)fWJk8wbRGe|ozy!4eAH8tXFPE3m@?qw&puffX8+gE+j|!|%aY;9nM+ zOb_Q90IP$e7$G3Zz&CVgY&fF(3q5$bKqWA!c+d{wKvy9{S|9J*ySXWWE}pFWd$D^1Ym72`hQ0df>}ZE;c?&F-vpr> z72HR<`$@@m2a|KvoiTUVI>7j_1I|z2YnZeWFt?(P8>sB}4b1|1d2X&rKoB_~+!HW- z?Dy?}K(C+~0AdxuSimHqattF-HRis1pe`i_2q@OKhYr4LL7_<8-?eTe%6;eQw+}#y z9KbGRCZ)U=%R3QF*@F6n!3$`zn$Z}_zgq+vkHlE_N|0X>XCV5|1foiV&xcuuM22Vo zc?H%g4a|GC3MwSNbZh);fZ%_YzXV1uK`iU$mWDw1ufYE70yj@ zJ=U_|<03^{8i6C?pmz$ADZi#t@uovMbgk7Sacuwi{#1o)v(Wm84MhbY`|@pcl$k)V zK6q|v-S$T%K?!K9ywlDWhkeYH@33Ki`n#1+BlTg1X{W{D>Zb zy>l3j2)8p2o>)bY-GmGyFqKp`e2h2XFj(EeXG?42?u3qevYF1{QO&Z_9kY`U*EJIIh2ZfVx^|K25>XQkh?h}NKovp3B_#BD~3=FT(y(GV9$U)->>n}KJYdLCa-?Fg@3#&@D#H9U+ z7xo;#=sh}CdHU4i0Kd+Tx;tbZtJuoJ$~rpAwUoYcA1T7)bEj(jeBy2oO;O*x15fe^ zX}=gZCT?-}NRRE~5fO_Ls~`!hwc_OQ#h=iuc{#Nu#v5L5o`lEh)aK&U$uss*T%6}m zIIz5nTOKrlMaxLui$JD&%{4uHEtna@vMmhcy{CFjP;S>8AX5%y`Nh@XtQRJ401KVC zpBrnL!}2Q&!|=dU)OkpMl3>VM{&C;rbgQ;4z8xFE~*=G^CA|_ zX-9C-1MbRKCPTs3&r%YaW)HFcONSS!vU=pJ{qPOUj-8J!Df5qx9KVM7A-`oaH|br$ zy^=>qmcB~K`F~COuYo&$WPps8^4A~IezKlW4Hxx zO9M-uANbXqZUIPZAlAf-*Jtfl_(PVhrQWN@AphA2BR;D1OYnxY=3u-j*mEOaA5xZA zPrmhCl+ilN=PT{B`%hPB%!UlJMMwQ#Tvl{uUB+4!%o75s9~R1}HHy2Qn^(oc5QS8#64EIAk7@%A!awBQq3M|)KoB>U^g%1uz$WsmW zLA$7u4FU#7g?)S-5&rSJziNUPz5KqVvnxWz%ywH}6-kxv7&7bi z?F^=bu9yfV@Qg-CYV@QH753YZ^1h0_geL#KG=0|EJ}DU&YVk`!)YC&($zro(q~df> z`9N}zf;zf7bX}E*s3fS#`Qsvemqb4WR)17&FW;drmV)mINtD_|H&-;tVS$rwa4e@D zDet9)G67_Uz{PTuc4nzL>+Z7-RA~qB>EQ~;cy|PW84p5wMylFY3yq({-XpJdi#}A& zNKkCU*L@b!8ZE(lt()&V9`LhodTj!$BPqBaE3nj5h+Gy)8NHnLW9BK~Dr?y>VUahS z)}OIa3uCHGz+kHj>TI{}UvAIo8Mq!K)WRfUYS`v-}uGUIrjG8 zk3m4GmVif#j4$1Ed1qG)9s62`FsW?Kd6D94+tSmSw#`)(jCuctcf@R+mbPu0C4Pn= zEi>z{$ec#1wQ2Zh%Bu{nmnYvQ5C4ptpd{%=B%2YZei=L-mdVjR8lL?gs3(=o?N}I{ z#}RGH(-|qmGa4>sMH92Z&Y_5-RQv8wgOsmfV~Qdmmyhi|W#hBX{hjx*u~Nh$lpKhIWdo2keV zJkgWkdD&o2)i~@hENFaeVz;V;hqfaR=i6WquzZwgN%Y<8;tj4quAi<#n1pYQyEDR)|&Kb^}) zM`%UQq&`QL^@r>DursEw)NXWq$#A-FV)$E`UUPre^DuKD^Rl|B;ZR7s?*Hd<}ivHkE2lKE3IRq4G$5@x@0(+xOCLzTRK>5|U#T zCIwf==Isw{=CNcWF%dpMh>Y!{WUQ1mu&LM!#lwNb@u~q*bGR`EYL%#8cTZJ# zdOwy#(}=gdE1PQD#3aK_mEJnN2|6^%;8>)`DJHLm^jP#0BN}#A7S`retx^yAYSfh9 zp(aYvq53b8EQZaNmQ#aL(IQE$HzhF~qna*Ugw#*PEKrJ$;@LN6?G5=+t|iH76baZT zzbwxOi|1P;uzZG-8aGLcH&8Rm-y%nLVFX}-dJ*b!D|yCq5)Db#XA>gZ=l5|Th?zOTA4RJF0Jy_S4=Fk@gr z^Y~9UH}4nV6o25YXw13R+^tYzAX(RLd`2G%ntuA(D$O)DLiZ7^^Y%X5N# z5^& ztdeqNHVR=&#rLG0{gkUy_5-JJ>q1hKFWA!Q784BLhKLWdO&-_PDcaPpqWn^;L&z%}Ss}8cO zVI8?l>Y51Jok~Utyzw`D(`&z4w~^s$T7ODYD&vW$ilvcZhESFL1C35E6U8sC+5KVj?fPjYeeeH;NnDPRtJDP z3Q4jADGJF5+@OpMS{{E9C=wPyO7HR#lIQ;H<7I^-#IkWLR~2dAP@BccTVy`Gf-WkaSvtyj&;agBzl( z!ncXO4#$s*+Iv3M7is;^(zJ zr|UeUpb2=)PlksGq*Qy>s{2o^u{%uQILvt#R?nOrE6GCP0@Z9Cbc0Ix-i=R%)AzHR zlTvXKohfN%ZV7}Rn)<*zF_j|TVV*TwE*&|SU#z!MI@3Ms+WYGNqkT;N;JJ}=VtbLM zx#B@$JRAC=6fTGJSJ95KnUsB%%cMT5WB`sDIZs=2{$ZdMry?-^#!x;4OC5Hyp0^}` z|IFc;Hr{+a=WoH~j0p^0e4ZD|l+hOzJmG|EQ(=3DFr2Kqa$WviZ0IHw(X#$xOe4c$ z{>RH?BeWyP+Y>HKS4u{sC&pQaTMbcmG3bRWqZ}kPO}kEPAB6!I2*6)qKS56VMNCM1 z|Mn7Zs~=ugZA>NplOav4fQ?g-pmuW~j(^pN=-b2JK`|U-BzUE$)sKlJ{ZwQ-LD$A`;7k4i#AaP`KG^_wFSQ+5dk>$}l_U=o#_qVLqq$ynb zB6}~?FNR}C96edLXI(dRKlyJh#p#10C->`Ep`YwDs%(`KvVUvwz(Q*&0sAH(meC0t zO_o|-gi$L(`9~cur~HIr-Qa~TKtbjV-&`i>tPc#&nK|&}9krcR=?E`#d^BzfJA+AI zX=BB(=yw>gBue8v1_L9ZcQs)U5mg%%e8QP?ApkW7{RB^RwYI*|;i`BH`&o_BYLujq z_d>i!bP>vIGH7OvMs-nlf?I+Ww@Q08MNd9G9&vgrW!u1_p#D*m{ReB1mNz6+Zmyj4VGo=38RU$7-h|7kH;IKf>KoOgYm z(nV_F`1YGm!_bTfA7A6}Jf0bCX37%IvhQ$)qbMU0tsI)g*g(>LxA<4*zEr z@``;S&97l%^5SKEJb3jycJ|W0kqR?LK$EjerTx{Jg>;!LToO^VLp=d2jece5h3RN@ z{sJqmSt(k~Q(gR_xUnB76=X~lLM?ex2PbsWB{rL|!t#PtVJVY=%j-&=u3xnb%pi~r z34AO62?JAYgK+Ad40ob04iz5-_({P{91F~3U|7|ek=l6&YFt7*#(2a(@U~~bt2b&@ za+sOL5@807gf@h$!ak`1nRW#wvF4I}1bC%Ed9~Z(O+l)Q?^k5#8b(amA#vR~n7=CjnbvnQrz#yZ zAWM+X@JIa?g2mvXM19GaYpW*(>`(F0ejbUt^i(9)oi*VW6X$iT? zCn8t1YUStLQ;(&&DtjYcDkF9}zmY5~P(LfX@%`;S#w?G``M155#7@y|3-3w;-+XR2;&e%a^ctg-WOwG7|2CV) z!>!~6{qM-f8Q~_1j#ZQ%^xKu-Sp2k!hbFI%DvRQmWKhsq%d$USmvE zmZfakrV1Qu?hyA_z>ZyLtt6yxjB=b7azWy(e_o1^WZ7D9$##8$%~pP_7S3+Y&Tp$B zbSQXgFrY?{1a;>m+==k<-kHH23oxT9-8_izA*3&g5G6N&v)c=>+t1g)pqvMk&^;51 z9qe_Mas;2bb~pH+AO-mHDK;QenSmM9zn=gXDj*lhHZwLX%)=Wgc>muN2Sy!% z@VQpfVC;Nh@H5(tizfJU3ZXdcy*+-#HMaX8Ke`Bc_9+BNh6na+JtFgHl$Mp3TU+Io zA0O|bO9n=A11Nul-n$(oCVC27L8gz8D}qd;2|;jXCVU^F4B$D)sd$432V7nDvN#;~ z_X#LXchwu&b{Z%?0SER05GM%y^^}#M+o*SmAWSZCL7;RjWz=6TIVzZd(@|;w4;U}B z3WNY>Hg@1oDbMFum#U%=YL5ZnC<_F@MF()yp*qEV%H#kPthQG~1tOZjFBC#Jc!Jj8 zz~Sp5)ApCCfSWo<6&f78&L39WTZyygpHPWY!g%}FAkaPxs)jODg|#(qy>BHgSpwh$ zm4tZ{m#{o(@ufZ;01l&}1ugFv?;dD|fP?|V$q?9(ME@+_53FxnH)Dte-lF^ZrsH9W zz&PML$WfqiHDDpO5j;}=TPQDY!YXJit#g;Hc=eayp|d)IO# z*7`D#u(^QY!CmTZccDtt0FAx2dCkCZe@x#G=Kh-wcTm4QyZ`a-Bb2~?^~4D9L_pa) zzkg+h{sdMu1$1oW08Y#Te;2HO(-{Z`5T@L3Z(5(;e0u?e!)>5Gc*_1GgDV)I*83i< z%795SdE8-k{{sWmZMqR)8@&NGYZgNq#{H}l4$48TW8X+Z5&)B*aImw(JRl5&DdJFm zfbSKMW(8mc?1mU`a>CrTYK{Hv4^avem=#!kuStC0*UjgG)(}#JVX%Q^{D}>_@VDdw z%O#EMj_;2SumZ(e(htJ`AELmsb!bSkJ_9a|)%E|8&M&Hf*Hx+dch)6gnE$*+1=dG8 z^t9wBi%|N1C1C~&1h8S0$m%}AVnYQ0!DRPq2o|;!RAB6wi%f*Dz&^HyVPO8JRj|gF zoc69>zx5te6NIpSfY`qwfHOU4FtOaJm7{Wq_WNZ4f#K!H?l%sp;I6XMKx+dcG6Dkc zm8Z`x(}aPJegFwlo;X9kJ61gT_6Klig5dP=y5liG_Aqwbh0>JrbH9~CaP+ z-csfAQ923!kIRKH%;%f99ImMs+p+=>Wo{s0=wq64C;7iab0XGkJR<%ZI|54lKSFbWWxn%G{JwU|$3LBOtV z(RdLz3|T)^4465;>52*J>QzV~5PvCJc{lFIiZ`4Xbki1L*v<^%?B`n-OZviT%)q6bn zjcN~e-VUO=nJ(EWaY&nP^AgPD(AfTc`yV_y>-e1FuQ}D!K*XJ{;=L+P(M5>JF|WVZ zZ~eInU76NAls)Yixf-0T`wIB5bE4Tgc~-qTU4i*g9T&UFtM9hrIYV8op$#d15gH)@}{c9oDn6rv~Hz^qGH_N9=hcGZu_D;1{Ed zzLdMHr3|oBV)1tUie)C)7d!&yt0ja395@4F!bBd98q`h{zX>Fr?F=fSt=eKXqGlB_ zq9h$(O7PU^Ra`H^sUbK$dO=K-_UE@Tq!`6pYDYTwb8Yo}BX31BX6?qJ`9{ZKw>JCe z%Kn)8kF#WP9|wP8I~KCHHIBb~AfY0M*L9@Cm2K9~^@@Vl4ksgMeZMD>kg<8LU9g_W zqt}@P@7D3^`n5jSxa!>s$C2L_UF3~rb`+8}Vw`>-YVI<=YPp4~2lF{>7zPiiheNqu2J$h>QNKjrP`&kNgMpw8=Fek0<$?|BPF3D~*w4 zDJiH1ibkqxW|HHh>K6g}?nE>d?70*G5dfCj>^cbbXfgdyBv=Y_93^z?-;h+R+}zrD zgktMFJ!~nMYA|3H0myZ#-rQDSy7QMg7Ov7aBbGOR{+FU6A;wj;?C`gY@-aeI*%4X{ z-knSaS&C)y5N*9M*r;&kvYn3{Wb|L?{4veCGgsek3+p@W8fWDvH#bJQyA}LndLZLh zE$wNtQABd_Ykf<*T9)weQ5@TD+|~SOpoDT9MUf@!;Gt?;{&Wn)ID;;omh|V2h8o34K}NIN9BsBHt8g((Kxhn2NzRD0 z46V6h5{S6bm4i4ev6`Lv#7g`n8fzc4Iy2#h!Rbt?uV?WL0I89wgI zer>L%<`^cEpkpk>TU}iK#Wd`koyd}y`c%%~-P*9#tVdM=N(>h>q4pA|p2gDW3Jv7= zm=?JzbkaJj?yuf3R!&YO3G^4{=36Mr{qh_~(d3va0@JCIg(kt0wYY_0iPX$qiHu!A zJl65-O=YjOC+lkhJ*x^1M*D);BdLPCg7dVv9C|;X6k&dkuNo+!4StQ+N5cvfr#5f% z`0N+j(j`=hg8Z!pA+WYRiEDklkeGP)sz0D zwI&&4uhAw$|>pyYo_LV7)*F~I8z*4 zIS`tu9j(?`VQa}0P5wkhX53sJAZdf>I068go#7N;O7(e|-gRwqpoSI-SyjtPn`IV# z65AJY`=B<76X+VY1OGmK3LJwDrPW}J*p;}U`*_ijbl|J4HH}&x7@aB-;5X8zE_KsIrPEk6Bp+p}H?3sh z_rOoeFE+;rEU@*etMimC*kT-ceQ-McS-;`Z6S9VW7^G}x6rOw#qhXctLARR3eI+hYCLhjmVlg=d=}nZe;One{jCXZ^Kpm4L9K)Kd_?eeh86wrWFucYv&;7 z)`EB7u(ujiC&1=&Y4;m||713KIdZNZe_Va~x=tr7!h91_bT{4kq&x-)L@b=BcC`FB zn4mGkwV>R;>Ze_i8!qLYOra$|KyXq&8ct4O74gd8&oKY<2&FDL%9`gkq$B26nx+?- z_JQnd2b~+}*z=h9&heG{M$^sscp)YO38C~_b8igjMS?{;sZw)ZmEh5;hCfx1L&rmK zWRtqct~3T`iqzkZxjpSC1VzG{V1vwlR{mcI|wqIi1)(r ze{njYbQJrwhfI^N!U{i~$4ChX$Dvpeo2r^0)^XTDP4MAr_gouMCx0t!koZQLf4mFn z^9FP}=1S6pi-(88=Y@F=yn5P%2FwJ;uq)nD<5`v`!Jkj<_hCsj=`N)TwYK0m-pry=1%uLwzk{ z!v4m@myVmCfbC2Kux}a`j|)pK2^Fds=dJ=93dmwbYPQ}dS0CB@o*XW@LTE1)s~b4! zidsLZV5CqKc}`|zAsdbpO*>Rk$zqbE=^wbOy^JP9G5M5K@g17^Do>Bz zrz(QAOX#i}i?q`eT!V+n(-@D(KmEdGn?345i`I;2vq>_^RI<911z}flsHo=oGYg0J zJVBXfJWkr^q(KSDTPLO%pBal%j!Nivxx&inm6D`gm_TIIi84MkO_s`M!v8exlqn>M zAb>1La4~Q-7*sdjH8()>Kf$s5zJ+J$S3kz8O)pLVQj;=p@iLFAhROIj*9qwVFvVN;p(%g+g%hTji3Drdr*H8+m@!U~RD0A`ae*vVjR z*?#}6D7>hDVGg76;TzrHS^yaf+KFYrYi~im`@ak~CkXrwkQaylzclqH)ytNO+)K{i}BevhZB=GZYr%4^Nko zoo5Gv$Yl$TU($}_v6zNE;oS%AHHwX+FNT;*TdMu6)*k9S$6PAK>1ZL*G8H12#wp*e zEa}+9*v1+5Ym`}YWM>i{c3Dm`%DfQIRu7D#cG)q((de9dQD-mlivIJ2Yt6(|OJv`V zHaX4aSF0AERmmmR2ZpR;S%*}7^YU8A(8E6D>%6w_vg#=p;Hpgi+=PWw;XJ*;?N~&H zpV?-c=HY3hf;w?#$H8<~kblumuOuW7gg+yfLMQ1zS5#VmAK=&N1u%xDBZ9J{AF7UD zCx#)cu`^!w=#(D=XA}Mr4j~b{zTw1VcJa^9ZCk`Fx;Sm>-L9)elK4x~booZe7j!nx zO%hE3hr1hiH4Bt?68ASf$HJ|D?O#1$rDdvb`U3s3 zkN=Yj|3QV=JB=)+HX(TyQ&aiWtKwt3){LADx!SSdf~tbuN9sg-p8?xO@9j+}+wDb> zlQcz#mziDPy^fvH$yR?bih#H3A0}gIVcIwCGhG z3gImTqz?qR7Qafi(`}(LrwvM+&1jrgrA)#}N>&EAaU5xo6&Xu^FZa70vy?HZqSxzI zst73o$!84(%zp0lw9z4WJmRML6~7srv`u|IH+ycO$!^ls%O_4eEO{-O66e^y=^)X+B$nr_38=`?1r*#%Dn)rJ8ZZCmTPHzxQ}Ho0`!kzTlb7tCiwi>o zsrSxWu5Z7^A@z*=;x{Twz|%c3txM=2p8zBc8$XQno8n5PPEi>#%ROb+pk$CYXxoXU`J9biHheLE0r}~kC{io0f4YQe9%}jfFn$BOz zjpPvVs!XiDv1~e*w#L;fKnh9I0LV4``eKpHPvAgpM2rQ0W}-5k4PP+3MnUIg*X2>3 zbT*swNSS;DM&rdF6!VU8Q3`&)ofJ&pW)i4`xaBJG>AgKn&-6*;aU1zPZyB6SCXB2S zZVE()N{uD6KB4pK*wT)6e8YhR_$aAn1CDuPxz?OPZ==R;fSE&mL6X=E^Eg%vIP7+O zb}I|wwlyh{JW&DC>+2_UDk7(79kefDXI`|0+sit2lYy9bA>z+n0rt`Y`)$XokEXq; zZL%Ut_*aSL$Uz;N=ROFfgfEBOeKvclPGMo;8bDfsQ$z0`zy0hhX~9Mn$b&gRo<{5R z2$dKwZy`Rt#5FVFWTqN#mbW9kMj>&Kvp_8q%a>51@I_dhX_DRmSvm|B0(R3ZK!l6y zIjzsYF(y0{%;JteGa0Ig$HsN=xs(j#L~S&@D9>6&4s*}1bcCLL%B)%E7 zm{aTgOXY=ay6xpDgbWG_Y&keasxC(wT=VH38pHr_n=UxEuTncmQ_pPYRQKvzI%ClYNczkZ)H@@I1A)4}UOIzw3pNC38@ck|ADXbr@9d9MDT8f42cBa|4@DxPcf z#A6j1S`y*iH$7v0xlJ97YsB9>yI+C;AZ){1VB(?ipWZM)&GVHVCzpkj#3@jZ%ZY98 z>%0XtBKiY8pv;a>(#B^)PMgB<4=0aG)aamSEx7>S+UWxI!n`CSW0p?G!Y7s#mQs)1 zOCkXf)wqrxpXwj5^A_ZB^8nL$#RzFH7CvG<^m_+=f!T#B1}#+Ba&k9|dr;^Gu>45| zfOd`0_;EmcvoGCB{zftXR*j%Z7*rsk)g2BejRVZyC(9hhceluoJOtT&my|VNV86)? z_KtZRd=2#s=62OmLIGO`^PrTF@_qMh$=dLWAFurE`c1AKC|n1|cLxSZS*>iPMsCDgS9eBCdF!4Vkl zblBgjVlDm-yZ^ASKKX@(|6g@efvf=JAPgl5q@XLTOs82MT!}vXz(A%GP z?{K60HMIn<=@pXOMqVJq>V0;Ao5mu+aC&$&W&}VAbJDp*-G4JMFi|j`?oWrs4+f=E zK0x{X6RZs6`uf|wOjaF&`JVJh2?WFXXf(C=P<9Fll>V*jKdK!OSTb9^@AK#Yd`KNk zu8gGXai90+xYeb_+hF``V4DTFf%)58eL$J-#=y+stEFX{Sx}5d#rF{wTmVZ0Xp73p zoDoR;eJcuI)Kkc><*`bvnRdVak@=4Jg&%^CAG85Ru4l;vzTLN$9R{*C5q(@@QMsHm zl)xwlOX&~MEQ<=X25&)x`uJWDs3@c(2u?>()SW90jytBCcyJxF(&af@rvC5_xYSu+ zG>y45T5R`!eF>%XA<_DBZzoZ_t3%!Ocza{M)T>;&77iiY(y#BMm@z+<1s%Z|&+jq` z>T#E=BGaVi-5Pnm}UyohI4W&#`q zYM}>*3zs-hyy^`G165%!#Zk(6ZmR66(hp{k0Mhkd&FVfKmD?0NY`6=j1B>Eeq`lZ! z(`lTX$kz9-S*OYl@YwRcU-D?3?wI?WQos3qlyGtRqE|uRJSTE%Z z-E!Wpdzr~4P#8%&QhZCBi@)bestIK6I>a|PfV^?3m;T6wi8?nfB!_fh?@_=`!bg0 z`4Q~OkTMEI6$O+Jt^ffEgKn2QI}{}1@W(l+qn<4biIuI&Ja&m~HkFidC(H;k>T5w) zs^yCQ$pWlpp(_3Q+S%O9J7l3aua=Rqv2?u&iT5$#@`g-l$#jly^_@2qr&QjDIZoE#8Z-8*OaVb{(|XDVJ+B+-~8&qq~?zB|U*r~Grn$UyVe z%wZyjWW^~uGqpC}(oM|X3fM2Aetd_FMEHS1ua!=zCCzfv;u)1a;rW0(|H&_mp-Ka? zQbXIHAxm1HdqO^>%N$2^GI7e|NL+-Mg6s83aaUP7Q&Y;`912hq>AgezzVJmjJeBv4 z(v{ivI0x1f-SD*D_k3?m!dgcwQ>il(ma`&Ds|47_Isohy0x|=fG2SW~5z@8^Lg-HD ztinNtFSVD3^JhTeXFjpgM&*EhDh)w&!%Vq}yS1>fg)h&)jGQ&1$?2_8PBYNWop$1gYGGy_ z&hMns8kSU)nZy>+Se+Hc(CazJ3DIdQrN{vt%_-zbSQ&| zeu{V+F1hktDm%P;6GX^M&78$wxlWbSc}>Dt#?MbmwxQ=DNhG-=aO9U1(Lw66IP@ZE6^Cv#)o>FTWe zcpf*;YCnESbH*t$DprXgetb^(XJM=p=kEx5p4WB_ZkGuZB9pUE-NR%8cgu8?(9*a@ z9d~F({w!UajteIn%{uJ?HAh8W^7*smzBLvrUc#Pv&gg6WK z@bX46o1J@s_^9G=wYm?Zu3lroq> zbsR9l1JQg_GW=eB-F(ak$Qr<1OH1(M-@o4IH}@#uK&nh1)_qQOGt|50z(<%H6gaPu zTVTo*(MOxR7k{7+jt+*7j^&OeFaX$m3K#T^FT+M~*r*XAaH!jSXHf89Nj1P=Cf-Hd3$Rd*_I;u1qWG~qJ1T+A58>@RV^ZOa#yCyAv z7pq$;RP@aps37w*&~p$hrSgl@AOOmYZ z$J&T@-Xvg!;Dag_*yxnV)7G|Pa7r*&8xj1sSJ&Q|bLgPWEH56Ab+I4o^^LU&K2o}& z9-ljL#k&YRnGAaNY5tdw3^2D22sg=@{y$kp-GHqJ-adHX+$=<_EPrSH1WCbtQ~{_F zaLP#B$2NbF*1!zOp?^~u1zaNvUZ`k`|8#B7}$60_f+P6V~(@2M!lRUtoX# z&ogOJpd(THNmQ!=xQ`E+z-~Sl)~1sgeZa@w44%1a5mHI z5MWV{YsSE-N5S(BzRqMTX{c%Pmri{0h|h`2?L$1g$$;nqSnF8Q(*J0%DOA)oTvf(t z=h7KgJwq!IoS@njD}#eb*^-L*JdP>^AAx9a-%r8Yy;&6<`uPfX_k zg5c*b^Tz?`mLi{y5~+XyUgOZ=lRdKUfFTEB1J5M6KH{C>@8vwPjj- z1cxx4H_hKs=U$WzGid z;GP^R;U-AGk$Ot8wSTO%x5JZJ&u-%zQvPJ%4IdH3?oeDge_6qA$t|Rk6(ErK3@7AJ z^R%98UZFB~tHNrwG2VWd&tQ77H9OQzE(vfXkS|V^C)-t`%6o|yxHAA7OpgT=-rn7; z+r&={q~tw`IBR5vlFEShqr4cdjU8_L#bG$M9nkl5kZy%FGxEsDSz$*FXJD-iQ%P1+ z3hliGvt1*7-uI`Gt%dPR7ds)(iOq##ns%Z8A6s7?msQjJ4VQ3JN=S=zcS%b~cXvxS z(p@4Q0@5wr(j7`lgLETEmvqB>F2dXU`MvzX2hN_|ot>ST-TBVWp4+zWXHR0haNVtws3V#%$aXAya~vxz!o?OrMUi}BYDr3L$#t{X2JZ+daDqyG*TWld|EQ~%(-L!3AqWpD?s1Qy~isku1+2?` z`H74%m!rBl4QdB*u9nNbpZ}6a67CXt7Gc4Wprjc?L%1SyiHrQbfS$uz$->fJJGtQh z33C4^$_GxonVTN0DEgd#&tbz05jw9kC5`PHO7eY=sYZrBRlg%oXesBi)?T0fgw1{q z1j4w)GTcRkpHC6BSS^~ueSua!+aEa6*vC$&u`u^({44T778Z4n5v(#3*MXU zLmhe|pOBVF%IfgKtbmlR7ge5N*WUSzp?zlqvw^g2;zi81rXAe;GG9F z8rq*DVLq%-?MfY>Ru)$>mgj52Y4uXc3sZRI7W1olL_ekRt^ zO4ii+M{QkPL^rCj04LzYe?@~6%Qj1>oLtV)LiC;U=8$31rh+)_VPwTZ>IS#V!RuS- z`EjKhuR+6x7?yM$aVGuUXtmnfsnV2@s0%69${B`<&yEIT&`9TBcYu4bnIAB z8WAr%U;9dAqN2&e|9|4|7hHa*a26*L@!_?ctO6;W_0Q~>mc*f9+vu;4KiCg-=2qw9 zY_V?teJ)^1aBEO$j>myB{HX?RrP)vWFMe;#W0CTMxg0(v@OwN1-!sEWGt{sWOYyjo z1(pXBEj~dNMCg|Y%!$%0#U$UGB4sRuxyr1K$C#XwzZbC?p^bzVn08zcmz_zEmQ*P1 zh8Q)x7>gVJ5><}SfYkYp92(kL_4@&_jrR6WhZ_lQ@e{+K)8=m|E8~UPitO$x*;SesX&Lh07=nL58M3lp95=lP1Bc7hMsqT`<{$ zOTuE2b2>bwx$GK?JhPy(;W&Y}t%GrV<-1?bePZ?#rOUF_s-wxO+6}Azblz0X%)jF;*omHnEZ^wR*)!R=6*?JT^<;MPf<-vL}flN7q_)GK%E&5x3`Q5ETl>p)BkVG z`yvV2MlHM2#zUTJNBUwkLLWhVUA@Goti(N3vuh(Ht~MH1yE`j?9;YN)G|Mtopnqez zp5z_Q%Jj=xSNrSoipt2^Uq+LWl3nK^O*=`NFG{Ae(!=NfDzBrM{vO+kQ*SIv}xiJHR%w=jzw!^YDIT z1*0kDhoG?F+@^1YCyT8*mMy`>q}R#FD~CCD1XI=vO|uferV&-lRo`zf`?IUE=a7lI zgM$N^Pt|yO!?n#^n+!TWNQ7Dh)YZAjlrP0*<&;@hW?MOl*R49T(rV>j_=B&+t^{r? zv~D>Y}bP~-1IP;-AF6`UVEDN)WafQqlt6L=`jO_0YtM$v) z22qhrE%91X=$x(Xy>AUU%4vetHuq1d_k_SA-qYRD{Y^9WQ;pbM zk<0blh5SSAmm2j^AKuZvrf}eYH#A;aA@}wh;mjVEwAQQc>Xn}3>z~wsbHf9O_>LVv zE#Pdtg+>P7o#SJLp02hMbof59um(sO#I9y9FY8*0Kqn57*?p=iqkuU=`pw)(qb9Wh zD_n!gPBui1VuWL&hf6mhS8nyEz%MbuL0E2;^j=cLrQ!LCY(sDMo8W zoSRL&!QQV`=lUvWriP7Z#(opNCBMGA!E|uT=|lDw`=rKZHIK@4?OXG>sFKV<$@=Z7 zu5NRZq?@1)J(QpCHjw`}Fbpz^(dZiU@)$CBUdK(M+cs~qo0U$WbKwSK<7ulIls#CV zp1z^1{tV@{ao74eusa#W<(`>XQFB)_q_z8)9>KyRT=!PvWLKI%;R#5k=HQyx+#5)! z;A;Tfwdy2zbg*|t(Ezaocz>L4zS^6~uK%>`HDVLPbx2m;4&!Kc%-H_)$^I^U3LG@v z5S-m#^ecZIV9v#M)|&rJp&#cxL-LC&ftQvYvFnKHHWaUkz6Oc01YF>Tb0Yuhq`~>2 zX)+RtY7>CbuxSfUF7(ixwjA{d6!@$$A1mPx?Z@^U-XXx1y<5)&%WtX-oIxqdjyjkP z&Y^UI>31}oPwq)(a!hJU**TPVZU+(@r*vU|A{`@qoW`LD^U2TUV)`xWd=~shQu=#U zBJP2J=IE-+iDq+?%1|?Y7WeJD)$ieZ?;9t7eKO_8KPZNsaExu_3lXoBst9Xi!P!_g z>WO{fR>W;bRXeo@duCNgB<)96xyIyBo1^fAUqA0E8x=EtgTc@JAu4LU$drs_Phd2$ zP4@YDtCJcAN)@p#g`stVy1B`+1EJtUi1w8+S>G!eP1wkOtzOqvr(8sf1j$1U*PsnP z<|&`E6Ff-5&zL3_a$M6%TFeTqK=kLoSBPy=cykEwO+g9v1)OfyhTFLhNDcJ7BDZ;K z+uFbW$<6m9o5^XXIy#Sf#2y)}7%_mm*&vVU@qm&jYD1tZ!a~|8^YbT`EVqBQx0EFW zxpou8^P-^r6(#jJCUp}6z-~Sku;;$&&{6c@Y9h#!Ozx9fjHrcZ_zB*DU;Ql*ne(_>*=B9x{~+xw*)pdmY-nJ!EAiU z5sSe5-c60BIB~?nYL7MP)h_FHhvumR9~444^2;bM;AFckyE2D8;gSPZ5^}u^>bu^+ z`HS8?2tyx~6$CO{{3vy5kVF&|R@Oq`000LUopl4(Y)#jr>J9M5+{g`XLBZ(;>$iSCy~;Pr{)T&{4K;v$y?PpcxYeaK~HSP(0Zq)&Z87 zyMU#vDlil9Zl-s}{tgDY6Q*=`P+)Bm7^Pxn_kaAd4p@fnq(wMg0S|y*{7_QB6Zfx} z07ef9Hcw1?=1Do$zt;;tyi>0Z@LvUiTI&|}K2Z6n3*KLEjrXJ%^&1ai!g zDwVi*Vs(ZAwSne8LU%1eKyG2mIwV(GNbxb7sc-3+F$qHW93ZFX&>{(SG6+EO^FO=> z^a=rq0~A#G2$2av1!FAIfV<%nf;D*_UYtDMH8>%#L3p@5X}mP;AVGFyIya=YGGjW_ zI4AdFIXUrn%*{ZCPx-kW5>f$@7=!qqvjkmaJ?VARN@X*(biUDfnk~lOa-4p2a#8_&^_*Mn4uU@d8U?cW4cj*&hzXc$pj%Ffv@2?yG%I6MQdALgliT3LiD`C2<3l)o5RlcrL{e*()sF*+brotAvJ)1{m?N;NHGPAIs zx^Ic#W$kYwT2}$wt&$Lp#A)usU>TVc><&|NKlYe`KTs}!1 z7xo6+Y!V7E-3i%ba(A6TAu}*TW;=PDo)Nj>aqh$G1gs!f|b+3!@>C6@^`lNH-R!VN^#0<@Zn{mTqz0^V>K5 z-iEwT7YYyZ9gd3TFL4_|gL&6)as07TogF=Rf4%3F`@(1?ha-Fun4vu8HdaQwSM%IW zT)$W48Lg1a3bTGq8XR`Sq2x0*Ep?+@!3OhES_y$bU;@7Dm|92%N z3O*?fzca}&Z%eoc+P^BT&;bRzSx*Cjx1*K3Zyq~`0CfQ5(vqR|-%;5o=N+$2R8jee z1>BSVzYbR#u?G;~j`(f|nhMMTyvbphs5@)QJ% zrb8f>qCPiQe70k%CJAXat;aw7Abo&fz}6OO?(FPXlg=`}{t4rwhcGnM3EeIvu)4Td zVq0bt5G5McYX&mxO#U{`d03?dFaxyCzAov&NBKD)`= zt>pvB-AH8jL4Ef_f&dv&@kyEIAPA`5Pn~KGgxvjbW%Ge5F+KeTk23c43FM71cw7`P z0L8X^2CxtO1V$H(rfUIap)63sZ_4iTuP}RO!y(gySjmB2>?EXH9~%R|Kp=*t8U(>o z97985dan_WM4=Pwj%Uh`Bpx3izkD3ReHkAL$Vhnv1BEj8L8kvO`a3U@0)Ok%$-3M_byDYb$u2Ta9%Jt|3Hs#;C3vF`r&iGm-(dngeHt1>@B;-d_4z#>1n zr%xEtOr7`%(j!N_tKcIrffC&@fL`UMMv{O(Oq6wpR44NGh6a>OeK7-t>96rAQGeZr zjSmC3I7I{P^EVg0kKrQZpb=z8lo=S>9(sRl5ltjr(K63eqC=ScuW^Gp%8Xn(oH+jU z7u?-4`ZzpbW{Uu-4ACnuZb-nk=iiRvi@|-Ub`x;B44HK_JN(Z<+z>H>Ru zAy-1#mw;3)Q4IeBur!Yek_-?+X0-1;J@sFP%_=!PjEo!|tFeVCGJY5v1;Yv@6HPCP zV8z9=nAN#00UD=SoEEM7ZMnvyJ)TTlM<`1QNS{*cKo)GYkazP#3%V{KEA4PEQ%bk#?gJun zJ*YlSKyUjn1AhbJN&`9quTcf+d~Q31Y@DOkKTd{ss=_cUm2fpU`gKM`u&+)xb8nTH zU46T{>#PuTV%Z9mr3ILQrHVlIDIjlp1jAs(FZF~3Z)t;3WM7Y&4_p-Md|9a9&m8Vw z2^PMNwS4vZy2a%t3>}?We4?QWcjAPezM1iK z;d6_*?LWsH0DZ`429b|s?vZs@r+`QMu*FUT&hFKFdncYjm*u(`_aR?>A|C++Ev zQ|IXUWLAb=A*{%l{4~nz=yY?9Es(2;MTTCn7%#(QnM^&TzohHksY#m+QX4@tqOFZ& z)O2GJ=WV`O-bP6Nm_dc_Yia3-iI^2$t3>MWQ(ycorZwBXciKpD;SqAboL<9iXSZmE zNoX7DW)aLA{7#aexV>{~o~*OZS(%z*GV*<*+gWE?;KPfn^2~UZm-fdtHzztQ%D3G^ zd{Nu3p#`3vpL=yA)xN*Hcxp4#RN8r(iC&fbGIy}V#=c}`n|I}x-X_+z`8Gwx9&>@~ zQH!GW1gf_`1YYM=zQ)%>e@fOXj$C~yow&@~f}7zAM+c7-0gQ2m>LX-guTf%hfSBdV z7B{T$+rrM>?g5X`ZxVP1i+*?_0bDO)1)@^BeIsO8RK6q{1T&Dcloio8SZS==XoqtA z{1*S*3pq~@@{%ewZR63yGJ_T^qJTV}3PTm4=iWM5DoQ_v8GDWY+Km65Nid1&m+iB6 z?X$O<#T&OjgFj+4-n#DjOI`HOR32|B_4>2O)>dE41S>6->;-7O4t`NzKEOREI{zjH z-Bl7b@oGJKuyOIlYsIP8TBjYJmZ9Q|R+U>M_*|46%N4kZ3!4RgGRt+|Ph2>u^?KB+OYoVqyj0aCKMkYF3Dy;cu-R3#D+g0{5$Zd0Tju8)5 zJR20UVINxQzi{+-`+3UjWU2H~C+5mVHHTH8g@Z(Go1Qx<;jPK(FMPjG0=E!xHQYxM zyb^P^%rjMy3cuNNn^`JOaO=HPcZQtOXIe3BgZtihMNOUJ?^I{xN(K*?aOF=J8Q^hd zJ?o8V;*dtaS`*=7-Td`B_mjZ9O{G&M{ugGb*PdF_k@2BABRemu>=~4M9361F&9b-J zmMhH1BhL%UPj^HUUS`z&T4%S&GnW>{zQFgYZ?O{DoW-5yZHx{PPPm~Y-244;k2fc- zCaAAj#CxU%hSMzbN8IkPsYd~=>rD3`mejoRHnHqEpqDY$1EG(0iLYlW<+kqZ$Q=Kl zCa!h#+x<5qm)zHvWy=$z(_1iXY05`u>%B7bxHrMKzvX;Wy{3yD5!zDbtNXdptnhX? z?OmG%w#cfUcBm^6PuIC}P%xG2Emhcm{2(tiemcmsVRoTGEg!cdiPJ)~;#@EAk(X;c zI*UtgqgUF9#cPW6Y{x9j$~5*S9n+z)%<05Ba{8Lrlt(i=^}u(&Ut}sX{O3E#TB9lH z{#gA}-g%qbs9(S1TtANc_zRzVRYqwM^R97tI;!j$m_N%c*Uw-=4A^SjGmyYm`zcr7 z_7fW=$RD-itZa*6$U$4f)L6792TN{m>ikA+m_m!q$?u{qWurowgg&h2WT)VWW!90- znPK80m~CcS=bCV(c<@KHpdp#DfzVYl8D~ku+ldv!Z0pqbLsh8<#9nnLu@sGmPh(QC zU6rAVxZDX3PX({{lcuU(aIj)F8JskS?Nse!$BlM&Vyk^NuDbk~Eu|XOxLW}G11pM$ zYg_fA+?quLF_-p?RX{^wT$9GT%moE$TIASvX1Z=X@}mXy<&ME-^x&TL1*=03hNZ34 zxwo)m9qr_s^a5a0Rw$n8@~C?L(3MV}A!3rvNBt3worCB#NoNkBbmt!hEf1;?TEt{7 zFXDxUFFqWju%v$W8~+`#CsGm>bU;Zbj%l~>PSZ)mi=C%InOjXu?sB8zqgRqAyVj}( zv-w);B}(T%{=#*<7e&7-u)Wwh&s?T@JHoy}mNbOn7lkG7Y;PIlGF<)8)mI?zayc}A z!K2#ng-y9oXE% zQh$9`m*&FGr0`rQXY(71h?>r=S^rpK46mUX{!6zbYY*l2DaqoVeR_xOUsON!F`bm~ za|aiw)V$bx*lnf6c300%W(qRXUhrSg@x87n+&Dv~@~TNT*4uo4{4{@z{qVB{Om2~c z+=YSuA+H{j9@BOb8VGRJ5m4WJ#>*hF;W zD6lP5ZVitZy5@FSfpWLL|!c!MamA@sHNnEL{ozm&R}kqlp}Wx{gnn=w0?+)^x}&TufftQq0^h+_c2fx)|+KhA;Rv22Bn z9n!|fg{m-h?uE}yrsflqO19>cyQUj8LwUTx3UEp+zwjCBf7@RoYN7WZF8mzLHtx*J zt`9S;GVn+4km^9hJL%rP;L0E>SY`jA^O-$~^IX>G5HlI(bsqY&9b3=s&GERgD6pkb zV!@qdVmifbZlTt6V(*#c&J80me9n+(1ro zXirpDhPdDy?M_aGT9rCgzy-&+yzzEJLhkptP%nd%&WIyMQ%8rbNr@V!<}>96UQJAl z!_rRHYU*E~-!%auc;aW;1}qCKwhW@8^0f47T3y=}2F z5QSu=u=jM@HMTPT)ny|p_yz9+C@ycs=5Gz-p6zjk%w#1skD20d(7r6#J|yqRf>^_o z#$FOlo*x)oa8d0Kjd6Pw&>}UHA1n1jyErT#&$05<3c{UeJ%OER_W@LiB}&KbON=?b<1R2t2* zo9z|8)$o;E%XI5-kMYY2&ns5$Svel#$_i1(b-p+;o*((Sf{{d(9q;3g}~CaPts`{zf| zx$N0pX~ZYmC1m_BuopR-ve7&xaXi_$cBNw#MQ%=d;Um*^G8EDm4%zx{Z zwyiXuU;p++JT|NKxZEKKTVue8=lZ?*?>sYN9Y;94V*8M~TeV;M3psQIR)}f|-c#8E zQs#~l{Cto5c?3`ohBb`_msoVwZQ|u=5Hs)G&GI>Kl+b*z>z6(?mObc>sU`$tPxhT< zYs9PAgT+S^Wv~mdJfK$osDvnr0MyKU2gmiTYomgD2}zTht3yNryo?egW=3OlpLHJ+$5rW6R;r z^=z)l)3}>-r(-)cM!A=9)VqN*Eg$C++&>7;PFyQ1e4VhzHzgCJ-0YJuyL=02WlmNf z^yAf)!NrdXXr)$c`Po5Je7qkGRrZM^-EZ6!n9b*|vA&oQO}TL6((Q_Hll%z-( zcFnXk-!4ZMkAi-jH8P^mOF|{VBqGBAeCbOf@y#Dy4*h~P9G)j$v)@A*J)CFc3dVk@ zMZ5@iilTgJ*ak{=jo&5aeM5iQMN6r0VvI%c4;9W_J+Jxl^^z=R4AL4h1rj84iD@q} zcjq71u8*H@e>8p2tMTd>N9w@6vC1)En6PVLzLuzZXs;!8ED{IH7BXJHEA(uzw5|ak*iHiW{(mylxHnj=&x1Unnt$q zYsjiz*s(2^eufWgh`@{Zv^U4NU=(jvk|UViL}PnCrD$u6e{-c>sFu&0_z#-ewxs9z z92dRS=uKp5nfTI<0!USe6Rd1G~pQ>Xc&YSY?%=g|(PLcXcjY@UH&8JiSxIN@7-q0xb z+rTDntP@+#B)^y}jJ|AJ)l=oeA{Tl}OhXR{D75R?jW(@&9-+{ zxmJ^;T)R0goj!ZB)ZmNnUO)LN;wN)kU0ORUE>(9X9S8IFd!B*cC|gnXnY5r)0AVqg zE__1+_|Km~AHx11PqIQ_Kmcm660jZKmhcfQk3*9!0SZ=nx^?f3N^~5=@&i`I#|Z2b zLwp2LA0QD1V@SQbCA#!20L0;FyURZ!85*brI>1X`H-QSpR$^kXkF4MWzR45{U=|oe z09k|xLh+B53lHSzxQZeomO)|Ehi8QmuOar*L_-eLffqNST9$933Ih20Tz44lv7yqM zn#LNLj?g+6ZtSfPK0o;1FFsL?PAJ3FG=`KHm!P>k;4t25uH;;Xg^2bgk;>D~89{09v zvsEKyb4&m)Jwd0NxWalw?mu`pH8q9Uv1Iep?Rrg5B`ohLl~+`tmIVPY+{p=PV5tpm z0D`$W9dH}93YUu|x;0vdSw)N(Ut@5)xmaUHtIEVt!2orEWV}6{q&KGWTc(#Hz(uC^ zcPMkID`Z07oBU`lE=r*}lSi;{j_T^zrK4cqiad5Ka9;M)GoNzUK$S>m+8`Ch4ej6~ z{&aRg06OF{o`GN$(;)=@0<>h!fLV|q8NQ3rSwOD-*`Ha66EHHCeRcP`y*`~?9<8iH z+rE<-)sGMf55nV(4l5`mgdX2fWjF!Wi(16@f(EIfD_2GM-y7YUPA&Q{ZH8ze*NQk+N27kTnU!#&(4XfcFw;jj0%dUIfggYC7MFCI>BaPU|gwyF5W4Dx?Goa?J|^CbuS@ z5qS`qG{BQ|6UcqwC~AUlZ7up-5sh)jB9lbDZ7iwE1pwJg!78@KjJ$uDZ%S)Y28-_V z5;E7U=T~%PGWivl0jjlp;%4;qdgw+Hcs zd)Lk^0zaBkkcflMI0g#sQe zw2Rz``j8$F5cvmkf1q!EzFD2c&o>3vu=vdf0FWg@m*@4y=4xbn)}@9LY}$m%H&PKqTUm`@18LG))cK5=a6S`ZVHnlN!l zxFR!$@Z8}Dg?loGx(IWI6~eU zVn|V4-SYPlNxTP}+V&*o1j$uJsg2#$tdWf#B|<>1LNq9dSF?#?$=xAd=d z4+@E|jSfOkU(w9!5Y*#j%#Tl`&P`~MhDCyeI)GRF8B<|fGH96G!4Cv!jl`Uwilo0D zad7UhO47wO)U(&sDHfL48i946hM!NfTvMwcs5h=QFo;t@bBJn(uha%{+vBxV>Gn2}3n5fPDny0B+}hBDYej&z7? z*0!%mD8?_zD<{NRGN!~UO40(yesXl%5pe)Bp*sM|35ltFci*RknxQsFzZadE`k@Xn zQ4s@VA(pDuE@4 z0CBJERO;UQ53ou)GGIOVb=gDj%pL?NmV&SEu0d8ZKuPrxq=8uegDnyB76Gb%r2;RX zde~whaKm?zr1T{yENn=qK2-px55)`^dUy;jE2V+V5K8|61RJPRlHnfuysHHK>H!Br zlL@fF0iZ|o1N@av1Qq=9Q)0C!p7ft}?4F4DGT@j(bH`7($8Es_WzcYd`VZ+PsN@OW zo9~Cgz$yZ}7t0uWNJ!Nd2<*Qb;{#VwMy6>a^5!#zTK}sSUl1@piFP4<@K`mW0{?87 z`1oLDN8q8rA!P_ia|{Bu2ck>$fPDtFwx<03!jo^fvAPH zH|*U&`vd__Nn*Tb_%rM+Gy-by(D}ifijMpC7pH*CwjH1Z4Vb}fzD$I_hpw0nVMiQs zA3`#ib`*ZZ0{(=P?)al?2~ti&VksV@XN3Ek2M{1-YT0n$`HM)bzgqq4cq4cPsCauXC7d! zI9QAf2*uirpv%k4N4xW#b_V0b*Sv(9*&$dHIn!&E!5Bx>oQRE-;A_CQc zdPs7)aJCeXz=@_Kbwf|U*4urs(_i9VHZyl>UjOFp*R2OHK4n&g}|A_s)3Kj7I>Hv>X z_8X1;FGU21Q>_B_14{Jt-RL^rv5&2S1y0uo&<2cJlMkVMWAF@Ie@UqkF<`b>CEgGK zFL{6rK7il8(*oIVKo#_-eZTMi??6chc9IVzRNxI{*)ZH46MYJv>uNu!_IIGMBp6?< zhkr}SAZ_nhT?z?yEmRHU|LoC&?+?D|mVxPNuz#3DaOXfEq7MkI8-dNK5duH^U&Bxh zfKVdXtn`q(cdb%_NB^FMr~0nAGE zkl)h34&hx*?*w2UmUs?Q6LuC1`cGSmz%dQWm{R8a9ry^2zdMP}1PVCxn9xAVROvzU zuc{|1v~n!NekdCGD>1A1krX28@UGU4-zXrFDN4!r{h?6x3ov2FCA0~IvP3>v>rb|f zk=Dn`N_qrx+zYI>w4Zbi+!zd=lZgFjPrb68NysZrNoutU%wWAa3!ZRu*m-p=>K@ct z6VZttW$`1-a?43bFm3jQZTG^$6}WMo%aqDK|E z6*|Syc{oWfCL-0lso})0tO&F}a9h_9m>K2j^ekV#Zs;iKK?JPJDURYS*WDdb9lW4g zXL6oZ@%3F?iTO+C3t1f}#`GRG-EW=eZK0P-`3}}V+bVH#y(&_kVg`M@Bp`J1^mB*HMwwQ@H#4SFsXOLm$2*(L8@nZDLpg_qpH>HsFxiYqDL2|j z$MKj9yYjon>TKHmL!H$r5naE(hOrE0!5bIc(`NeoQOC}BMZw|vN=K)BZvv*qmPPK; z2sw-{=++bpkKMKQ-Ctu6)=neumAm%Vc!I+7?h5rY4#=Nt`D6bbWVi>+Km@O@Q5& zw+vCqHlhig?Ox@??f#)gG9C<1`KN#W#eT%xE9j4a8e4(d?-(cR z2h4|3;NU21ypQ+lfltJUy4V5s(foJBg6B|Kc@v#`b%_4O`EmSFuZELA+PGM?D~lXq zaZZ-~b)RNHB1gClQ;OqeQ3Koao=jBQ8#~3~!N3LLZOJ^o7&!3X-4F8xCI&CQ{gS$qq5`+WN6{md6qs|cF~(RZq{{);5|(ksaZ&#^QTh(gx2JBx-SZFXzn$4 z_N1MEWW#AsvgNZb%t7T-EiXJ)myf15F;M^Y^KUtaBmm&RErI*D1%9d%ew7G zf6b~OdwQNI45~_=axgAWQBZzU;qb{nbaVJ9Nks=GYouC;b8bwn3>G(#&UbswA_yO_ zxBTabp|=nm$y~T7GHG#=Ok9q?3^pd0pP@c3#hN$_AK*{Yl-(K zN`(E$wHHntnJFDFGi1VQ9Oq_2XE4z}6*SwkY|876UVNL6I+?w(TnnvQ$z-PDq&X*K zVSO!)i|O>c$ykqVFu_Z{c)gP56&WMdYr3D?6TW5=!#aI4j+`|^3dfobLUy!ttgAKp z_?K=H^4qcb64IR^R9t#H8mLYk;#JpiFVCbrXc=z;ypRgWNnfV0nhuwdh<$pu$|qQ! zwO+|d1o&!2L3Ot8tW>^;WHNFOrdhP^ehmuwNKUQZQb$Zg$4I!^lX}XTSBZi{COv0$ zhO3@K=btCoT-K5+>=$~3BGj@``cn>7&RISYrz>1UTz==9PAdAjwp3sPDmqi9l-N!2 zH-;y?cP3$+fDaL{zkiN7nxo5-lLn0{?(Uu=!Z)Ak#EdsfMM10{`^8(D!|2p!jY>ItQB+McEz{FdQO`@d3PWBh0cwACd^Vt< z-d!elM$#)<8+TrP6yE4uRKlBxZXu&`8sY~8R?Y#TBHFzzQVp1Y> zDdtz6Mdfe4oW_P(Qi^qVonV=5i2Ng4zeaMiSex@bOHrH3$4+B5^%>iTZ2Qv^>%hY| z#`h-$frBnx(Cm8u9(@5=0D7ZXeNHXu@GIv$jVAT>yzGOBxybOvFztq;qD480>Bpwq z#*ht(>K@@a6)lYZC_QVOi>@?nw((oFJ%6UQscP$O^f1z}T5cM3v?^27466`jI5%=u zn^T69V`tajB~XkCKcoaYPE~cB(oO~`NGLai8W5;*zv}A@;_oTWjVDD0p?~4#QvDVCMk+>(Jm=z429^Um=GTJd7TYwM6fAB_E0VdH_w8ms91A#l-hj7%E!I z?bJ;g?Y*2E8;)1^?@uGjR52M%WP6s%r>>Tb<~Xjdr)i8{yYB;Le%Ul_nh)&ozLTbA z!Equv8I6oE?2Q}nXb34Q`z$cb3%|#D+@Tp&z7mLZfXL-!#J3jUq;nV=iRN&jVxvFN zR2?V2V)~SlXY-&$#kGA7Pxpjac@>GYIey2G#J#jNBHe-9?EUsuFczn8nI zl&ZKpQY?@Ahg2CqnOYqmm-a60mi5e3V5OldJM%J9o*I1_Sn&LLv1`a}E&(U9*1zC& z9a$+ZElC)`)9W z|2corV7u>mi*6EEja$Gj?(1hP?-p2_2QOYlQ|iQfXwH50+C6w9MY@w915@L$kJgpM zMa`{QU-WE3bhp3WiDkUc!^1so>qntN+_#F;*#X?*b=>U1Qp3YbXYp>BCpsR}O>dXS zoAJbv5>6MTv(<9SgKd(newAQx8A{4deHHN-;4qPuZ3cRk?QIr?UT{|wIR$z4>|Dr<9yI?G` zts()x;F*GhW<1+Pw)AIntBU|Ssg5AwAkuXMk@ikD_2;E@d7g2an0y&OR^-q^pD%6* zJ6lXq!FQKrTPr1@Yziozs@|OQ9CVRj%hdbCt%2jo9hFtYOJZ;uM8AMDo1HIC8@>?R zsNrat86~*0G3IeTZ^;bY7;9oJ{2>MISxD%q+4N_L)A@cp$rvtsNG|b(vaP|FucULu z!^4{MmB-9S$h=na&8EMJ)O*q~DN|D>0-v8+DJSG$baT|I-}xSOLj*78p`o}QY&2)I zJyp@!()<>$t$!sa)l5JXWw_g4VWygPoix~?t$Q{N^a)*PgAHb)#k{tvP>I~+nUl$r zSiC9Lsnf{!>`u`lPTRirKOeDxU~%!4>*N|Lj?LMGAv?CJf>_@;iy6jz4;vUydm`YI zV-HLl2Lejw*XEM`uxJur3&$c(RrZh&WJXCgpUv#4v{hTXdwpfjNVeT;yh>(wHgkzf zrW!45D_xmE(w0JoL0xX;H(Gspy3Ovq%LXHpAS@cf>1c3Gp^%V!wA-wEng6P-)Su2& zE>{|F_P2IG@-W_qwR5xYq)n@*pFXLtv{2_CZ63Vi^x!{B@a^?Kdu@?%;I_9_Dv|ST zWWeti{&>Y!)-&T!o8YV;1C}~N)N9HG<^2>WX32yk`l3tGE&Gc5QA!t2RXrIrLrrH( zQrsi*Db8`AEHFVqZUHRL5%DD4sp^Dcbv0?{5aSHCt!36^=vVze1N1BY9LAok20Rzb zFT7J=hL9qs|3N-<9f4h^Q4I;yohzw(4l;P;SPb}_u-K3!usL0!O{ZB`XkOulTPF18 z^Fv^Oy!WOI!R|LIe##%$rRTXW9@tp>fB>yV;QNXE$LsPYML-4|*~tiij%T#2`F|lb z5jwzSbE=I%K?gk{++VJsH(v(=gKq)=y(Dh5B4hk%3p}N|380u4EG(AUw#t%<>h5u`RfWN%QzyKSN_#rz5jrE@sjn;W(&ppRnvw_*s703t;SL=(8R5P`9X6-a*xUGR>A`3fJ4 z5R8I9RtCa_le{ZRpPoT(A?FR<<}0=@hW^K0H$+>k=rV-L;sPlVMs>9cv-9VL?rvvtnV}Jl65}si3 zwgqy;XfcKVc|@jwuF^B0uz(X~!QdPhP=La}RRCEP1GSs^0&TI@u4g?W(RVLY)9JFD zD~zc3%SXZf;nbaY+ks+$=u$Ez+#d^e-=bnT09~xGW7=UP{>@#WPBZ{BRYR%1Vj+jr z`-?7Ms!7b$wV_~Dn;`ziM|G>f{Aj2o0lX+u%ygJP-Fy3iwPEr-3LWrB7Y`)(CoLx4 z4-ix}nkR4WbQAzX5*|q41Lt@s6VN@zE&0TtOzz`xd_jN=OGpaCJW6VM0dze6-PDKx zxsEXJ@1jEYg++4S$$-@NfTiBuM+^vzJZKJt&l21aJY)zE0<8LONNn=wIq(KJcE(B! zmU{K4{Qn(xkwkiHMOjcHt3X;z$yn~}1Zgg>3u?ch{&05dPQs%KJZh%}NLg_N11d6w zHrt$eckAe)kETpV_LIoRAft@3bt2B-YY~~lm;cfP{_Cp+R8eCNxbA$bKM&`P9 zee>#k$k`*^_iq;>m#*Fsk)YJ`e!Q|aqXDbEaxgOtK7#cR(}DSmFY{KKs7y#Oj2oo* z_@)Q%A7TPobWr`eHR$qbQq7@%iE71+YGyRG2&NSFMD~n#cvG$?wx^}eVl9t?qj2tY zJZR&OQB|VV?PswxGUathc9QEcjA(pP{?Qv64v@al(Wm-fPcvj*ayydt*ADuUWD9%L znaq{oR9(uXzIgenUc!TN#p=i0*-QtmDd8Ug5SfA;(i}Khb5ynr(=79ngp`HWxxZ6x z*%%S)re*`5X0mS0Tl@sZ>8GX`oX#)IU%9pgw=}W5X5rQ%`xG;{9{Qdy z8`i}7<+Ehu$|aNJ)|%5$q#SANNlDM;?Uja{nTnX_KBUr7u3SRor@sqIoRJ$dgxid? z2arxJJ(Ub*{9fC`+XQ^bsIT(8|HL$k!+2i6BOie*~GznYb$L( z*x+Yz&g)>?qod;`Vs9Xj{?2EnYr^_-Nku*I)*5hxwz8>$h&< zwui0fKRfGNYjyfP8>x5187iB}S`6`z%lo-&HB@wS?SF)YU27tvm{A6#Wg8!%TK;4I zlHH+m6LkXrnxSNOd^l`bWOWu9@nSb|qtjaN%tuIp?0B8K@%DqE2Hxy5={jfK;lBLq zu*_p5&a=aDHLVM1o-^Aol+|B7{4cvrhZii986EB8<}(-IpK`<=?&!=NXW|%3VohY$ zz#5(Xy8R_-5GofX|7Ay`>38v4fp(9L@U~cN)X_Qk1ssFGx1#t0oRL9G!c`_7Y_<}= z8@=DQHDK-OdX@4V#ctHH$3#|ID|^5FFz<6|HOqs>Uf=s6WkSl>q2}ZNYwFzNnfm`Y z9+fUc5<=*PB$qIkQjHmZV$6h??dDc`Iee%PkUs}~6U)Wfx5arR zqZfaj{xnU&LIf+7o^QLmJF_fQ1C7f(r2@G<$`>Bhd}jhoHSsm+iF181y3{BzAe9zA-5Z~Yvufa=Zb3iny~`Z5Mddp_(HPihApc~huB??xK!{7Ly^<`~;6oMf zQ>|Z-q|~&J9pthjBBaXjydSr_j0a`s!koP|N<5bJ$Lf(2*28MMq>U6aP}lOWHbe*3 z=X?J=skkQ#{nfcSJ2Tl*Fl*&dY9==r3@*5jgzC-4aKNfsjEf@(1VXZYfm4PfF_bG# zaMvo2ZJlIe8_q=$g-uzRn!a~)_q#R!ZTa0!UERp$`eVcS&e6|=rdl%No6@}hb4ux{ z{72Ewg)kBBi%6|@(g*9S64dD$o9M4qIup(dbgSA`uludq7+(0;010#6IZkNVl+402 zB0wdFY)x8zQa4N~f;K2UXf(*&ZqNu0aoMo`(GrFZo9i|8j~mGh-dO1W3BhxA3mv6Y zx8V-S5QF@tzdUJ>4G_BW$iG{#&N!3adG|<1rqG)30G4X7!{!giIK%L9b^@<8?G=WP zH$WFcE#%X|?sH|>S|8NgX^xB@EZJa3+?YaITYNFWPZf|z>X_R;woL6O;_Zz;dAUqn z(d!*i!OC7<_E3y`l$x^8#Y8~<3btFcqR~Cwo@07fi zDMUwpT7_pGiV;??t~|K|s($OF#37C%eg0m9Cz3IPGiK2a$%))}%itcIz-HvY#y}VhSNv)zL*XHofO^uD65n&%{>b6yc zo!H!Ie6b6|L}TCQPIZ2;4rR2SAS~k>G=N1NCK8AdOmw2Eb&Y%bbf=&_ef>QJ()Na- zP{SX8h3J#Y310JnUZvN&X|9;ARdt`VBFwJS&iVjPz$Ac-h!3`5?`q^m*e4H>vGPdR~VAsJyCrWf9ZbB%(b5=%}Ai;D}`t9Pzs9nMlk z#{b~KvzT$x-x3~8Lcc=Phw7@fnejFp`27QQT;1>d-Cj~O?sYyE;#<$y_sIlxaKWJM zHX3oaQOcZYom68co5fq;+@4&O5)go;^_kD?M#gr3*xt!)2y-x{L{t{Sw~JmIC{*unZZ1rsny zsZ8celG#* z3#xq}68CR{wU^&obFgeXR#!HO*LXleHaGNIjd$t)49bE^S`((-e0&)7_SiDD4c;ry zE(Rk2ZUcpnKm?a4AqWxcD@kVa!V%I6vENEL{VVI%gFjQGUvieS4sWA zWJC!LmsuQ@EY$-6~QzsoFz}7 zU%bVN`x}KgpN=={?DH4Vf*SA)e@|+8nS)#BEtu3%vlPsTU0l?%n+V!rlcrdF7I-o} zcDTe+7-Bk^e2rmy4iZ46EnRdKn))5tt5+u`a|D!wGuQ*pr$1-(&0LfbLZg^Gza7#U8n;OA9(kzjF9P4$Rss(4D+adE_D95t47`Vv&)(tf zAmKbzMviV%%kx}9k3`3W)R!B?4x%-jI|qSh zcuyb{PuDq#fsnhZsJ#{B=woJ~ySv{=;p+4lQIR)9VY!O3jslc;w+(g*%d@>(1zOL# zO~8#_Bdsi4n%zF=55iZ7`x=_Gby4HIx15;?w(!s~q24=zj?1~35lvkpR(K^9!&&*2 z`>t6m~RuBJ3!CxE4YPPYXXa-G)Lb^JDkH{L-|9&pDmUaE7B z6}n}Q9vM#)e*pmb`nvWO!x_pW6lEvRvDS}9LV%eqN0%r~rZa@ESFg|4*{Gd43E|Og z^B%gn6gZ==-=n`AvKxP_!y`~YH7D~V&ZF}kK&=VR{rO#VcWMsuX8N#N1H^WW9v~E# z72AMtE`7B>7;~#UO;i!y-!6+%QT8%brgj3o+)d{{Q!PsGYk(FpFih=4(Heh1UalTK zr}2kyzz=KUWiA_fUwPu!C{=uhWN1#f%VTPnY^{Hi4c#teq{E-b+>TtJ7u~uoDI;Q2 z83gG`XY4+vfWM9gCg;y~8z1JFw^jeSZ5z#xvZ~y2@^lZ+h1WIa{1~xlIGVwG@`Gym z)Igd7Huh)~AnoD=6vrZYz14_z(uQ zI}v~r+XX|->U|JUA)UCHy|C4tQo;{Y{M6Z5VAL^<9!2Z~-(2!QH6*ERO34NcalhB8 z=GyZ7Zf{RXgVM{Md>q2tNXN-$Y7X^@k;77WTG%)Qmh`<5#{AvuUVYa#kSP`mtqg-3 z)=KbmH{@&l{JBV}_IGP}Mjn|Jh?ds4i6ERy!w^neY*AAt^@K<25%4)yOK z_}CiOs&6DH2T9K?jiA+W9FPw*&ihrwp0TCr97%ZJ=d&*?A|y-j^5E~1oWLc(X@9R? zHD4TM%wk&^MGt&HWh)#s^M7^WX3AJbRGd#bplLumV|hua!ZE^O$xOFy(P{^1@hN7@ zncvG0kqf5+4uM5DXYY}JRCGz(BWmWJAh%mWyXT!VDucUoVp}aX6c!PfX-JYLDR8=d zqA+Ab=Cu3fdPjmsG@Q%ve%&TOlpy=;UiIO_sufpyy4N)SnYG=oEMhO(V<j%vi3)nv2u*tv}qprb#^!(iK)!`!xi);AIt%~B)`9_wzi_dt}rN7 zCu`*En=;{&yses}T;i(UvsE+bcRW+9)-1paMWIgyr-O1K;a-_!0xl>qE z>Y^_!-=oeiTEbsuhNyyoiZuVl!AylFfLP7RIc4(dO~)DI5XsVGobHQ+$*4}lW5M7# z`ly#s!^m;E=c;qz`D;u;u)vWvj|~nR7uxNg$o+HuU*<{gXT5vVx!K?T9VpZMq!UnP zGi?H{ek_nb?;yvz2RE41Pfq1u%5lGV@1*jFpqAgg`vi3>oX@et`cC{}AX>af<^FAk za29(obr4}HBgGzA^FBbfyw{_mj!-i&cT9Z8jzUXs6MdjTCuewfW8Lna2Nr zZrX7Pp_iS%Ga|>Y?T(bTW73Q@(>0^JD6U!9047S}!6#sv8bH=3NiMD7#Va?3c z`Jg|P;@2@73lCmG7uL9WB9ifBg!0xmiE0I2gQaKT$>EJ`D-2?b07C9Z?-N?s$ToB zsd=0EuON>{5MeZr@5R(*={ zz(q7L`n?jD(bj?~;Z3&K`LhpLSmVQ)s_k=+4D4#uMbtln{$AD76`rM)wYK)I>6>j+ z5;Wfn?t>A0^JgD~v2G+Jn0w18r3PIwE&MBCHOXSVq)dkDNlvMrdnmv}d$AnX&O9h# z6^sQUlZM=XPTJbB#{7}R8S@nv-W?{oW)H{liR}sg&z|b!u8?7YF(1Rxw>9MeF`-qy zGgp6&Wr+8<52o2#cBm8IBwzIZZ2M_1d(UsnrKgTel*tzzrSoT|pP-K(|5YZ|uo8|k z5)ldjFPVe?w;0(ktp#R6PY2eHH_}paA|NomK`MTB@^AwYHMza`yYUo?5kS|B=nw>@1%RNzJW zPwwN)r%Vfd)HPSxD5F;9hFN*o8;D$I?0$omYvi3IL(1~-A&K$`xW;-|CO+LV<`FP~ zAu$LT}8SNCT6 z_tY@iBa~eU$Ghjx2qpdqWP3^qQF4+6ivyTh7VctRozLjEg3Af~|O9d~U z8~kZgVjf{nQO5W5lO(gBMC**?Pp71J-Osi@VQ4|YkUFZcTxne$^4i@9AB1uv3LO#H zs==cvyOj7TeSjxBW<9jO%3(t0A>Tq&|0D+r4fkD`feRl~h9@_me6S8GS^my`L>+lQ zsR2+=|3C(~5U+S=o9|%c^=r-F$>Jhc;5RH`mz-)-2QB;P=<8L=FT_t-yO&cfuV5^Q zEm)17 z<4FwVL#5DP|0Jdo@?&;sRJ=0o$Uko9vf%Gm>{X37OPcmpkz(FF<*qPgDR40`UZ<3` z`b?tM74hMQP>(R@Nt$SRc)4iN@OuA1jjFk0`OV%a$V2jTTIT>iH{1zc6uI@VNJPg^i?2!92*1lZD7|kIo}%NKYR@kS9Qs~(`X^P+PYK9` zK6=DDBj`j}qFrKt_7QdnadmB;8&uo!a;Eyup+N1L-A%(Aj_%F10wYB(#eLm-Cg96fEY(>myp4D8;rYmRh!WvkiIv;B_`RfGdNy&I?-P~cV_eeFVu-7 z;x_rtTwwD0oRTy$Sv+Arzr2)5fyG~(G@TtdRB3h`JR`hGkT z!jn;8Gj-#{rGX~-oBeLhJwCWugQAP^P=>#Q^L2KaCRa`ignvOH2K(^~8u=@!5O}!I zA%!9z1t(5{jx&s6b{ATAkp5Ph>-rZYQv6vJ?g&} z{%0N8f&1s#gWSKq|9P#D2>9^-HD8DX))$H(|7xnhMmme$&6V}r8Nj`)`H zpT_@MD^>Vq{;x5gAR!+Vydlxd2R!i7jQ@J_zkWFW`c)eYWjGpqcUXfSOi$2Cn;x_5 zKfeB-r@oTLe}$gLWI+sgj@W9*B9|){6UO*w$lVH*zh^8-NlE*9NdrZDhr@+JseY;O zlaj&~zbW_;&p7@dmV8?p(9RdB^F;zmbA{BHg40+J-a7ms37lI`CY;d=C^%Mz- zQPZM&2<$$?vkpm}!H+KCA29ntN}iUtTk7ol?6b4sL6EaPvVWY!G3MR@<)hK0i2bN7` zD*;yuHk)GT=wY@Qx(S>f8LHJkwl^|k+eD{n&~J3P>oT)4u)m|9SRS0%mwtMr)x|t% z%#=uS@ozgw0SWUpCo}cv`PcTjin!Hd@4Ax<+adL0*0kNVDWq<2nscgkw~Mltis8pj*a|R z`xkfcOT`Jn4@*8i#gVH+BJ6&yRQ__;(5+H^yJ?2381X*vC$C02?dVOkCqg+q!qS@? z7-bs|GSP3WXreAEWOfmerM0v3{nOw@wfPYVs2C<>-%Q9T^pBNG*^k37z2ZVJ)8(OG z=gkP;ko8}Vhf)|td*>5<4!C!&^Lxno(1K}A`20GhT$6cRV^l5hp#+`LWcXjDv;FU@ z-HBfk%{ahtV<4r<#+z(b8BxL&z950egvJ3CVkK^OA%Ht1Hq%1tzrUo><5`#{XX~Ti zo{!g7i&m9PE!sS$_+Tva-&}d1c!UaRTVIkN>h!DjKH2UtjA7_>l0|)UgY<$ z*oEbaUo;4IH2%aXjC2Vsh`+ST--q3fZw!~P`67imPUMotDi#`m_5C(EaKAy(pR)p_876-oz{W3Y9fdr;wa3`jYX;B-W zGQdq|YUYVqjjlc5BEZAaR)z8w*b+k238s3g-n=#8a~-jiWH-yA93`Z>Do|Ry$YDiD z8jlaAv~`c@V`}-_>|k~6dg$8ouIcdE|Tp-HAU9~al?ud{s`Q``aD(f-?oY3dV-r~9@K7FdWi=>~7#g0(FE$Ty@XWjZ3;e5a3*x@VyduE5E^Thf6F~cna*5=> zci5$xsHRIi@4~sc$ft!Ee906mu;X}Tw$#PWNWgwu(f%9W6Hc@PSZ%BZ@~{@@0Eap^2xer~#h=V9xpA)(}JAp$CU{bY|bw z(uwqTMmZIW2wbETqrp;)AW;3U@%IHK+Y1+e+2qi*!qSK@D3ab_8O{*16vCrTmwSB~ z8ATOvV#N?&*X26mrZ_DSR{>k?{{C?^YWkS;nVF$D%#7wAhp^P2M}5E(xV~q(j_f1g zhMdMv#hI@d_@gO%=VMkTCwtpraDOUqYjBWK9-9vW4s)L8b3Kxgs^MN^B|8QnekERD zPEXGtP$2C6l6D(tU>WL$Q8q((45=T!lM!lx4SNrMadMmX0N~bec8Up)2ARJQzDfK! zX#fp?^Cl)i7bbTPG2Nq7J7(u2|KXd|&u)rdskN^t^OBJ{JWA`=S0fVeIbOY=D^Vh$QYaJj zl_tH>U^5aQk6NjPtk~C(6*fT)h?d@#VcN2B+CGaDER@WT1koYf!J*D?AqCQCH&_Oe zEw8QFyiw0JSS!uI2C8@XVZkcZ_x8a+_0|vxKKs1yLn%ayCf6y#h!kjA$X3pjmPuM#az=y8#7+>I~l>t6Xku|Z*)-#6iLJY zeqb;04-#DxIi*Nf;kp~-X6C?Diw^m6MT?nA5%MUj6k}pD?i_gfV$@B)Xxj^?xcL2w zFk|JI?o$NbRd>AgK|8~;2}v}Rf3A2eNCCh3y?Y%tW|Q7Rw>l#3nfSF3=tYsBg>r4z zooYrgOg+k^36OCDm$3+M zadVLwBfueXqQ9cD6DiGMj^_b4gNCpe4U%?WyPiJkfr|NoB9S<|TF!rd@VM_kouugM zo^jX-x-M>!5@G8ZHhYNK|l{1v|)zsv8Bf6an z)D*g0AZ|cjayx>{*NqE(aew3g_`ZXWNeG2&t5xE%t8k)=A#d6?_6Cs>5-qgN4P?eBSAMPyj8UBKbXlt@F zjEH;ZeQ7@dZ3uomiB=+ay_GT+hs|WShKy>`?S#K~YRVvM2ID0Xs)XG9Ye27>dGn+l zN{!ndVsg#I+GB8-#GRu}T$}%|_^;vz^>Gei_TStt_*Hvr(@P_++vIpbNCZg!k+x6E zRt1#fPv?7&#Wtc-&A`x@46ozkQuG+1o|EJ+@`sKwkhAE@9DXnvG|wdJjjm9v1A{Ew z9LY^COd7q_Yclb5)|6<4bkdY&mIX5GDq_YQJ5EX1w7|GLEIO^AA(`hgIT@a%>ZS3@ z$KOuHQ*UXSK5e({_k{WtwihsSSmd=gFmssuph{=d&|l=7|#GnVh#Etp2lKz=E@Ly1?o z$FSfZff5ggGP5#@V0FiD)KWjN|C2LsP)SVKI6&Tw`tY77SYPnl&Rbg;Po7q zVtrQA#rs6QgRebvi_|$&=Y4wUFd;I~t7o0HbLJTcb`QfdAD3O6NvAZ+pK5kCC(W#KYz) z{e^#FDARHG2KXImR7JzW1sNDwhI?M1J{x0zzgnw+UfxfsmD&8PD~C)Z@Sw=#JG54~ zx!Mso9S3;tDT;Djvb^4dZt*OvT*mX|T)oM}Igy{X-#l-tM78K9blMl`)wu*2zAV{p zenYaIoAgg`qSdc3q+Q}sPd&tQ$A5j|Mi4mC{JZbKUardJva{N+HTK8&U8FhyjFWp2 zDJoJqCad*s-JjD&t@2ovbf;QQWZ7Lu5gTx1TsOI-I}oF5n_;BicL>q4FWY>i%mryN z0`s<+j&8twogT60NN5PvD<)`yf|3wz5p^UVxUJj#oLA*5?smaz-M6@LZ?mMyWkI?h zC|x98h#Yqdk@gWDD&5T$q4_(#n4OjV;*zq^n$uy+cl!#)0KmAhu_|@L#q?eC)a&}j zHADmv@N@aMy`1XhhJUbf-Dl9D)2~Iu{3uTp^nD2MAIOvouQ*cPP>g86tDiJh>pTU1 zMnZm%n=5EZ^v!dChBUB*QR8o+4hT~e>L<}G zK&N$7kh1a^>CQbh9gzl6LOu( zE&|$A8LUJ5?fGELn1R9n{q2!RuU%x<+RScxC@y;MG#dYe$JeXN`Jl>fqs@Dn2}Y$R zZt9f7F4v$%vBK@byx!u7M*sB^@KJR(Pfg18A~FoTSgQzuWzS*mGaHUS7mIpt_Iq1> zxaj*(uJJ zul5u;AImX;+c*cxy4ls=$a`2<4~(`xA|mNlc(+fLNhES)b}dN|&EqbXt`_OdW$Zy> zGO8cI1o!o$J0FZVcr*bQZ1* zA)E;KSt6Cbzf5=+T3p{e)^z1?F_gl|Pzw|tq);i1ya-T*tQRE;_g};#IJD4Uz}qG< z%Oyt|U73RW`9tSQDX-(ip)ee>*7EJC(cE`JDYV_=-S?dBou8PjzOJ;0p8c)=8{_x* zE;{vYLX222uT*;-SaHB4f?5v=0e50GytGA|OmEOMA0SHAbiSO#sZd3Ua5`+tvaj?l zD43JV1pHWeT)$8i1GJTGr00bcGAHrM#XwW@1{FuISqJNO*RO?tn)#$Yr8c`3U2j@D z%dxTwz4cqnK(q)Vafg;GY@iq-H$oZH)uZ7)A*9lNY5XX&@BEj$W2;N`+PcpNIoGa~ zr0JQC!xYS<3vblg0$eO(qTJtIV%>yF3~BbLk!fcZj3gV=_(rMt4qpuq5=w{5 z>o?Z3@ko`?AT`!T|Q166{<@Gs_-j|3NI$X>Ffe>>v z0j*hcL4Y=@b{NYGc`vMTgk;Mb1(fv#+2IfW~(+t$u9+`OA~5acIT74rho8Us;WUK&XciJdo?i2pYdI+?Vl-ZJiF}TyTDb_1_@K`cWG1<{ zJ8<(QmLP#8N3C}E!S9V2ox(pI@G*nKs?OmcP#~LeAeUv`uR3zk>CNeS!E+QR=!S@W z^>V64je3wYSKNGe9^uIh)yT$9ypj~fX zNg{e0gLC^bn(_;Yh-vkDr9Q#^qSi#BvL}eZdNKI&qRC9=SK87u2JJMBR+C6bwyqw* z*+MzDqv4eQ`}OS|AGd$kd|?=cg$=C)$NuY1JTK5}piFy0+kA}!|G^&5)(8&b@5Odna^cl91O;x09*7O*D&u8BqGV0mZ99_OnYX&-MUl2R-?sNxAkzQtPe^xoU9a&-BnWss zUYWz{T~R4C?1GpJjU!x!IK`?I++g67Ts+DdPsnYY(``YoeQaC((_)0tZc0y{5kzHE z5ge%ex;$h?G>F3Rl5rR2$>pMw6l<4BpUpor^e8jsS3qJ6-1LtgO=Ar3|6s4xEB`y( zGWf9j8_xq#l-%CPsP`LsC-Q8YSW^7-Gzcm0_aDXKoq$CIOfkk&tqM9Nd+kn3P^g)< z%|-`vc4DPA%h28o#&Smn8hKn3omL0->)1yw%v2gnb4WT$wLZZ2>iEQ+D0s`nqrdaUqu%>t z29w}r@*U*QOwv2`8C^IWmO$M*NnL*L4x4^lZm0O@73%tB3z@YlhXev{hcii72K@?O z*ZuFPX0wy^v^Z}5!zT}~H=dQTKVmv+;C#@giC`S`Ys_TfJC^4R^w z0QqP|i+P&jKg8Wmxo!7@wKTuze|TLyyMZo)?z7sBfU8=GXaxw1>NUKY#(49gMN(n} zyRH|fWQ^t~+p2YcObBnMo71WV9;LQ5;&}EqZoTyrGSk({f;J7hZjR-GYdcLwq$dH~ zhfPcvepy3otghQFHDnB)4a8RyTA&e&kTl^6{ zBOyfW%3>!DYw*Mjv2;)~J`Smn%iP`Bl^u;=Su?f6Gis^aT~HieM&8aUhm#TfwlfGS z0cw#4Q0?rwH^?>Cx052*+rHN2Ae5sI>{C~`x!iyGyEiDAy3k(~DC?uI3|KwlY#Rc- z$O+~lnYL!byR3ZI4P9XyuWYS9^?iFG@@nwYsrT;QgANLPt1R1(B)qt7{FNaZl7AY5 z_-t#r{5Q@PYFF1T z808K3xID9Fx0CaP;Pg%9(W562Vsmq|&1Khdr#GZ6cfNGZte*Zv6FgM9&OglwMJ%gxB-hYTFS6FdhM-mq7)DgPs^7ud8<8hj8jyA4ovz4~n?%aike^1fw zd<9xfWG(7-x!v}c-sZcy?uGEgkt)F^>%}nB)*$Ayerkh6K?Qw(CK#>TK9Re?*#ZhT%U3NO!OBr%utR^ z_g&b{n81a@IW#Gr%y9z*f2mAiI0)}bTqq}a`@PsiSzKqm;Z~yc!}!2|3U{m8Lc)c0 zuH-vL;_P(uRbL`n5R;yaS5RAml~UY|@AFNPaPHO^FXluVnZr96#@L5B*1`Riuj9ED zg+Q9bOJ~O`c|T=ZQG&;?W->5psZ0F1T%AF$OfhzSrT%Er&IXrOZy^9ksON{DF;@D6 z#O6AZh5kX@1vP+(3i;+h=HZW66sM)3LB2?jbPAJU2>?)AWcJKqx9wD6KtyP2ALQ#p z-j{ER*l7KxUW};x_t@2L409v`RW!fUI1I65>-8wFSFOBBzoFzufjGhYqadq}j>k6O z5eUF^bNkE_IA@C&UhYQJ{(xtXFjwsF%@rS|GWz>IJ69$4veqPg#Rt5FQWM|oJ*oWk@EwXpb2%hViHRtT zE!jr)G_e9D-WDf!On%p0d=*zKOGmFU3;-?!NC(jrp`W`9m&NS#W{KkfUDyrx)Y!-D zRGBsIl5}Ma-tVbDRI1a(nCFbOOnj`~S=ZNm)qx`#=ep%jCIr`>hJ*Jl`(K@Ak$8@sWhem}av+Z&Xjar$9r>9i8 z5JZ@0D7;puSL1#@D){7w`)&Wqn3*)D4z~ke#ZQ>9f?|gEwrbwN=$fej+~h4LlMorD zl_MyWxNlm88uL5N6`Bx1V37_#MO^A2CDtFcvyXxukiJnz5$mF{QoeJe4c4u$R_HJn zKRJjE%H}j1ja|yyWi{H*SZ*Bp56Y>P|1|htEg;9B%%gT;%-pQ87Sme{aG>e)$Skvq ziHd5Bo0MDE(2&mVI^I7c3LD`+0M!YPfDj}qvaqWI=H-57X=MNKIJ+RH<8HTQ_oV_D zUmGsfwPH54+GuhXmnX1fyIgjiXHUQS_#?E~1teIM?RYbkKm1erm%=`4Lq~e6nd}^M z+(8Q|$6W4nGVh0VwT2-p?=7zy+-9kAjh0)KFA-RdLT9$?$8GvnUE`Py3_Gm~bH+>g z)U-8gGjf|0F)nL`Lgi_%E4C@Ua*m|OXXf+xRC)~fk@8~*Jj;5iLihR6xghjzweHYC z^g3u)$NeIW^s_`8CcP8*0B504V$i;tH-Re@*o%gOa^klGOQTJz+|o^iF~(M9V53OH zDFb(Vl`c4{*62JC>T2_J`h~juNw9es;8vig6YPnRN52z;cs?`N>o5wwG1m0byL6fc7 z))JWPv6JM+O>V%{IML|w6gyQ+#vuI0{U;+BZM1)T+8<%JTjdjQja-6WGNr&{pDj_1 zI-PIr^7S^Agm$~RTCROwD3dz8ePQR*7G-IYY_yhKD)^1(pjre=g;tdo zU0HFH%JB9uNpSb}bgq>N@H2hp3@H;??Tk91W*WdPgVW=W%MEmiAqaNs z^W!Z+Qm&SZIIOL71_EuD>)_# zuQ<2lX%UmC;JEc?P*k1_R%))K?zIZePGX7X(%l5J*lo-m96ojjqRQ0Dy`nf(9W_f7 z^9N&0wk$K;;AFEh7OW>a%(BE~-|;w{7H{J6eDcB_INs}}>_8pdM)bH#y`#B&-Z7Nm z#PFdE$Iu^BbyHtGJbX=smw-j_)6cmtkH4{ z02pY^IYS2m;FZ7S3bLYOVt5+uy6ji7=~6K}A!9y|t3Q=7_p3$qYt7E=%p8N&;D2L= z#+>lc_~~kOBrUOn%bV_}%wyWzBHvJbOiV=Cq#Oh%Gsr*>2xFtE44#kg1u|*X08fzq zY#X#>R}3Dvbx5tqeZm`5gQ61~rQ>TKCHEC#K-2KD5X_JRM0mxv4tC zQv5to_DqE}!Lv7TREK47`2f5AMpDz8kycOiEK8Sq;k*Ghag%w(&K_Typ*ta#Mnky- zotK|tlfFIUn9V~i?*U$^BjA0X2p~qUq@zdndiw+@z6~J~uztG-ats-VjHS_sT(0&5 zQ*4@@u#vIXOOI+klleZ%!B?joPT(H{W-%e3u`J%SLZyVmw|W%-8P&Qg(ZFXpPXenb zpyxQEo|zJU4=N1Wf9w1LR2V8&jlQx+#rWE<0Q(sNR1(jQ^^4Up_?(qIZ(b=z_xp+I zVktU%xOxQ7m|FKr$O`7iyCw6{7+G23%liuYu^!2rDf`dv$G)#6hR~(ZiT^26JGM0a zv!(=VZrwQgF_)$&D#QCiS!PLoM@E45{cv{{xGlU-^?}3Zq0(&c;Z`@A)4r82YNpfd zX3+LisxNey8T0AQecyzlemIwZ(w@5&zjK$XNYqtT6@Mpky>y=Z#G*8JyiU2<{@eyZmPx~vO*b?|r?(jI7wil=$gmhQPZ9(q1H=e5?G3L^R_eKe$R?tGGNaBoz0U50 zK_L-`Ryq%K@M_%rt?Bn_vt3Q5aL@-dJ1n^!fBD>`_E{YH)FD9wNStgHtJ4j}%-qTO8pH0KL`BAk+U{2q8ajKff4Uf7~>_2KCoVPR#g7UOY6 z{ciO^QZ{CTR@6O(i#+l1uF@+4C9eD@N2JFT`^iLsMzkLn7>`u%JB04JOjH(7Csmwv ziGHVathwLp#MK`j+}f`3%NIe#rK{G))7rSi7Kjo9k za&k68;ILpZ>7WTfVIH3oIGW0nP|2i|BBETdWXtn;y^=an(NhM_I_cqXdDvRf^TsPHKv5MDg8DzFV3= zo6mo2H0oO?j+ojLXba;BcDlST7Mbv`uSx;kQngFRm%$zVV2i2tLXt8EB6S9dMRBIs zRPvs=PJG6$TST-h_}*TZlBV|X>-3zcr-{>^dpLzt9srsCa~gj!gKd6BY|`kLl!NC- z+0yS{a!QG0(Hk(`XM)~I-r7jnBcJ%8V)Z+GzNG-0Y_;sBIfhmXMLaR-MoCCmWmZZMh{eN5 znXkd77YntmL1(1)FO6mK%K9o?LPZ5>fU%tE-GOm`vpe^~~5O5(Bz9h^egjxmWbh_F~Tw zcst2pZGJcxE)Pghx_-F_67pg1o<)g{bai;%UOio-BH&4fIY}EROnpMAY1XsgzI$v% zcgT@#w{5N-u3xxK(}^vYsyU}p>5KNr(LY83Caq~=QC)Pv7ppmTSJR)+AJ6v7o6lXm zg!N!{c3wOqnu_y{?KG(i4Hgz;IwYa>m6j{5f3iE_09Q1VAsyrS`6)8?m`_~i*B1KW z3xE%|N&Bkv<#%3%OI;ZEvLn-h^pv2alx7e{+|}{`?g}?|4b`PWhl!r@#HMS0J4nR) zanqg_Xt~$N?-reVpyW_v!zTtZJ=jmFKuBy8S9b5DaXFgweK=oveZB=?Iv_V(US4uL zlatLAYpgw$Mlmxfj%ToWOzx8;V$@9OmHfJr%V_`Lzdy`*q>XbgG3+IUxW%APR)`el zc6t5sO$>}thwKJKS6+0EM?jB`5JgLOgX^GW46=G13MVS6hb zgg3FJ{j#)S#)A0qN33F*e4bmrLZlg1fvlxvJa+-p`ip$-HU6CE7;};_6SV%_KC+NF z_-yJIdHw7n~7%bsx=fmfIPj;n= zt?@?6ZMftk7D`UQG&jE@c6xc~dFJZ7Tx~#?W8!oDjh@SVwdXBIYX*3NI*r}gqkSdd z#>=8}r2O15*YptxgGlmfaqC=JMWp*lk7?<&f|$FHlM-f`8+?b>Vh5nr+bFZ1-Ic}_ zc&7ko6TDAY5q(YRr%cHDa9g^|%B&Wc!-xB02teCeIpZs|X)nF*S{ug0XW%|Zyf#~>YkhCE(S=rhUC^gRc`117&jE|+a1faUgTs3G z@aH;^2n|)gB;nIZwOT z@poc{Lgu%t!bDzNa;aG?{%0a7TyE;;uxV(gxu5X~87*~qrt*1O54}|Gp9!vA>k07>Mv|Z+w8C|~y}jMt-Bs@l zm0lWyt^JcH@)(yYz2m$Qb5`B=$9a)*F-P-?od;$CKU1{mO{L--bh>K-iw<9NySrpe z?EbXVkcI`wY&v{zcR-xnjd$4%EP5o6FvyLBGA0@R(jeoPE4+IOtu2q* zFb&tC%h0Fj1X(Of8vgRZrz_qKQKo-NTHc@{ zGB{Bxh+$?5f1k`9mfTsYuZ(G&zdIg*D^1L1;o}qW(ztR!3@LhwJjhmT^#t|UOf{GI zge|y~Ho32jo}dK-a*iJdJ~E#chRlAXMDbk!B;+YL{@x8DNcm7=-pUD@7H5>k8*+QU z*KuHbnivTB}L3#64ux_N`TW`=zu$>vIg<~I26>L|EKRP&@(l6MPAgYe@3+RQxKqKKC zGids0HTFB~amz2DEanby=J(JIfi%DHPIwfXE#NwZw9|H^bNH`1`xW5gut&lrS3#T|*+EMvnl` z*KHrpZ$Cg=gA9852A!*JC(6_s8I_JZ@@Gr5a&nKcgfXSp__5%&fnA<8FR zwm3YQW)rKvYfV08WBR(CUPHgWYH&C(Xm@%oO=KZVgf#b(bn_?>R!hXyaFm?!f*v)_ zmuo?>1cU18mM=_VScCto1yDm0oHaR-!KdW0Y;!`PbX}ZW(V8pG^cJPl9bcyTZTLP2 zsOz9JRcR|(U32>Y$*c46$bzt=!WE&!nflf#5%6%aRLZ7^-dWlTmJ)3;9pvNPzKSE> zuPz&`0C)CJ(S4yvKy4;Vuy~mC%hmkcBi^k<-b-4@cXM%q~E>|In9!n6!eN>GlgraQanfUn9~3JY7&p| z4;izNr%y53{s-{{%=UP{Cv7tB_1%7Bk>jqj?P$G%JeK|?2z!~U{rTP+VhD4DKKNo=`;MPZNXO~7L9b+GFHnd6vz zvPWtFhm3hIOUBe)(ciJgQW%VADM`{QSACwIR>qd>bKE`@V8aa<^lNvvXXZYMLreKX z$WrGE6%Xy`i{&;tsv;tySra5t$}*)M1dAt~@4w-uL#QuMo%I zgjdP|`P#}x`Ycc_2hJSkro-p{@VPv0lc^onAAPDkrN%kK^IgQV5_B4@NBq&#KH z0_EHjf#9RvdoRCO<7x@Wma2p9>|6um>kD+P$+TiqDwAvsEe$dH!i3r+KT0Py~rj=ELi^ID#aBlSoO;%R~yD@f_aq4FWk|B>eB6@P{L%xgr3X zcB8}d^-G#jA0&Zb)jgh;COp9LtBCfE&>}|`J6zO{$7}aXwp<>Jub*t3;Fxw-IJug9 zi>XCizNeur*JvYGgb0H%eD0t8f{IA6cq(URGcR3BzokvWb_^U|6zfVP;(W^_xqN#m zm;ALF_CX8o>`!v%F7$@c-_DTB zO~>nZLJf`jT3_*WCa@%_|_Lo}37;#qL9_xMcyv{o|Ron*4^VvduS8N(c z$VjRwg959;EgR$q+C`lrkM${oT1b8iKJI& z{zTH1#ycf^zw_#yx`~i8v9ExSQ>ET#;hRN9Q~5(I9#A=4G)3znHkuCbvTyo@*UK~SD*HJ(!LNug*CUoSM9E(fwrL94p{)|)!PS< z5V%L|f=@gphxT!VLxLT5F}wY;6~vZe&$zT^Vu0`NAuvo5K4>3{XZP+z9gp~2ZH6Pb z%b$=+e5)9_b0~W`tn>Wvu;X}5*VPjg_yYk;e$1NCcV>J_%d_V5OF>)ZB>}SPt&Xr? zpV-OCEc1(W`3>-3DDE7IO1VNt-TsH{5TU3><(A*sWv0C7F3nKX^5Vc zx>a>LAi1ioUFrw_M1Q|#kuq@Er35$~Vb>0y-Dr5w8l{nsf%3&>YgH{jz9106?fA1S zBoUi8U?gp~9^Qp9nj*poecn^>mqEX^XXp`5JeS$Zqvy3ZOkp}XJ6$k)j1;xW=qz_g zL7%)+IQUJObwZ=cYD2jd;3Y?(T`w}X8oTnxA21wKk5!`E?sjJGYBW*Kd)UkpuAiv% zAb7fHuQ8BhvQNY0~K=wJ$%@vDp-^uCZR;;uWDiGU$l z>Uz;!*4V=yUI8LPeg?S*;Ze3qU55HvHpIB_T`qa;2=HVJJ}R0oTt!|Dd0}Kc7GsJ> z!J@kNtD2dH-*07=9lbW5&(y@EC!hnAA^RZS%;4b0ADDeHt<#-C*df_PM+F zo9cce6kd4ryc0OMKX(b%C3wTp7M?aHZ%nTgDmMkgeY z7^bIVr@7K>mU;FS-4=f`kYo1x!w^j9_0Amh+H0z0)J_z(iCcVD5*KJR=uVD*>9?u3 zn;)P8Fj59H*u1v?F5IRt15L#>k(xR1)F*9byD9v;_?%nuGp5Q?XkJ(NcB=7&J519X zwDx$ESuhFVTv+ihx84O$+AFr57z}X3a#lG$Ci0ON2c2|3p|GHrmXVg@7%b{!|Aj=r zxk+w8ZSOkw#WZt~xwUbf@5V0ooOn=rYX&tWct%kB;`<8SgKyACgw@x6@nCi zS%1%9{OkG_Vp%7*K(V*IA$I2gueY0GAe%2jdS>|mJJR2%@Yk0KX-8i>6cmv*0}?-> zle1I4e-DwwNP<&VkMFTevEj>u|fjqz~TPjF_@)fQmnZiaLF+=fSvsFp0Zz1IV!Du=6Ct@B!KUB0txKxcM3X_4!u6Me?o72#a5Q*`8?H%xmp5oyR32-l#Jq)!L@J+a7pmZz82)y&+1mX~h+o~Uk@kI^ zIj}8Y|B+G>zoCBL=y)y+L-N0W$(qQG(K2)uk9}Qm8Nk`1akn3*&5**}DZq3B^SjTl z)2ub%7mFNJn7ha3ZXviGf~ai<(Oqv0P-}BTe9(b$*R2_s^ieTZY`GbJ(o$ho+w4Fn zziP6%>+)sIXmw7TrO3SFj)9m*HwxOJs-p*WGeK?gge&boM_Q;6sJEfUzRJlaN9fo3 z9W7%!Dyqx@&$G|%4fL3)>eCXG6Z#g{g-BG&*%Oq?O1`_ACi6&Bq)QhGn+As;`&}At+#$WEpAAlHt2yAJ`W{V`#COe^|N`cluJ7Np*Q`i z!YU}&PYw{B`pgzgnCM9MUWnAEAgf+`bX7I(*>W}xi7Iw_Wng)5H_hPNnYFgl>ORIV zdn@x~_9&~W3QW&B9ltr`P{W_XL;Dj#N@L9^Vd>zTU$UMVYpD(nu-+@!~ z8!e=`rG4Q*eK#IZz@d*2?oyefWHvsu{G(?M4u(I}x{Mp;scjo(5!mvnUkoANndoCt zst}nL`TZx@CnPq+QB1GO+;{}0C^V^*#K6pnrQw)DQa4dG^ZOjZ0KcFks-|g!PuHvt~|>nv6%OE66~QH zhIoAWd`vpdBXh_3Gz3TTkI?6b5D><6q!$eB<3YC5z>iYfQ0PlvPRdg#0xbIXr)}Y; zm3ldwrBn-<3k53Ue>6~V>s|Dp(EYWUGTi6mPB6=6&oJ8aqscmg{WMWp*3jCvzu4%B zPWyAQKjrKN=E}PlRjc?_~Rp1&gYqzAJRX-H9YlT zV-gy{C7(_#wK$)S0zLhfjdCfr+NVHzMSuh~xtNNC_%3xj#{`J~bm|JML0i%t{$W*> zn@rm3C)@byWNw~qJlvDndv>fq{qwSbO1>Sh<7b}gdJ?#mk@#GY-gAw!=viNsJ1g6n zfx0gyPa59@&K2vz#QEB;sZM!lMIvlwO~MJcLo?U!+AJ2TsVJxHI`uRW%>+spEd5`h|Y>Fr&`OlT~z#ms>H>YLzp-h|oBmsEwl?LH@5K zJR|u_AtggA&tU_$PB-rC-PzRiO?)E@JJkz`Vg|7m1$8;fW-y&Z6DF$0O?VOfA1pBJ zqRf1G}`DEN$ZXRx4;KyHPS>#;*?A8TwQTI^}6kUKTQ@n#;N_U7I0@Mewc{qo#b>r zMI&BpuKieIVS7{Qz{}2hi0t;lc($k(GtHc`l(lQXQQ9Gp84LYt4ThZU-0CCicV<`Q ztT~E~Ts1SRIsxO_NNhlX`4;5#d7uAs@t%tAMfdDgN^Q8@n;oivIy(L!mmIdQzwSCfV{!n-Hrf2|)QrA^iN zdKCGNse!dh4Bul_$3NR(6_`W0zz8;-4IA<&KWAm2to6)-Q?v>5M(tmS1O_FlqC%1M z>)3Q8KHW`oe2X%*XfEb8GtR0YevGp{F(~5&YMQMr9ncvySoIWQCjKl4(aah1_9|7>F#%{ z$8&tXzxO}=u=l#xUTbF7teI=BDb*J)S0o$F5>3WozKJ3Us`&bN6^MC?@T>Mb%i~tr z>4fwMU*qYa-5&IayT}`6B1Gz4^9t!GyrToviav}zF)?5E(|hGk%XsCn1KT#=?Ab=1 zx$F3)6+HtlpYlt;4{G*vj>`BCHG*KVTfFENlyWJsxQ=EZaK&_~!W|B_Z+odWdY7r) zgw+jOEcC{<`b?ii+dg_|t{>#okgG*keG0`2WHO^mSXjb;(48ri@jizVt&-h0vq+c~ zVoEUjDhvIojviGJpT@Z8xsJfV^iBctA_$Ba99r-y9V+*QNtq^VkiYMJyr3_!GTriG zC*l{!r!J^(XoNl$wH5)*5_)6RdX303PH!I2ub;NA>8Z0SH_=b-wh(^AW1Bh<>?Oid zzJAYc^U1xCl?|=KsZg7Vi-qN;d(2r1uEd3-I^BNMq1mXMn%`0Id)mG5^S5j0?It$% z`B5|;yYMj&7wt%T3@7bmLpO)u<;M0ZlB9H(P4kqb)-qlWb|*)cK2ltG2vaJbn)wRY zL|g*l1)uF~2=ZtPSX^A16V#j2LlNOYnb_$0LNdEak(F{H4NY|O6+*YbQn3$u4|t0t zf>u5|usny>9Qc>bC>j3#q5w*NoG`iXE*b0u{0ykk^GJuesvy`8g?*O-X0d3;mK{1G z`hN3dSQDD3Sdj)15iypwB`ZuMOUSKI12N8{VNxE0GE)T~m<#?|Z1g0Xjep=k(j@GF z2?!#Hu%I>T(~3{Vz@z#8ASJ-W zk(5aj{=d`|r~vVVA6)KySxmlM#Wi7B%K!6cpn6bb8r=mj(Er2R@#{Z=0q=ht_Je^Q zUkY8zOT#{dOF~8n|DWfCJjqFiKQDg@hc$)-UtpY`rihx8{y)!jjFSo-^FQHXS|E}~ zx4}+W{&9fkhBtZsDKIhx#nxB_SAE+1jpZ}hwP&-_7{_OF6h}tjm4=H9y^EAMv z`u#3&S|fnxT1@-%j=ui=t4T>=UaO`eweROr)p@s#5+CZz>??sLQObgVt$ph z{=+(=1nyiU1Q2leU<}yiOT~PT&Z9~8|L|S_<9)s=4JI@+G;)P(VC8fZgV!z0wz5;Q6>gW5-6mSrSinvVSKH3@x-nCDi;37+F^4&v~+W`3#yB zP)LlC|9LDX z+miw1)00c=`&H`=sG|6vUHmnRcO<~utNjt4zgJ3V5j9ieFHy;qdCy+PgjD>CEC%?+ z0d7ch>ObRyApA(CYC7q5(7IM1vw5DCoTlha0JP2?UYAky2w3t};tSXlJ`(J_D-`ux zNJ$^~$Ol|ZVF^eO^o!JS0kW7U110Wmhjg>|lJqvfzQls{{{9)EyO$?v$!gtS&q<#& z-UpwK480#V>e}X7{~_1#E_<6}=PcRYBOJK#j%@qmIq*a@5N0pnIj|7CG^54hgapDNG zN>DY??mH@X<7sT*`)`QBXMXKOrX8g5YGo!VR`Zocj{b=BV9`vAbhm!E(NxL3Ki}*e znMcyv?)rx!BMGr$JOuUAbxTuHBPD#-QArHUAZ!qMrW<5ej*4E_tYc8u+|W$d%!E{t z;(!TZ|NgRwg|OI~7o0s|NHzX$UE_zTz9C4nX1xYpKIO~SO(ntKYJmzn;S2mrIYj6q zM_IC2MF6{0lSp$HZoh@QL6OLyLpBUKHgP15Sm~Yt4H_hhC?7L))>@GJ17=mNDg2Rm zGz)YN0onvLc;~v3Fd9C+69onZgtsP6SrF`l2srmrbs_S>gilOm6X9_kAVdZdFC^u{n+LRO4!tzQs#3>9@ZaTqX9lh z^MX^jT-oV6NmlI*(Hi(E3`5liKT#@ULnTs@VchQ%HGtbxc7sMO8b%ztW#m*B-9U(w zzwy}R@hk_zHxzQhm<2Qli!NNVskgq+;J z2ANWv)FhcxtQP@~9=S>lSH=CF6=rZKu~7L`wBV^v65v(QY8rDh*8vf|8BH7AVi^jwZ`bl(D&^E&!@atum-=C zHMBQEpnbNknXh0`P_+`DopEdbtT3SHq-C(c0tc5Q;d`j2!;#0YhmeW|d4|)Ngp-90 zi*CS|q1G?rhH9np>R!x$)V&Cr5Lf6EFTO>+lR$qVF7cQla1}Jorrb?HyDyV?XCjRoS^_;LDj~2__v2Ro4 zxLzFL4@(q4OF-clYoUoXo{MvkC7MJktt8X{3g$K9%Pq>(GUAs#0dk3+uqLG;rJ2z;yQL(u zT6E^X1Sr2uG*e`H!{i+x-m({8a5dC%1*O6Kv8^!( z#IvF$CnYU0azuT8>-w*ag3En7O?82%Nuva-VjX0~=i5Hrz$m}TnLym$Yw=@eYO^jD zufFj|AfrjY9TS&e%Fb_^{$6~X+Q$3pg-VbjMYZu^VHjt?&(rUR#?a2VZn+S0)<_10uNne3)N6*&w}^gd?$E3Z7javx zi*NJ+iX{M0SI)FzZEan{uaF^NV{OflFkAu@12}9-3<986gviZr%gYV`;22|uS+}LI zY_-7w;*!m5Ouysma7jx`3n1r_kBUdsy#wo}O^C#Iwj z;Nt3+C$X6YhlI$;(WG$NeAK9+k}GRQ>@gpmnQ^{7+g=nc256fE(0;TlB-0>Ob8P(> zZScp|e&JLOCXK+5n&TU$At z&LJ#{0gl?Ycg5ic*fsCNObYU7S#V5=e+(EY<4=j~lUD3AT1PG96Dv~ORm9;dL=aIo z50W=AObZDOA{k|I54@Yl)6_Lbt!1PeHUcH71&`LO0w_U+p6`p%L&YSOxg{oWv!lZgk29t4r_fNGywCZ=q^{9!+KM$6cGQ4c1OQ62n z3Z{b93?zF?CBx3J-v}~3sJ25Ji*C-BL-U(?DO8R2LNkls?oTY>r^a@SQ%7$c@F=;G zw|~qN>XCj~J|P}OsS`qXP{G{tSEPzg|jWRQt;5Ik0NT?EPJOlne6FmSBf zskt&O5?*H-g>=48t~%AGNT8Ym`Lyp7S>5G2&C&058Xfao0|CVKT+th|%kQ(OQ&Q`O zs70?+B>M0vQQ{n6`P?7QfGiM;$_9I0zbMu?@r{)ufoKIh^AgLxGqwyS_vre1C2Q&- zjnS4ZCOH|npKvE!qmj3o8n#66(AQ17SyXEai>IelCo| z_&VSc^1clt^YWK3`ALQp;IV)R%T|fbabT1BLTP1RulR|H>c;Uyf(qjLAbFr zOlJQ3OMATWuYmZhZ|KGLNB4BWG9=Z*pb(P+A#6jMP28S>urLJlV(GlIg=({>rzZz+ z^jBi0vmG5mmK-3^-Q)GDUOTq3D4U{kolcyYZu zBny{_kZ_}?M5Q>A=#}YkybWMhsO3{>6f=cV-%}!!1qk{)6e2|rZxi;fv(VAejd@{m zY#_-s1-lbUCzC8J763d0a$5>7e(Kf2Ca2Bf2w-zgH+uKt77*dFd9f|)+$;TARP15R zns(Mm24yj)D8P3)1ME#?Y3%(sVaDG&)25zRx(IJNj!eAIdL^?p=RMKm$f0Fn^P?u{ z1Ei@gmu}!)+bH#9rD~YO(+Y|Vc9i$0B8^sbKALvBa*`k0o11P&U2z9EC~4d^F3+8t z?z(rKFN$9Mb4l`(m3Uv5!U{LgW~4P?%|}^i|1uK6ZC!+jmm@Uurs|e$$Q6)D^1S(%GIW$-)BpJgQY7;w&ZOk zIrLJ=aH-bxIO0k6G4Op0 z1>krV>4V#Nb3?YBL#ha+3J=4a&#sg`W}h}@|5-E3sTY?!@g(1*ucw}5Gn*vKKU18Z zvO=-S_}kG+>nq!D+|0}sXWPS~uF^XP2lv~<31K+QrsL_$b91h<#j0jwslpg%c}=1# z&2A`T2lEx(9~^322)phs58Upr4hKI|i^eoHH9^C`T>n_Wc#5F_;E%zs$16mqz?v@9 z*(`l)bXrfa9!=)xk0Jq1#!WyC?=SWP7FY*>k~~s#yKfDCOn^3vQs!S>UrRy-^F9EF zM3;XUCM~!^J}7cCbvTYjw>0{w+yRz4**R^$gt**v5?yZK2qEf4>e>xj)|Bk3ulGcs zQvg?bO51Uhv^$#A*ChMCO{MpA)bAj1mX+l4p`f9xrt1nBbQs@R;N2l-u;7GTYF?$* zJ9~?bENxPcXe&1gOWx2o)a(n`ZK!2`*k=aybU0#H_Z~J|TpT0FLsX?Uya zI%zU#fzwWn=*vi9{p-Vp{i9lplXjnn)kwKvZA-ODd6jzC+Q;Wo@9VR>#?Q?#D0@t| zGT3fH_GS2SdEG%y)axuV*y|k4Wd!l50_cxs?h|O;*bLFkAKWb<>HfO(12uM&Ye z9Zaw&N^R*vr zy}Fvv@I+C6LoT+{kWm8)y{k_`LV0nntgNJNyuqM#?OUCvt@+!Vk1nrXK5v>;#E;^k zJoo0LoNo^{ZfA&o60EG!EgPCwIOc0~bGZfe=3Vnxu_xo5tJm799e2gZ;Zm2B)vhM& z;h3WnY^C_fuo)q+<(Q>sh;(iEus^1Fx8rpt9+F+z4 z6P9t6r~45-~4NCgw~VAY}M(OgJ_=WBfpt)f_#~Lv)*?>kLIyVBa zW}ow;?*4H_Kku89$|;g*($Ak<0%-^zS$0Y z1_o?$vp{G!ZlF-Km@M_v>Q^i5soV}T#iWgG_eddT*7J~-dkqkesQi8F)WL|(bH4PK z{h2Im2oDk3#-rAbYk$JD->jXNLm{g_hrd+U<H<6N@hvp_9yjDvKJmlASUdc zaY!T#2=3u_uzq^DRo0`Ky1zco!D_m=*q;VWad5k0mdFXE>Gn{ZC?X;Vw@4?j)#tIP zcaiMGpqoS5s^>+*^lU$I%mCpldOFn7tp+KJC-SQkMi3 zO}-hA64aT)rZd;eQx2kHY!>jj19xV+i{yd&gxHe8>ojYxKbgM&Mq&Y?)mE=M6~^uJzQL?l~Q};0Q`B3 zNVAI>uP&NPL4IK89H&B>*oMboBvUYj>&I7{iD6vfuzbpmN$EfLh@VkVL?OT@j2E7O zS3ii(;tLzB+7K$V=3zS3QFDYz?t^?|;T!|eD{&$syb?lZ((hJTq;d%_a_YjjwB zM2dLah;^!&UPPAf#$szBaJkE1eEIQ^bkgaUTE3j@%C)&NE^jCxpiztp8JtUqv5W9) z#)vBYJDHs^iU*%ba0v}PIw{SMVe7B$sAGFa<&-EpEYso5#tNvJkMm?Xh zi961@#p!tc9%ZF)Q{&=dAuMsArw2ELB}qFn@Wd*r9?;~TtT{qodXTl^INY1v<%c@~ zX$IY;7`ngj@5hkJ_6F28sts3>F;x?FEpHQ~`x;tBwJYQg+)XTDIu(=VPTPx!nB)%a z9pFnhgJ_BBP%MXXQoe?=FJ6(qOaw$ z;eoK0Hox``b`gj<_zOPowO`z{n)DyH-r#ni_9WiN3ie835JMpnXN@V_dtI*^l@l&( zI^O`yEzKzD`cpj)O(D37S<%zeBf$E+dGk5IYyS9VR}c0wS8~Fp)%B4RRPt%L@m^|)-Dc|KhlUNc z!ZU%RdI|?t`YJ90O4LN~%j#@3D_rVSJoq5(oZIitYuxfoVG>(!OYL)@nM5VzKd_Zv z_bb?~demAhP_}#PF6Z}bxEK}6{~Hnn(o1rrcf7RXUZ_lqq|&`Ir+ZB|qBOXmay|@A z)?6U^Ua#EtJx^ER`#<=cewUjS99q!S>a?@9^an+nj9X5(I2_KWA8+2c zpk%b4In!u&OlF~`0*9cZ#zl2tQqhOnxNYD5dJzJ3SEhiu3`6D>pDP4JTFZ=OsiGTN z2t(8eiSxzH(c3p($cM`(SBLkT&$c`s<^;K=A-m0)9cw^rjAF;@$ALf){7(DLYHiu8 zE8(LyU*=rZNdUJiI-;BB2sQKB&att@nYO=QAw6ffdbdI*o+kgXk9HT{1Ynneh6>4q z<9sJ|ta?zl(&Vkj6xF7;7I=Gi$7OpI&t`UoRDy$xPq!Y!Q0ZP2C;e}@?LDk97`UDe zmba6jG~Q=~`90K(2231j=-ZEUn}Ojab;Jh-*%Pz0G41G@4vpjIi@eO*Q$~;wJl&Y@ zMzQ7o!~%Yz-X8&O+6dqTh^-cfLoqTzFlPQNm||a!fI{Avi(4cXKGE^X=}plrOjP4) z%lQ{^iUjV{+q10}pL=2Z&=ZYOZn>!}&71|V6XPkp9+M2N`LKCAzEz*-CaIUi1HO!J z`CZLXD6LX3DefvXSPMj#OxX$|KYr$p z>&gYSd#86oG;tN{0g#t%Q`7w6=X$s&58sMF8lCHQ4_w!oFKsSX>M0<$E2Qy(g)zO0 zSu@W`aZnW3vF8;*M9+`KxN}OBA;9$CAw&dI{g;grvP6?g%IDzHhu8K;Kv%ix6hj-9 z@yCAoa3WL=GS>6xBlT1YHA&^|mODYH!d5McV->~g#`F&WK%*D0!FKtvnPS~TS*Q}6 z0OQJLdGLMuT0O0)eP`s6qkuS;pfPUqWN+P>BFP@Izy7dubN89}RkMCyVQJl*Lv{*h zVbU~HNthK-@U7*t$It6FW}bDaHR=B-IrhFfTP8(PK~Ik06{)=Ba<~7L2XCG2RO9j6 zp6*y_h`q1VyA_Lz#tuyC(p+aS2QNAe{5sdg&rI(3{neUTt`XFqk~uxcuT%$$#!@&8 z23My`tKSmwIVuyJP{a+gVZXaY|6;lDV>`@jXE^2HDS&#)yjxOX_4>FHyBsP0iN96H zNi904ITYmtB9a=N=^pja2THGv3=O_e#KNN5q@(29EW6WJ1v| z#uKfHD#iWG%j0^%8$nX8VYg~qxtp6&Lh0C!qe2AIOpr070iDh0)TiV!KLxW3{oGv799jO zOXCL{yv}*QWvrfd`pcs{9l84o7u@^0wOqUPze3;@If9SE0L{E?1PTJKa|aB zfpd)ocRl1WHraJ&mMHD==z9dh5lZbI2R@^BHui}Xp-yp{jJ&Qykkkxxbj6aZN*a!s zlApaNR{;_*MCwwx0v{yppmy@$CgXIw74^a?TmugT^#?P%A0%&^ZdNZhOmx=jtC_2R z_!8vlGeD$koX5WoNvS*P%*wS}YDOxY&5YQ3wmJgca9OX!iM3$921uWMA-Hc1u*vwi8{+u*4+ycuzynRuWC_lq5q|2z8LBB)^XeqJ|&v$#zq4cFxBGnIZ z3R8XCFc^DEr9pH4l0|9ndu*3D--ZL)PYX$MIH|jlLibkQXiO~qVOxq^Celd3xZDa@-j#`8{C*8^nPasTkw-r_sGLIgj>T-D{@7eD~-> z6KRu&UT|V!V!@JP`896t?qXs?UU|;(kee>6EUEfnJb&)UdpIvNkHi+(QGl@thJ^9Q}r5rv-lR3rn2&e4mZiTefL6_l4+bVp?=P?k9dN;!z2~38{x1>xNPfbmcFv!SeNK*~I*@ul zDs5`oQRE>Y)(f6}LyCp)aU(#L;cah7p+>0mKwEI}EejIDn{zaL?5rIM4hH3J$z}i!Q zG479YhQ1d-y^)urXIz%;JWF!Ss~RXaO_&{v0g2)`*KlpKgt9L(Gg{b_M=OK#WlRxQ zp2A0BvF{GO9WH+PG$90JT7uWUrmM)L3iZ1(A|mb`5`KWVtHcJ}Q29eGDsE_E1i}z? z5Qa4+^*<5N7l5-emDqt|vB<9bO77VTcA}7!^s@udHv|jxNT&Ejs0}#8_s2a!U#0sZ z@D)jYS0K6a);;c2V@UBF|2qiogx)i$T&(M6a_kYk2nv5=(Uw*?+w5X?0fqEqzSj7I zA)a@F#g}#<1mNjnmGQL)Xbu5T+RHG!|DP18=uhAes(@Ts0i^w*ZAaw*OuZvuTPoYS&wfS>+I3jfviRZ%_c70@-PX&;Z!Io*&+CX8Z!GZ?kns7Qe zp_YoFYotJ@LK00ICxA+1l(+{p+rZ6a=I+rQ0yVq$fw zC@$bu;wY5;yY)h* zq(TX_N$a}#{Q2QvXG)-?k+*#z!9dBw4DEsJq!=j#TBx#xNEbzf2|geBNyC89tKo31 zEdGDtGlc*&%5=sn{_0W`(*CwQdRP{z;r$vchquNIN@ecYejM1?1GBJ!J0{Im7nfMx zyv;<@2caQ2#h)mxpDAiR;QjoH`!KZ>X~;~Am_$&lleGLM4sNm9^y=m7muKt|>8OfD z96m3yBtXPb;C$F8p%b5jCPBcv6ZGIUxIc#hoftlSWWZGjuMV*uU9LJ}VlAZF`q2Pp;xeSQa$pL^_dUUb2*m70? zOE`lM5-EyK8e|7Jr86Ey!9~ftC{(2kCb`H9?!6K?GeyC6*~TnWmxQxo1fH_Emqv{( z^R$D14xJ`c{6|P{wjs^If9g%u01Xx%+5j%3vgZ{wH8IY`z#BYV8rdyA^g7uxpwrR` z3gZ0_l84DC00D;z&YkfHA?jdzuGGaPvToha6U9cd>+48Ng$b~Q|AV#4g?o{#LN4U- ztJxH(0eCW(-3>4xF4HYg}KxNP6CJ>ftByC<%1@zoA};s7k7fSLr2th#>w zKy_;4&!YXB1JK?IHF|q|JS4PFu1ke>P)&s@1=}DLRjTvU_7`l=C-E z=tLBhI_bX_bP`@*v z56X@&y$+*#-1?J!5oe1H!?5IrQA9x zo1ezUZ$wyV+vT8d2a78m#w7A^is`rOLHcv~{6?gNNH}ct6v=6AHZhd5# zQOT~$`8v0U=ZJf=jVd1ufqUQfaC|C@qmZ%jOlOW6*vk2#7KTxdju*-`E=$vVX63V1 zJ=SZT8}G+9*_7&B?|NaK`-oH?-$q{{($t?Ewqa`4_6Pj$PWCMJ^3+P!1It$L6aaqA z6rc}+`PPh!))O2uvft-$0F~)?q7{a%R?MDv4j*+9&4|!eWp1%7{pQP>bX-1{ZL{M= zHhq0dpnBBXiRRHqvky;y#`5$EXD8b`6GAOFT67(kJ-zl^V%FYU4a$}o6#i)%7;K2$KK~* z?|#3!Lbh)-8Dyz{%mn!O%({&)d;spdw&hpWI?d*@*+~GZzyBz}zAJxR1KUc265~%S z03Dy#sOw8)SxTC~^{U`~R0mwM%k|`%fXkC5Q3(n@?vs>)TZlXiz6 z!|Jax?#0Xv=*B6Uy^y(mE?mDP8Fgx6*-(&tEMq&$gyAH_+dAGJ9f8LJNU5#Mrqs~V zQQStq?s4u9Ien_l6#b(Yzog@5KfcfTSl5@mf?%`@Vz6{Z+Beu0kZ*za#S%x9}gyu&=mU+hKyJ`6)!YU-&b%j}e`6>!e zMs{WHZS^z;?ZlcEef(S@yVc%Uf?2_Mn0%mwnRLO-o^S8;dEZ3S8%^1S8KawkQLFE2 z$sBi>!OHxr^*Lr?`-TbojDbD-5aWs3_JO;fM=|DW%3ifP>>@c`w_?OmpSM;ui#zM} zk+-;AW$5OdSHiIB7|!)2CY8yAcn0*jy=`iJ*1MEjNTDtuhL$NCB1A6p;=*UGy}z<4 z(>VtLq$Q*?6nw`Fnin%mO=~AeIrYqkEG}x-{LiigZ^B)BduvXM?TdA9C3600CEB8RN&ymM#YiZ|@qC8Dl* z908+6 zh>UfZO*rffU$=Z3Uc6X^?(xCCbG${+$9AQS3n*$OC`;z*;vUy+VN$C>Rbl%6Wt9+K z^wH;GE1;WU^7UWT-r{cu7*%y>HS!W<6aJ zdGssRkFU+$v2(YC+NrOc3%?e}M|@&En2IdpRr#?-G2&i>Xr$FZx~H zTDyjTB>e~p9-*W+>)wh8&lUrS4+Q#lKSyM)+pjiDfQgMwi)feLEIjWR^cJ#?0rqug z-uddpTwaO{qt#_M1q%ACwqDGj&C$L7;QLsvXR&aOaoVAEJbrK*WR zK{@GuGBfi#4}>Py!mn8+Zw%O4$iJ9$gg1{PIn5WFZ+opzC1y1%z}=w=XN%uu=(YH6 zi__t3{ic@q(3H$p@azJ0HMnB82j zaRg07*TlP&M2jVj{iHvi6<6@+q(ZxtrFshD8Htr86YG0Y_gMCExQxhleyl3fKD22` zw@s=s=|g*l?elL<{~>s{!W;r24>w);mpajOaA1pb4SGJ1fbSi3THx@tCMJ?5dX2fv@)l8k$fV$Rr+XB;6}gD;yL z0!?bP43fXaX{)iTQaI}!r|Vd)b%5O}_cNci*$cX3m?Jjq)-Mh=Jb6a8PWc1t+Kmbs zo;o^COROI2nzLTlMe~&}9z;-He#~^cS6^}W`&dqEQ&Qt-JJHc7N*~f99hAgl{OSAX zExr1qHSfrAtG?y1hRiqUc++tO{txs8E-l>=v1Sspn=aeVJr#GN2DWPrM>vw<4$lvSrAmFl41IGDk+1XY;utGT*v0uNg2cwf zSAZhbAgpFV9Xlj^==^&G!b&ifWW#92qT}}mWQt;3PrX*OG?NJ8(-M-M+mH1}Z|oES z@heN>xUk9a1YqCeIQx~p&yv-2Na~FHEIyXkd2a|0TlmKW!y6^ZyGf1~`L9EZ=Ngb( z$;^`yjjrPph`)Mw`^N`BbKuV`3h4QF@6gP6SyUh`ebdB(e%Lb+gM_(G{Q8Ybn&Acx?WyE1H*I1SJ_Igg+MWZ{WceB06n@gVZ8dRAVrqF(+ zHq)w*Jue~nm!BG)1-F-$zs+6#$*ECp>B^kF5}u8L;oa_vsHzWh)P1(pI{2}GyH)$t z;Q8UJTFuY=UTW;GO$${x3*T(61O4Vk5~$|^S5RdGhida=^7Ae+fae@W_=%LW$p?|T8lM*;NXXf=I!Z##VJ1!0gNGW8*Sd--vgDqWkHS! z(^AzT`ZjD&#P8OX6Mckd-Z6iSImW3^Q7W1Wk2gB<+;wqev@sp%^3J%2l)SUWW6^TQ zu^N45Y%7aIyh4eLy%W<;tf84>zTJrJOlQ*^D_k&Mc>h|x!gH8NtFeZTu*`yjB;B=y zE9Z4{t&v(AqANqtgS~@OJ|?7FD%mG*T)d};nTW^x<1SYsj}2Nz5L1$Ug_c04sjDhs z8RQ33bJeEeG>tFgqT}`!$pbj*Ub7f0M&FFTirNjvDdM61IPZ(P)#3hDm5<8@-HGPY zHtCDQa5lQ!tJUJ8)Tu{!Rg_0{Pj>&@GDVj^Bqc-<_LWC>HjG3hJgk1DKfi5X~5 zDEt($K?pp%SgJL0N5!ERKG%KBUk|bbh2oeVW(^ISCKdkm@Bxn>8XUy`&A6a$RPg?8 zROg``=wT(=ywdWhfA{U>j%j|x!F-RU60KV9+T!SQq00AyaXn_uwk%H*vmlYv_3nOv zZ-q=KXOd9R32?oIx8oUg$P09?%9@c$VF=Li>rAK1UCWZmaSgrzy-osygT=)pY`@h} z173O;)ZsdCeOs03xLz)ze-X2y(9e#BsWR%?UjbdswQI*W<1t*C^a*OUt?ITWazf6y zZf#dx?Z+AIw=AWSsmU`C)x?yG_QA_@EyQERiKEfk#xUI;L=@lqmok(GEymI=l1@c1 z?3UBFC*yW|$q6sBC4!Da0gR{Nv7cOmH9?zYbU*~@%ibdoqW)1k!8}nWw!X7CCS6_< z_P8#pj5s_5_a{a7;}Tp-OkrK(@z$iIS{wiGbY0{3bvQ+)OD3pcAjYt6~^SqmhaQB`ZxfQ z#^pm(Da`J@v>}1J*d%+{ZsSw-QTjLs@JUneJLvtBa4PDJ-Rd36)!J}upuE)w8u5Y0rOEv4ufNT~(&3Ss_zLeucz->SQ zbM1LMR4pDNkmiZZsMX}opI~V(y>q&w6ZIlz$rUeD`{=}v|0Q*t*xD<&8-W(5rKK;1 z$Jnf0RgbZ1oYKcQlEi&dR3=x*zP0A6+&6pSLElQ5Z}J=KqU z!O)ixI*C=tS(t9a!kWPIU2(;?9YbUt| z1^&v4Eu~9sNa}c6z0K2`tS-lA#vJSSbyetR=;kI4@{{ffaH(%f2~VpP9l(ly`v(2)A1w6L&%LOQYxcvXuv#kY74 z_py?)bgEe+>l0qmIhw97noWPK7GMR!jhkwgXl;YK`c2wxBQF}i91O+0;o@W#aQzNd z?Nn3Erm|I{x$x4iC#aF2Z-l?bu(wit+O6Uy-t@_H!j4!&^~c-B8jX%gtfPAWL<8gk zfdF{Tdyg?EjJ7hjyB-c3t#X}rsy6B+y7hEwi=fZl6N831}Q7n%VUiC_~Roxa7 z+_@I1RLuec)oG#^nk@fDQ-FTxRk3ba#DGlnP@t|~Zp<9QR(Bys&Q&%IPn0WK!GXK zE10pQeq_Di=rUX$f)WRGsAJ#sGLCEdnR@S3OuD4oGT-C3!nqU9sg%OgyROhYM$h?r_$E)M;qqqn zM_C#5+VQMv7VDoC$Wq`nw0{m|Rvxhd;K_J0s#V z6Or}ir|!a$%+7={S35=@Vh+jK_$6kz&QE=8%$rS*Q#VkfhCQ;8jtDF>{(D*0sai*k z?4I!mXBi*6Mi)yL*>rCxzrRFW@_Hu;bLbp=n<`QIDOuupVUKe_BbtNP8;`BVs@3^n zA>#65ie!cSgTXe)>LPE`7Rj+k+F^1$(IX4Ziz-b=RYQ}~$aE|KTJNJy0eMLEaOvSx z_-CdxBEFIwh`{ujd6taxQvMBU)53p#$D5k`-H1s)!o0sr$BHlnhzXP9H@D|qm1_8 zu(@jipo4!IW8f*$GPsEcF`*0~@IPDN6)-0PJZwsydEa(0Qe(GB|Bu@GjflO!x;p^k zuaB4E7SMlWb@%)8#8k47=}e8qXzI?dlI8yi+oAephyvB) z-R5R)v;P6;J@bD?_nV;x5<-_r)8YGm@0AB7CGtap z@`pL5vi~G@fBhB+_r?0g!UT&Pr+6}_+?VNGPlb-5k3oTZk8~D(co|@a(SHrQA0TAU zQe7kaIq%cIk@2(LU2pG8@3}RNfSZMfPMaU05A<+zW zx?^A8p5I+65PlB+UH%UDLKFJWie|`wC5)yP6*0ISWxTQmN#^j`fP|Ia=2MW;YsIs% zOz`=R-QU8IpbR*JnRowQ#tzsQzu%@52E!R_P?_WN>chhy8j5{QewM%)lmD3KZgFxU zC!|(Rn83ySypQ2~U$@f*1^RcpNLj(Rfb}QEK<^L-F~#wC-LqrXOc3N+yzmQ$rIZ$m zXU=Hxbn%$ZKNEZgoZ&y47upepk%<;6)JOI{Z0q~1iN`sWCu*?_20MJvmtw7JQY z{QrqcxELTR70p~0#{bWofOAp%lchkjjotGMRuS``m45N>gKJ(t(_6%rKoxi{(Tn7y zzqb76EdAbs3+7rtu&+nu2|iN0_|St#jcyKwx&5W^L;+Lw3G@g7JF=b`aS z9pLdY2I+4M(p3!%2L=P!(YU%+SHdo)SOhk^^ND_CHU2?L{QCv_aUIv@n!a*3gA-P7BIVCL?`T`Dx(*g7Ibj;V@f*&(bwEHxnPUUsr~#;_!0p9i}5GpyMv zZ-EjS6hHXE;SU#KrsFNd*2+1 zCnS8SD~N7I^?wI_{eI_{J^_9nH2|tP$bo~~qL?9sEMv(dRV0%m(}SWN{#klSxs zY9d1KToRiV;Xx1DVtNo+HCM=_>e9m6%0V^&l577Xop7k6I6wE5lnE$fUNnmlsB^?H zR$~n(RmL->`&1oW@UF)GQ8Qnih5lC^ zd_uuosKAqggofB{GO4t|&s~D!&GgL7b4=)Fn1EK<(EIck7!R`OHHNg8=!W(K?BN#N z0*V-9fm6Q!cc@SyOVmuBDXyQBLzT<@Smfa_3>3PP52%!}W5pJom>Nxv;Ip44FN#>b*X3d(lE(jG$ z_^Y6naY!thn#H!fv?eoPqx9R6DvC4iTHeH>R{Yj``rm`Qjs)IeMZHHRY(nT(^_Cg1!aUhM#Sr%4mvR9e|A5xhtYr2d5Mat zLKOy`L}*yb2qnPy-*)@jSc{_&)~j3l@*W~hWNbJL9f}98Lafy~Uav=r34Vy)A(PBV zj*dVtYtQs?B;}7C7SPi=R}6gI zb8rU`#B4TekX;gmv!4&dR5v<2G5C>t82+*>^ITb7C8-C*+i?K3S*OFJ z!}|$6>vKFgk-(D2-RTR!gLVUG&`3F!MMXtp$@EJ%a+#0^^zQ*nihn&u0Ui(}d8^6J zb2i5SSDlFV3!yy%5Mva2N)(Q2dn@0epiem|ZS*`6nMs~9HAO*3sQnayfZ|eA^8k5_ zv9cu#20mZ&h;8YNGj9U7l74ko(G!(l$PEIx_Ab-rFNM@++~GY6qy^x^p(N1n#=h}>6;Q1n%ZKy`i{5(OMx#Aiy`RaUehg zUapb&z-E|*olyXI085a1j(;`+p(CQ(rOup@*m)WX685L$@tQr`Q)Eh&>`=1{Rm4p% z=6eh3T7^f~}vhRpZ% z8MD~y;qqW_cQ?>uCQnqJLNe_O&_;E-nG6`BckZ);ESAVDqQ5+#3q1lh>$4LG3*mnr zxZkzZ=4Qk262YMXt6v+UKe`>V*(WqrK-nawSTr~Z3Rx+k0T$oLOkP5L@zHn`50h6v zOY^QJvu)~d-dSefrjFY=bG2~wRNhcKLxTB&JXD{2RF6n_EYKD>HKeXX-;aF6=W+W| zZ7>j)8(|1AqaEz+0nN!$B|gvF@r@0BnJ>2tJ;MO|JS{yvnMzp#Cm3u4;4msAq1X-0(|Q1(CK1SFXjG{ zKN_9~HM{ydDCL-f+H@&Yabo3~hR^2jy@OA%PNSg&PPHTWBgNs`uv$P=YFUia0& zz6=Nu&VZ*%gdS1eHFP~)bKma&3IYb*4>gTXj${tB?BV8A9&b-PRrbM`%dNw7v3NaL zE<1pA3s8C|0V}Q@2qOpC3j?rRyo7H?w zIb`qk@o>}<$&HY`x;bx_lMJC(Dt zXp8d3W)TWS#9CK%`%t&p<2wULr^?7Tcu#GhKgAL6W` zfWW(8*=gkPa_u&kLWx9xL=2eH)$;-iG==fQx_AVp{n30WI<3a9)h62@w*Y3SHrF$J zlZ|?Flq4lU0)dp6*-`PrAPC^Ve#wnX#m3beie$(-|4Kz$@H#;0xdiM|! zZ6p0tO=H4+zk-MqD!#clRF7nJfu7eDrD}eyzms68F_;6;k|w4vOJHnq(4X72$lG2X z0l~0mU?>Cz`WD$A!_+Z*sXpkWsc@MMw88J3Q~u zsa33iRZOed7+5ZWVPvXDA(!d~L8sSQ16bWY zFOOuHpJfp3oG2lMgQRSswA$>8BQ?96(_Lgz_~;1<&tLl}>RxsD^zQp3HC>NS(#-Y$ z$r}WykcL_2KtnE4O{z9pvf~1FJQ5p$Mepn4VzVT3wt&EYd(=Mwbu;lpk$Ww!Swr` z{+iz$@(zH?3NrC^5uoQ}@_BolZ}!9y>;W1q2>3jqVMbp?f!KVqI}(ri-sL#yoKdg; zcU}Nc70O1MnxyE;)3CD0P&G&RAl7YCR<&l z;aNOC0FZIqPDa}1_Mq{6!@Xod)$nS&o^)SvxUN{^byzDyRvo@q#=b`{U#juKZ{KS= zVz4mV@IK=|_#lD5Q_&G(0l}_dKx&FMi6~SSQhq*AVS3wt8jTNbtf@l5TmJ5cF$}uL z&CJtgLs{MJGqdYPmhe(l=j(lqm7fqy>z##sDKb~+1!7N$&>GX{MQAdICV(6RsJUUh zZ_(=CvDu~e*uI50$sFw(0`SkaqK|F1RVPGHoOF-Y4)dQz#K;XeVKGkQRHNi zP-s{!YFa`~iY-GhWe@=wsD)J-r8j3k1Ac`RYPSOHw{tzn1pjQwpF@?=_`I#|S0?CZ zY)%K$Q`!7Ojud-2Y(RbxC;JX+6*&r?d~k5&OeprBMGHu;je|O#Zg<9z^ z6(q1{z=K$lmrVrDgl3>@hGtCrT#_GgkzaMrX5wb>9Grox$k2L7_Fh9t0*c4`)?s!W zOnTLcTC+ial6Y@a$^6{3m~ZYU4LmGt7{8L5+WlyQ=25E)rP?=%*x3c_`U4i{+dKpv z0@(~c3U3AWnp!te4D)&*H0cMbWIpXuYN7YEge6sJ6}xZb?!e>ml7aPqe0hGxpwkT4 z(-#Y=Wld{1t})v4@O^9EK#8(vz#i|rs&EMetWymY?Rro7y@(&GHd@1lQxpq5;vfq5 z(_J|NQ5N&xhD%B)IaZwxqlLdOYCqXgVrB8HG~WcEBoXl^(OAd-m+(b+g*a?Ty~@lt zb~cb;dL|~bhI&2B{LP26FVnERHU-M}bYMQz@|RWfh0^ycglkoQpM!!g0@8wSG)#tM z#i6e(GzA|6sVjvWdX>*Z-x`2POcV}A=ie09P(f}&?3Nn7>y7L*6NHr*jNtqr)dSp2 zXF1=SKM?8b%YDUoZM$9Bk#=(fW!W;n3-_hh)-F~L;qV39@5wJ#K5D?_HfA&0N~VA1 z>-15r+z8&hzIh^sOUyvFz#_@u@?<0?M!rBCiO%BLsCn9u=?Hc@VTOhIqG)OMZJ~hH zh&d?)i{JZ})Aa%x)y;YdeoD7}G5Ao$sP=ntIFVtIzG7U}q1FD1f;Ib=fCgNFJOD*ws zcy}sn=Q>4N~9tbHi z67)U;r4~8T2uTxz42GyUob2x)_gqll9h|O)j81I81*M{gQp#dHoan=bR0>u8T$>ko z9Tf8QO_ZOher5-_MAw(Iz`Ph7*(9NK#ZfIB)8P%GOM zb$)B#Xs?cg@%^dM3@@o z*a8!EQg84%u8B95|GYx@t?d@);xzzBNgOHLZ3cLR`woh=-ALo@nMxgwPd`9fmCBI) z>$=4B?!Ba9rG)+7mL-xcza;VJ?{o347Q0rK$&CGe-Y%S@vq7ki&g%S5w~ZK zduw694WLVG&Mp6b+v-SkwFlHwqYyRtI3W*W?QLJR}vAY6Gm_I}hzJC>TS7iG$3 zcO)E1s@leZRsgoIuP2tLT0D;jkB8Ql80o3d^bnnH4<0*~7^`6V*){1o0C19!;TY+dS`@A)gGG9M5^JczmWISqTy0cLvQGi7Xq z=mSa8!lFr!E(#3BC_P;5+qr#dt>p$$DO0s;GGLBjpwEQ0b@C0?&;}gn;B#sEDOY+lgwSqVb}Rwb%3O+bP*Iqo{}- z?h|eF_I4j-10_HIqvdHw6qUNbFjo#5`M?>b_04(YQFkJwn_kL*+K5;q%c?!y+SN`I zf3v4|?8J_8BLukyoViI}1Rf5_VO62joB=`C$2y2_eUU_#L@GpzSf`K|{DIUw3L{^! zH0B4;wIG-U*YXfIOlWR|U{P%Rc}&J56vZx&3`VW|!+}B-FZsJzm5N$NTxM3r&vqlK zmFw8t#x6UH+9!Cv;tEaD$*&4(c6Qh4o&@~fM0*ry(4v_d3k8eWYNLA&$w!HW?|FZ; z3xj>0aXsV90SU+vEp5P7_DMdfa_WSaxC8`}F=;d#F2-9VOQP`>`O_oesGwGcWV6|= z(3m<3C7v5iuigkNP+$WTOO+*Jb&dbEvyTN;+kAV>9wCBAd7#7N-|^vjZ{McRbDI3 z{d^@MM#HhTR3S$u$r#D0x}Ug?M{45 z)ClX(8%cp-i(Xy#lFmlvBPEge@2G~h_Bd7{LiL5hQ2y?q@aG=ru9Ztxr(`x3kVbKQrvMbG$hRNDmIfp{S zbp6ka+*GO3FIJ)|=qa(@K}kX7qUpOx62UH?)cIEEy@D6N#B16GH!>+IP7;Q%6$GhY z067j&m5z~z{Kf4i<)K*9l6t5cFaFZzNNaUF&uD*}O!hN8U*Q^U$R7OjBLgKV7loDa z$98*B)uF-E>$>P{79|x;9IULjf`Al%#u21+b5*N~C`H;Iko7f`K$G z3leSE8FM)GGt$HPMDF1Zy1Mn^hxRYIf|&YOdfjK+wN8o!Uz^gG*Ka}(Cycdzem#Is zq`Y5dmlImy;u^h9?9s}*Lpdq}9*;1I?9)sM4z8R$2`yhh-x2rKl$V97Hzv*I`?v7q zJBs<8be1B=hgogz1~E%y!@R^l?Hz$Z5&`bf@1Q??7N0q<#xhmqPb@JfPAz`a*3J}$ z$e-VXLD`xN{0J$BhK=0ZzhgL48M^<~F)V)^=(^C8or2ee#%Zist!W*<_d+v@#)jEU zJgqoinf=T<#b1(q({SHb9CS<|HjF^eiCE!Gw3ri!f+M#SEtu7*NPlQp)7&I#EWYUW zmCMo~d|W@d!lE!t;doO%9=IKh?R*vIfro;FgNyGp(c+PD$$hD&^RRj{eFH2r^FYdW zwcyFh1=rIk^}|&wyWG_8!A+z*o)eyqZdNw~7pk=JjJ>F}DBpgg!@97mxFi|^M}@$y z2-fT5;~H!?I$e)>S%jX;S}qKMg51wHR{6`T72AXOsM7z+jD`xp`Z+zK)HdG5354MD ziMBqW9v?E>8RyvQ)#nUEJ^SAe#&_kEnjvJrAN$Z}5LfC8dz0D1{8-@{T!JwWtzaSS4H<~X2!LpMmpyAe?9er#vdz(M+?34%77kbrKt z@?wxpWVlbK1*O?Qq`@K~t-$Hs3lKZ}9`h-tj)9AvT&=?#+d6P7+fwUXjMUtSZ@~i& zvwRh82BE}O+DC-+cO79pzEx_AEkamIdc5l^d*iWqXau@l*^NZlBy0= z({3Y)<3%zP<0pMe{7=~P1tzo=h1b4hCXDN-nxLmjAyTVS?7tLewq%uME zrt|(L0o%k%X=9+fyL-OBKuEn9DZn$Er@BGl)vI+!59?IiB?{+9*X-F|ol(uGg{9(N zG&G7h9G9mZL|}N<1IQ-_ai3{p>V?IvS@gM)*|G(dsh2 zZm|R2fH9Hku-(0gFl9sdZg0f5>14IhW3WHARlh`7;dG-DoH35K*~4O_y%e}V<$bn9 z>{B?7bPTDVyidF|&SZNzJBy~b?eKQE`QAA(o#(>nJ1Nf20j!fg@LR5C$914!ll8-a zzuNF*(`VhhjaxH5AEa z;CdI}3gSETSjZ75cp<^4&|-W;%%N}3AW`ve@v`4t{`=p6CR3rTdO-g5|8^kb0C9Y4 zhtKl3NYnfv^~C?4BR?f#J;R>DS*b&pw0a?tG`96Drg}TzHxvZE2>oe)BLXa1VbHL> zs2AiI0&L117a3}i0(0h5PEqbLBhY#Rg_G%4b@Ej%>$`pAoS8o@SVTWi$bv*YNxhGc zM-snZaB~xp2GmQir$V+;KLHRhN~sOfFsYhd;A9$}-8 z3Ae0(p5_>|7-w2wlTXJ`(aqME`lpiri!l$B^hQ95aTDt`NX%F2iDj?;a5M@3>h$`}6A9D-D2iZkD-q^=Jd*JhCHW-kf@-Ec zpOxuD3qqhJYOAddg-Vi+^YSYe_&F^1^rS52S722PUcqsevE&0fCUCgbLiWMrOW8=Kq~_NRUY|MoKuh> zc!a|qGd{zJ-^O0@gJs^hrpMlzh>z_GoCHD*~VHChQL(}#l ztkqn`Kg-sL1EiklpSdNp2iYhzSI%b1ZelX&#xmMxMT$T$^dc?VbeB)g+f7m1w>QLv zzL&p*wb7x$n!2adK^tcAi%?_&j4Vv4!yiKh{|y{J&jc;O`FnPZ_&{n=ZBwIXLAAFc z!WoMUr23$aP~*`0%s8SLAvKiTb;|PtUG~7(cQ|FfUELGi2#s7}=PE(iL0d{siw@2o zNdK3=h6wCWOQ`9C-_O}ELg=@29YSmOM=LCX9^njV)EHM|9{OR8++EBmxqWvxCt!nL z3GuvM`S%aVHm4|slpD8mg~q3!1HC2i!nZ$*k$RH2(y_4(M8yOMx6{_$=99%=HKTSM7ubSoDjm zGh`GI0sdIuFLPbz{6GA0botk4Khc7)Oihu*2uYV+8cWR<_$LJU54=ZVu7ov6?CBZu zvO$Np&fEt>8e=vx25X`;mJbO-dlEXRJ!lP9ebC4JUq{D(7TPaONWfJ(mFvree1u@8 zP`c3KB~KO7F6CVJ$3^$G{#HV>{No6Ws~Urx>6iog<@-D!0|IaW*2)&U$*@IJEXTGcWzpzHYq@q)JPRL&<-6C+|svWQ~{WvU7 zv@@D_d~|-^79wl)i_=MXiU=VpD-0S2MKh?A2b30k(_Qf3vVC*kJ!0^Rr=ON;qaM)V z1^Q+!j{6oQ6jCXG68+ZJR_+bp)^YGJyx>2>?~3YnHPawfWc9~2#+FaDaAK~<-4TBI zKxez$Qn}hKiPO0M@kaB9LKMd0+4pJ3{=Ev%-Vgq6kQ$)5Mln4x%{)^qc6xG<8u;QP z-z|YoECf6*2hgi@J^MlQ3;;#0eoj0cS9Se5IkEo)>>2?sGJ&yw>3#hUe;>&Jmr3veWHG_uNX5Z`aNBq7i zx(&?p3+CFkm@3ToWGds#KznU5D3F$C<99cEWqJALa1J6C=pfSRc6x1eddr8vVKIS9 z;|_6ha>C*B+`l{>@Vj|FUYi>l8j`yGN1I=y7tl`+`J_ZzrqN&lh|bFUUTlLsC)4YS z;jwvKo8bbI#rg2UuDBM~vjv~+3@A}hP?Yq5e!K9?#SlSBAK(V~4lD|q29UCi*(m9j z)2-HfPgNaFzz>hjLJ26>9yGh0Xt@0ynZ6?Z52cgPFCqfuFP{WIk}9)C2>M;N0up~V zXZ+6x*Y3iObB`pC%2rFgEa8QODp<^oELCeQ%IjOaGuH>>zR@xn`$Q4We8S;G?pfkr z1>;(fOXd=(Rq?r;N)(G_06kqzKnEVRX#TF-?*s6C0P0``$XpZh0h-C*X7qY~qkDi> zs+c992fx0yhDbO-AwOyal5IE?HIc=u$qri<^kO{d-Mx9mOyEarLF+Y3D>-kkZk<r!K$`HT~^Rum{4W zw7|3#Kp!RK%jI>adrXf6bEaOPZfhuI&+BqN&3K}iT4r{6yc%1|(R9~&xjdR!H#EV| zX#7s@I_c5psbaOt!6qC&(@&@`GMF#*YGAQgz6`ATiFEd8Ovb!VvBa%-l8IDcThRI~ zrc+q}pd*XR8M*>!8so8ADCLVq7D=TllY@}0EEe^7jcyvUzgiqKff#m1+hkx{WEAvF^GaT7hzmCs3<4`vox&NsJJVmX{yN(}{9oM1N+jhBy9q;ylQ76TX7(XuoxCy3u z#HP(5L#gLaNkM^uTJ3H~xiRHOB7ulbwg5tjUb~evsHM4iQ|=GKg+OMcIYl#Lmnt}j zflj3yxIv?SOgu;@lSD7A)cmGIHM|bUMn>Us)&e#qt^-HptM^xOqQ znehG5i7}kBE|y$RH8;GcJNhW3>(o?^e^id8xff!$a?2QH-QIhfpleLVma$mDj- z;;_#X@B?YRFg3LKbbj<0%e`K2J~x_3?VMTS>ER*dn}@s+V;LD1hRyH8Lms)27C1CK zOlgAFI|V?tD3CJVr-flqLxREJ!LY&z18^RbFBLQY5~iYk|M#8Eht&@NNNiQ~`ro6n z;y~jIq53BomYX$foQx&4*4yucUuZ@xAjubEF9wPRiEAylx@t$yB(t52s1DYc?bZ6j zq7QBn1<&Aliz2Xv&&c_#PG)j9>Gy%}G6R?nKKDx_BSm0oqIRtUE&q=8_8g^-0nKDO z?US}5Sk3(U<{ai?`8eVg9asc&Xl}au3;~AA4lc5N#I)eddNTmbo zinnyMat0nAT>V)lIh7K*_aRuTIeOGdwD5nuM=Z~-dhUPDwJ(sQf?v{r?Rw7#@^Ptt zcupvo313}BFm#*$2=<#wJ_`%YiH7W*W|SF`+0Vr<3%vF1f^ zEcxSsa5M)xRgho_v2~IYKt}GLgHdGjuN&1D0K99d5ek^`3dIu_k6uNHC!s+^7_#5u zt<2g+JiW1Dlqz+O9dRady*=Fihr&av5c7&%1F4f_9&a%B@YQ_kU z(qD0UiCjsqUJHsW|D@gjDNH7XK_37Jg&+_laS2@a&QFCAIPN~0Dc6ZY}RWGLxghg?>2miy2PV!p(eZzriq4sa*!C!3yX*NS4XsRul$8o z{wqWLE3*N32&wuO>Z9x}o0$D;fuP68v5KS9a&@?VyU!Lqb0hrL=I^JRo*R(t(pIly_-9x43XJB6a zK0xHbTLK{%KG$|@xxrEuFp1ep_ytJID;7x!;t7{795ES>=D=$<+id}eqY!9V<~&b- z^1?Kv52e3RGate6-tKo0I7a?Ci~jr6386qX^38MGas)&LVXVg-AE-K?6F-p`F$c4)>5%eRd;*YTP6aD+q zeEvVc>)%<=2I+5bE)g^tHKaVLMm}@BToKP4HW z`9jNZ8qPY4foj69?xAWNa!f!28!F3|j^hKUR|8mq<7&P6Rbn{&|L+aC|Bk;{Q_Mtl z(7a(E4UYU1_S_>0Es1Qf*02j}A=qymooqSo8)$@iPc~bD;(1_(%IShB}I&%zr(p{;V4T1yF?&b7S%dX2il$@IpcZ zA}Jz+pbu`CQ!uking%Ahbg#?!phAZhZ}7BJFqes@*yOip#PZ2F%u;?Ie%}KW#J=SH zk4q}RA0h=V7M3xQBd~x{Okhch`kwpeQHvN?v|}Cw1QD7!fij^ThmtGARvwm$l*BzG zEX5_rVWemRK(acONy<<7uj@s36|un1-zO|jDhoCXr3f_(wLs&SsOliL`g@@rn~7?p)(a(G2#p9gU$)C_tCiFpa7A~PIA#c? z5NB5B8v}njh7&3xmewsUA(pbFAqug_c)TUIye^A3`XAznpj)TId z`HFFjI9THh%AnIX0_)bmZ>oR{XCy+{fdUB$`{=nhSQ#+H?uf%+)LX8c{szb=eLhQ< zD7(>Zu`iZ?;ydH_ny1^ms7pT2nfFkrGq5nw`Z0oJ;nJOQ$V#P}FrsiPl9nb}*s_hH z*6~1)!DC;p_%?GvqIi&dj*5uM;qvo&@7S4J>g~x_n(KDq#%Q=zqHv}2?!3etM#Bkj z-g-Dtw2YnK?HQNbdZuJD%Q@Vtyh3iH@$7u$Dp~%sHw@H%_%+mb7docNd1+HnI2{!1 zp|5=s`2iYJaAKlM(|7?qKFMtKx7zIIxQ?Fa~U(U>#_4gcgK1cKY=%!69jAR_s7?!C|fD7#nd2xoWR@= z?Cc5wnnZEgp6Qo?!S!B0L(}tFWi8ua?nSfv&yGpf8?N6MS1bhX;49J>fm6!k<)=2+ zI^`7ehQP#$>d_T~@(QhpNR6>LiQU0Tu~_P8@Dhv(txmq&aM_D|r%mK&5jnZ6u1CQo zwppu`Pha zph^{P8ga7NDOwn2?BQzDp?5^7+eM%5N|4|ZTrmC9H_$`Q?$iEz!{TwxV9U&*Dc!9F z@m^NqaJ~wh)HK|)UN8ec|@i}goAV34EYNSY2ILlH8>M+*}vR+Qz>5u%@4`)!Khdr zOxvQS6;0~eAD;>lpym`$?!8&B$jatd$0YKaf`rq_p*tA1;}!RJ zgW|Kl&fcu&JG=D8ue-La<}B~qjgRe^46zu>MOK)OmTWh~zicGGo8PBVXMU{`E$QZa zx_@2vhOEsm>7&!_ihORg+<(RNoo-Gwj}v8NkmEpeoz_q}{=TGeF}z-XEU*!)XwOF& zd+>6>yhyWL`C+J9u)>_ZGAQTCE~%9;wJK6vv;tj5#+t{#X2UlEg8P0`YL4&G13tap zW>u%Y*X7L8f0Kqtq?-AXCC#s_;wUm>Qpb3H^+K%N?NdQcvI09&FlTZ43hs z+4ZqN)P@g-D4ww;;sKnbkmy07)NAhn-PL%`gLPjT|7$WH_v>=AZ<9-=2J67JTg0#L zuApe&fy>J~6%RNvc$X9U{szsv%_RxFoEU$f+u0AYD$P67t`CnV_laSrZkTkMP11LM z0o)h}WY3-5j!aJQ{`y}dv%jnNUp>dMYM#Fv`ha43cnG7)015llTVO9U!x6Bv3?6L> zO2NjF*6ALm(?-_a;`IXWPqylLKw30-rig1G#^an1(pQIN2Zzgz;*1GNBE^LG>97xu zB%gjTmWI=_hlHhOgK3tqR8ECP6Po_(_UCsPlH9ih1C@Yf66Hktclr%bdZ>anDUV=5 zSDv?>rgu~fU!>3HMdPpAL2csTvUwn6%u7JCa|EQG+QUr0F*3i3@xa~y3pEc!^866> z)kzY@YOGD({98x5l^hWr-+pg!T|?QoY0{u{{gX_aRU%bFtj_oxm#|PD`IL4N zy=#cCZPR^Ua{h(;{_oJ71Dc0AWE$;xN z?z3(9ATBGZj~!{!`>T+gTx=)gT1-cB(B5{#^Ru*vLRxCtCNX$2gY=OSzt8PV(0U*FRM*v*UyRj z&8gu9W2n0PZ%}pUp5E7o3oQ+WK@X#m+NxS^p<2GfK!K^uFQN?4q{@@D z4}9e-1bhDeLOCpHtmVA+Y8zUdwL1+h3!1O7CjE|9ON|rax5p-CW*p|HOee=23YPxH z{s>Kl$BiAgUhK`{;^U!;2Z!NH_K#T|PPDpN8C}V)VLQ>j2XY+z;C{+fx?DbGS#Ep~ z+f30nwtCkG71+xf<To1_rUmdo(CkI zOGvFVHQ8BN8GEq&#b0I{R=>T-=O*NTXw_pchcIhf~EdN#;Ps}{oTWjp2hvXN3^CVkhWK*h5b=+3zn1{Oa5LQ8V5c;VYcXAO`y z+R<=g3=fvKWKV3*`+XkB_u~jBFHyLiFP^|+htoC#X%sKn=Nr)9=4aW+v_EejvK&S| zPCw$MB{2s4VrqLYWi#r=8n0;&Ey?$Y@JvVm)5|mDHkgmvU+&iV*;(+hmn`E;dvN^6 z)U`ClpGHhDCNa_`>@iqIOAy5M;Kb(vpy%nZ2mv7Ojzd@!zCX0w;1E)AN2adQmL(TA z?bc#+0Fx7kymGA?De4NFXPygHmPU~EP zztS>5I8gSe^XjqLYyFnaI$fEP#EbG}bHuT6QJrxAwL}hE6)-jXnQZIzWGL!(bbW`A z(PbclB-iKSv{dzU=Ep=`3|7 zqM;j<XwF$>2 z@&8cJ3I{$VCCX}BeQV+#ap)f=BD%z*k8iU5F+Tb1a#p)Bxt>eEkjKVD3965Tzj)p! zTvP}K0m04n-S86wgeSK=+RZzKqEAsqDI8eSq_sre-M?y$q@uGNji)lcPbeoXELmOa zRu~*&E06j)#-DX{c%2kA&kFG{^|{G4Y){eB>v|SmefmJ)@^c$4LcvFfg9n=6=SZEhl$-vmY>RD?4yomGWd@7Fbq3J5ave|5b z@BCZ0I(-_)v07cN)GLi*1$nu*w%zvmZWI%maeF@I7DEkal|xIHmeO51AKjz-SE z#UyNZMC7fR2yn&e#K+TQE5DkE@(!sn@ptoU=R9602QOW2IFWt--Y>Z-WFc=D%J3b| z&q8DB z=(xN)p%<{H9$_@~uxYCElY9?vO&eCn=i9a@!ys%Ep(43#Fn=u4sXSW=z449-&3G)W zV<1$L;B)H1VkOq8AmQ7?nCeLy>$GK^(fF60*>?TR_v>71p7(0)d{*l<2!dGeVsu{Ym z!J#s=9c)Y#N6B-;8UtAXsKRI34Avp<68!F{RvY@6HaVgyVY4{yA{F^ri>XsCf}U)S zdf;Ay$(>3}c4W6ArJbxU+Tb#F+$U^VRsjUH?sKhuA}$kl+===iAq z)#o9sy<0?cvtBRHT3Q*jB>#2X}7y5T6JDtOYI&JKQkEL@6aI=^VF6gPoIMhRZv^? z+BH#nCPgIMuK8zEiC!vV&^ z9w~ZK{!=Q=2yl<8(F+RJUA)ET^VuGEZ-)(DBEqQp(e0#nqw#`0K$t&>EZSE~*2#n| zy;NT~|7N}VAi06G(R48T*!13PduKm{$>PH^1AXG~kaa(ds?FvI2)~fxcvuXm2W^yU zlb_-BMDw28L=m8e| zrivfb`Ufu1^ghN;;+9TJ(9{_96r}7L!}lKATti8!F<0 zCA;;I&)eEFJt*d4_J�Bobrlgjl})WG(B4uO^!0XsE~#-_RV~6RY^OD)~~X#hjm=K#$iOU&c!-B4v_?`&Tyh0d2I;%4!6Wq1_9hcmLg z4>L;qaW{IA!zzA^ZUFZ45vGDOOTnRWX71-Wu3Aa^5jOYw+W}JKP!dpuf=?z4m^SMj z1Sai(i(9vI`fD*#@>rO9Ph8IDr%>$_Bdf5kC_6h02Hn$N+_&Edsye)07F8cMI{QF< zZHRCj%#S0RU!pM6Qsha9$axfa@4q0q$qy?3v^^2xL-aQaZQWR5 zU#d!}5-|k(P{9|nH=2gUP7Ll1(vCkPSxdV}y$C*vA$#!#uX%I)|*Gb9$oiNbhm zHh8_se>16^d&Y=G2h`O*zqFS%f2@oiwNjv8t8qV`d~q^Y?1Qr1isp8(BN;Jc5ghD8 zFa*H{tphNZIzebwJ*CP!t!%Zqg6THR%{>j}S??fVh6O6pJ-0<5dqqM*#rG+n=W|?Y zNlz*^qhxcuNlLh6c{sjcm9XXwLTTt5|Z~!hc_i?a+2e{eyZP-80)ReOZb=nY8a*3NS z^KT<%iH0H^zl?=;cB#;4TP?Rr-=jpwQvpYhnZ}xKp9Qmu0RjPcWLHIV_VKUXKn`&7 zUuW773~kvyC18y7#AmepLvzx5bRBY3d_ zYeerpDi^uw(_ngdcpT>sX0`|q$*NLmOGWRF#9G@;$+X?RHM!lqUFQ@!9v)3N;hR^B zh3UPd=^8E=y!leJcWme}q9bAM9!CUGcU5R?wSC*GS_*#&(icn#b57-oJEh z@dM+rcY?iMniw}}Z zvqhhc2_6SGAq9z;pY%F7PhH9k1rP`Xo*wR|Gb&Hne4c)$T0|$z&Lz->z=lA+#pSUu zHBBe6G`ZK85*W)Q8AG$yM{n>G6l^|86y?5SGCfaWwV57g{9uo?cJLH~0AVs31CKG0 zrDJOc>4Z{+U`EF!f@@t=Fp}sxnw655GdL3f{p!CI+aG}T{aRmG#+vg( z8;)13f<6<8B=hRTZ*kiL_Y!E%Ux%<#Dh9trd%5cqzju;M=PE1VmUnHrSyFgINsOJu0125fShu4$^SN&*~%p2*Ue`rMi z1ggPvVrT?n9PSI2*l>{@+NEr{8s%N8NIn#vvW)AHEJ1(@-@!1(A6mx#dh+v#$3-vt zgSborn6A`nF=t>cj7C4G*7g zeG20w=={E5t9hspLC=a@v&`nus?VpQMvKuDk7XeBbn6?xCyB!Sy8-8sIH@n1xZ>3n zR6JR;7F;3-TJ)Zcyig#~zHexgF|=7hELu{JWb`Jr$Vr=WR*;Vw{(Kjt;6 z{YjzgAaq@E-yM}8k+@;^+~P#+VXN&z0VhEPvti@eaQnLZ7aO50F8%>g0Q9L)tI*hWVEmkq@3Y8kV;T^%-A7e8Ovdl@WiW_oM7%8- zu6s|bX{1k%qUoluKPlVL6?et=yNGwq`cjLKFM`G)IVq|bqAC-w`hpK(YC%&4 z;U`y1`<(M9B>ss#tmFA|ZYLeNq!;K^pp(-bBxyTgP`0mB%UL0>^|{_iw?S}fgqEAt z5A`qzLQW<5;g_uWj!vt9Iqu}j`9PO1YqJsBxx=rhY|i4P$VHw9Q)KG%+$DlHdiGez z;~F+X{5+O9MzF%j@k9Bkjl$$XJ_W^52D>s?g;S;3_zuk*OERvfchBGFLu6K4S^{0NK5b`9d) z@u11(!)2+gkDFSbbn#qTwL7PpLl3WF`rjQ5dT!RJ&J?F_r4x+KNAQM+hH|iLAKZIH zvMYg~w4GAT7C%`al^;7XIi`Go8fv8kcu;`@V@i*@!)e~EXb2pl&$&Myq0r#_>B{E; zx{f)fAdC5N<9^oC9QXSrETQkTLk3%<=M26;oPcmQw2@X-^)LAf>CLWV{+oLnJJ@A5@GX*@0oK1W_KuSvLbE z@x|PPP3NFg;qc=!5V2PN)%c*AXk|=B-$yCnzD%R&J#{Z~!*{JZ7tZ16rb((3y(L{8 z9o;yvatYL#JUND~8MD`OHKrdwK2N_{&?|Gi?(aHZK7tIQZF_0m+p-xRpBxeInW-mk zM2vbB%rs4V)LMH9d8CiF;$Xc#T6x!?#dv-|tMbCt%Czc@6ynurt$JxKLFJBsBfOS| zHX`R;#1Y+h_Zd%m%io@F+rE6DZO?Pv8k{g8$kg~2gRBPynjqUMH(s-wa^PdHE8+y1 z#!A?TPURt2n3%0K>z4I3mmL}YI+54ww({mHDmux-AS1KjwKjKhLiQ(fK?Bq0mj^C$ zTwC1s*eBgo=hrWGrxt*DBt8QEd%`5>$Jd8}i1}I_)k0-h=otK+!-lQFrCV56%?0vA z$LfUO+Hy5AQxV5QYr7`VDzuWz7XlL;d$Q8^rU|s%W>Bvk@!2wbfF%R0s81f7+KU;p zwk)kPXviz~M*N$0_ZA;93|-;M{&qMw-?3 z;-UAK9Ied95*}CnP~jFHkn-`otCA^svB5=T_~|G6X9ZU$1}hWHR4XyC-|ScbXWb4r zSEE+3P9^%`%^;NPY;kjXr5m)q&NSl0NuZS82D?oR{16?BPMxL?Jh!900(zCR>cQo= zb8n1wcfHL#d4HeBY0AWmRk!~7d`QsIXeG-YWb}8TvL&KrI?0BPR@sYqJE~;dyu~2t z;cqZn&x%GzKl`zUl%U^Yl4_gExyoL?)cpC&u7|O;sgcX&`pqwJR_`I&-^Ae% ziMPG3&|bNG?jq&cnr%#|*J`gG=l`73=6ky3#>iov^65zhm(Lj5z@>zBbI=Q$P`8ttfE%MMFkcM$L1%nb=fTt8akw459$-sC(^ z{8(4Lq3uY$AAaYtHLzcv{s`AOEv>RT8w9wO?&EUS^alkxoA*9bwg@$ror13-a0&`Xpr3bk+39YU8H~xq@%^E7r{vKk{ksJoc51YY%4N(u_l0@g4>_n-Mz6o-~|PG zI;TA*q*HU4EJQ(jC1RWk`XSZyF2ru=QjR9Ph<8DXga8MX+jpBl1*fqT>pgoc5gBet zvXrYf6*1X?@utP2nCPZ@6-iT^V2LS?!?uku$2)!1pRjmx3FCEbhISmKl}P41y2iiq zAzMU~1}1Qp9uMm=^Q_)Q84kQ*NfkC7yyNROfp5ejNehFxtt(U?^T}}W?jQ>lYf2$i=~d9V0c*yn|t9tU+4MdGE9QAKqX?1U9;`!(WDDq zC`CnVRd*BtA{yLA*r|__syV;!2^oT-ER(5S*4b`YJy|_vd}S5o1Lnz(}wDRrCcXqZW~`wdUABJZBqs@ z1Y^XDBnTlP*tkvGK@2An#wt0OLh&$itTW^*Thbetz_ps}l$X!&Kfj@%j9igAYCIm= zPm44ol zV5gm=#>xl^4@tYms<)o$j)x@}T%EIiW94HEarXs%yALd%Jd# zd#%Y#J$F@B-NCI4+3X&d#@Gx_z>fpuZEU#O`+&y@5r&SPgb>Lz){&XzT!q(W!@p&j zDEyUxfIxf53JvdNAJ&a0@FPAQEz&;UwfHceuM|b_z>5&;v99DZx#esF->;Qg=pXEN^_CCNqBj{Yi-Q<3yL_p*9*T6PsMkf|NGlQ3q2nN? zIwHRu`p}U}=e{daa~gBBq{&cd7)YZJ$>2whz4PzWZ4XOgfQIwBAj)|86DhJbsF78w z1#sdt4hNm=%cgDXtl6rHhqZFP@WN@LM=1I8+Ma2;has}{2Q)z=9F&-Z`ySIfI-E3t zsm{?(iFY)S_D%3)5Xqm+>|3!K7vQ7vwiW9)xFs|jIvQn}O@FM*f~OLs^ivTPeRo2u zD8mp>cT2us@M_O*rWP3vAMzMGzd3sV|H9ph^Xa3Qn6H#PjZsUr5f2Wm)CzIGcQkyW zf)uOgS4ED-48eEn9UQu!c(p$o)4Um(5q`~|-VFykz$|Qpjarz%;&S($c2BUM*X0Du z@!)#bv)*!%Rx9;P*`8MY*`_6wyO2Ait*fd!7`2mN=*MN*D4EGP%!p zkY3b7miL8jLNtleUQ?#!CRoPsOwl>}{=I)c-yg^>!*Q3(#Yf-uAV+;+8oM)bADf^~ zNoSD9&1wE)wt0z3LvuEYu>67=Zmp7PJCBZTKq>PqnS@Bk;updUPIo*eBuC8u9d>UF zURZLXRl}bbUdTO`WPFC2hmofv+*X5HCmB~Rjz*59nv%gfJ6RVkD3JQHh$i?Rl%$BB zwm(+>X?21fFM_Z~HawLw6%00#g75tQ3?7GBr8{w-X5BT`fi*oZ-mK8_Tm!Elb+0b~Kl28ioU6rs=jkVI%Noj`jFOmS8k;WnY$`MDz0;unA!T z>VG`M-+A?E8JD^E0MAaMt|V`>v<3qEigBPM6uMrTSCpTVj51ebEEPWnha%TEMt(#KS~1F5SHHLp|Ahs>>!o2_F?OU>F)|?=s(B#@uT@Y}RlH7W zR%WuP(TvZJd%ik};y9qRS%-cL93$;KkR$+gsqrC+jOgd;3CnL&5?Vhia zz=(+4?0TTLyx2X`k?~$X-vw#fdfz(9n|VT)B#puXg>SDowFYbkFEX_(?39%*g<4Qi zUeP%&4bMkxW2xkNLKHciBJ7WqO(Ww7Eh)pCX^M{kea6$8#38{jhkVeb*FCii)IHsd zkcM@7)&8>h$2QkZ{*#Glk*AxJHk*OKFGU#TsqU2_R6?6jZ1sN8&I64nJ?TVwx#M%; z1VP!e^|R;PyCpYv3)MFwUhL7)=%r6$9Hz_s$g(AV@zy+*Wl#tHJe+5ThfOkDiEWpcpGQQlV+G6)dVDS&77s*3E*>`pjEEY2 zU-|qj^~L4d?Eb`th{VZG{2!KV^3YFPM6{H<9Ic*_fg`V&8nwa$yf^T~LF`L~{0g%geS_}^x(Kh5Jz2O%Bnb5%~qBVZV|er(3FqdCe(Ha*Ne zAG;`4&Fv+NkZJWi%bAYWp~l34=g3#NP+E6}en{CFt2Q69#sglh;Fj~#b8g#t((OjO zW(@yP?)yqenJv%qPpXhb>bB-eY;MA8Q#QZrw>V$%aJX%A+Ct)kcISNH2ilb8PBMfn zzWyL!lfqo@)`>XsNl=$^H8lE9O<>)BaEWB z%WpJTcZ)C4@AM2zCv33x$UnJwEP;PjElff2s9RN!*Amm0o3BtCn8UOuMt zRNCS1yM1*_Ua4b`ZT<+U{H882Dh$E@wio(yS8+2ArH3woUoy^raS?MQPB z3Q(+{oX69xXTi6oDX+(EkpYE;nRJD)Y2@=7Z}aXzV%kF?p${o+ZH_DASU#XG=h-S<~?}UgLNEH`Z79iu`e<3M-yXShi{>^8iA&ovSFp?H+o<`Qf^) zo*3wIAP}aL;BGme*UAS7!hx&(!Wsy0ZV6VB9LYgZDc#ZGfRML@^&uu&vNBie^|@>f zw}kN8FKu7gq*v^wBi@Bqe%0uC6PK_#YpV%DjlB=onu6;~30Pv?yBc1NT7`Dy5K>!v zU0sGmW~DwbNV{%xtE#TXdOMIJ=mBCf0>5X@uo%pJyfc2&c>MCB?u=O8TgNKb^OA zw6V#>jC8bI!cT~wpzQL;S}N+1jn~x`Z_@Rwi(^88#@IXOS?tYn^?_b@a$z#ghimz0 z`}(t-rUX?SJt(H?jr30&&z4$xS{Z#8l2~;&V{YuO{2P%E$HpmtD=dC0;_cQ-sCL1m z10|;)HFdHLxkc=1%s%TikS^6I&E@q|D2*(&s5fd5DRs#&;j?(}f3wrK^C;pMiE%h{ znWL67(}C7)qS(}yL}=K89Fj{uR1}o+^X*DD!&V`XYzh)J-M)^SfBV$5iJkToB$Kqf zIGSsAvjItL=O^EnK=spZ<37K`tD|W{Ed6?GD9C!mJUlr8KOnDT#SfSU*+h2p4J%zC zRQ5dSW4j>NZ}c6=J^>kx+he(itDTCp>RrM2#>_x^E98Lx!<)qoP*18-zYWJ5A1Q~? zQz%+`@X7kv=R$xpcj_8`iTnzJ4A|oeL_RVbmRJHDT#Hft5&++!X8kW)7NxvN8IgOe&W#T#PaN`OYDNcH!<)c?+m?$2?%-9_tBg%TC~0S4xEteF;SvPmXFG zNnHH=F^KK8mD6%7W2~T#+KFdVZJ}(YD~N4*Ip=Y&5sy9MT~iH}%X|eKXeIUe?s1WB z>qh{WwK2vbs^L2s=SSeNs0 z>RGL7^-k}b#Cz*YqmnFX7S6G?fY0Su+T7C=0BPnMFkE}1sT&$H5979 zq1*}W!z>Cfu%kiJ&F%L*yI$auORzTXr_woyIQf=_TbqMoWM@F|wIn8AM@n2I-d|Bp zbzYwQ%J=jgDBYbS72$olf=I7TKPYnJd7;{Sus$HMKb$4v(-%t#Xy^whFby()<3Y9M zF;Gqz6y!bGp2k4I@6<-i19^qoJ1E0^?=Idn$X8Oy5^ez{he7sU45=Xgc8fwX zvzQ2kT%HeT;Y1(k7Qn)zVqUh3_Qyc3PmR4dr_kgir#FX4YugUS=|e}Nhys;1&Yas^~Wsg!0E*Ie9o0zW4lmU z{R^8+d1a-@2YP0Kw-PQf9~lhac_M^J|I&0sVfTG~8OO`gg3B1Rbb=Y7)I%v0@_14g zLc8yl@CUE$u6NLD3tkR>Axh`%_}*YNTvnd$AK4pSTi}*1f;eT<-zl@|%&37@3irs1 zd6u!{#z{mwyNAXU$Pe?~YCsw?F=RpCYwQ=AN3-aZGv0vYCr3xe1X`s!*Rzc*A9NIy z7uT0fmTJXnG~Gaa0k$(yuEz@x&OMnCS~8xm&=q1l#6v-G=c+yAq4y=9PK}vk=X{LF zb!Y_&0jrQvyKf5HlJ{K>&nNF<%tq3(CF3q-R5C-N@e+apl;CSE`Y9kzEzGgJ8=*^Y zJHIHA2-rUw(O^h0l}6RPM!1@7eGb=MEgBM9C2uZIF5U7UL7E1H zQZZ~@aBW+Y+J`J|Z|6*bnGQunakfw)-P>S3Un#+PjC@<=6;#B6m{u%4&r%u$(WJ(h z<@QIa-;d5;X=3A{A~pl@M~(qD6Kx)faZ7EYlOPg!0f(;hWysMPxA{R{&d5tRBx}X+LCp&(kE_q ztLv#(7wBXUCtqtGt$6v^X|>pguMzW|!BS zw3fg^d&*x#AsA}<96^DKPhDETNI-CM!s%V4!-HJwyAuC+#df%2J7M_}aiLJQREZd~5u>i0MeZ#7N)5 z#1~1^c--W@)K18R&KZ3&YiPo8Kcq03hc})GFH@=I>-Rg;v^G1dduj0u59SsQ;|-=L zI53guBy(EqJv%*RIB;`ucb8z9Qm#hNU~`?s#Zr)P25!ja2D@M~GU0no=BBBbUN_^D z>0gD$XXfUf$fq1f#jw%R%w@jyyr-NT`L!yd?`~M25P!|RZ?jg@*Ejf;*W^4@by^@& z$kVe_i&>q|$3F5CO?=M=(!6)c@~~G3>X)JXB|hKJaXfgM(_?MvrKlg~-N|3qae*{q z+q>{Z4);Ug23`uYL`RGf9()VDYN41=>dje9L-|r~&4wXRGoG&TD|?Fs-6KoQ z;ty*)yI5AbVg_3oi>(vjXP89OHEuxifAprXi7Q-|DH|1MEWMVw#%0!K7ri(r49|{1 zTDl859-J?f2ch77$Py8$7zR0{_-Pf_4H#ZpW`3{;RT}evaf6cbKu1I}9Z2V8!#Aze zZ-OOn@VW7p)pv#U0c?H`G#$YZd6!)ZGQ&?m!3yyp6kdl#w5-@s$fGKn@U?)nppK3w z@96G$d8~b$r2++zn;a2rN=#bkCow*KlUUoUo~^cws03rxH4p-|TWQKt|dA+=3Ua<4Q(3I)j6^MaH@e!<6$~HqOkd$TebphH(7) z(q1_;)xeaUIL5%Vo$#|Ajoi6ORcQ0G6(DV6vYIx#Q&9;A4@5xx){$FH-WHt@6$y13 zQWu3D4=&Pup}z!|5k9Ifa6O~mV(^vuk~ z!eN8+0%x5~xdp~V<`;(_n_j=;mKi%--NS#ZEdF9tO^L4GV-VUj(N+rONxI5!cXy>5gDdG0Vg*@7|$Z~P^ zazW?#hn3gyUz|KE>6SVOy0?5OB+cn{r3}oVUYq)pGAy0S4aZ;A^WGfq!FZNUJ@&X{ zHw{mWK7P7K!}SPPPV**2Pwt4OJ`p!AOznL0{j{NvL5*3zbkzMQauG6!3&<@eU~Ba% zT=z#nZ2$%N08@v7yX(3$gH>8-Z*OnV>`KIAs|^yb8|@baoL0Mm`u8;#6mt8t*y7P> zJL{jXTcp!%1I&|h-FjdPf19cP>~nLm^ja(cD3n<|c5@SjDyFIg{>R;6IF`;kGY_b9 zo38Ep_pl5bY-c+H5M9>#{B(6&Kh4VH4`Bo(U|L>&s`Flzte~PDA?38Yz70^a=nvIt zdv!_C%TB`<K`X@?nPVlx)mK+1OO){;=%grk0v5w0 zYoFzT2&tEgrxtq$8X(=f&qc^#hP3+d#i4K7LW>9Ql$$XSEK*f~+FS+wZ^iL%oeS-<>t4O#-H&Q@{)06ZJTH7nTrmvI`u1 z*lE{~aL#;K(wdD9_Oe@i`eRvH{O<-taw%NgMoOUGMw_^y(&jz|jy{8VZi%Yzm3BUM z7YW)_Js=ogPW1xX@orB6mx0gCtZj(tiJi89>4(rIJ?`QNqi-ZSaj~%>vF^vn2 z7l^|%wVU9Cv>wGA1;%_1{Q)CrjxAl36zT(>za00 zynKE-ng)0A?&`8q*wgV~>fTzZKYrUN%I>6^L3Yr15|lh?j!mOw1f5*?omoHj0P}!s zI4(mKVFYCd=5*T#@)@Ys;eCC{zY2;~xQ_~722*HiQCJ291Yotfe#Jgy@h2lA16IWT z(a}8=6anwcQ$wFCXqAyzxAC`c-)=jq#2b$moqr&l3dE}B5)6GVC$9DO>8^hrPpaZ* z3t`hK8H4L$al*N<-Ju-7*Z)PV{Zy2FN#lV-MD!hZN6Aq_jr1vQO&_4Q)#ffzES!Gu7oji(i54fF8&-X*0U zyb^`Slp+Z4y?<9M$(aVES7FljDgF6IDc>uAqjsy_?x>XNv>K)SzCzqbSS%!i(;76Z zX4?^E0>le3C2wn;{Ir1bmWW)_AB<2$Zu?aui$>cK*3ie$#+=l=B4PO`5>F&u?lQaH z9uv?QM&$a`^kv-lnd)2s5*hn{qV_97rgnB?c*(2vG6N{i76X^&*SWdu-{sIb+3j!F z{Le$p1)IT!+|779n`}WS7AhVSLww$cF-#rQR7PHAb#L9b(P1Q{yLNUmybk;|QmA@5 z%4<6u^>!h_<^#q~n%H&#((lEF-C~mxZ$WZuB3pL)K3#+Z=wxo%>m)O~AkC?6>#aPw zcpB#fE)kVrw5ExIgh!MN{Wx#)o!tpq@5k1WQNw@yE-Eb%+wVj%CF@}jBnGZ?jpXdbFymuZ>j104f|_|oN*N@VhgY(%ko|aK1nj`(?Y1hhmq?Qz zz^aQ6yf>s}O6T7)AV`hH|I4+*2y^{64ZI7vRj{sTcxSlX<#Eagv(m0?X=($QB{m_f z@a4KDa5lA=&GcQK15Tj_P}}-?okW!(Ke6!fP6j*YS@hjo=h^LJ^bn@ux35d~^{uZD z7B3C2(ItQ({w!|x`@1n5rbfERN{NAKx{rO^2@VP)3DT7~9XW>rR)@k4hu$XWl3Fx7 z*eO*m5+Qq5zr9ddsdwJe{bWjh&!m=f>&(<<8(x>&a9`w!@E2HZtQjX|Bj3;A7YNgm z*@7{6w$cnN#TRLBUJbt2^%h%-k^Y*4r#GLi!#LHs{uo9V{=YYQM!<-aw+`#dv4$N zijk-{y^E}H4p%nTerqDXC|en)N^PR|Ym@Wd|9%eO7!hD{7J`{OFaN(AvCIj=4Xy@# zXT4mJ*hBvJ$HJlDgNVkaRM@9#@NW!%?aRO19ToV{@!2;4r|YJJ%|QL*pNV|K=aJH;Dbu+A!#_b!2o|fNGiT@e9GW+(d44&S%1Fr=NKlzqGg{@x$Vk?m`QN|tnS}S zA(=aXjV?HadW zTFcENHE}xRWMMk8F8DWs|CuF)-!ti3M|+NJWhMh#7GpewUqJ5LH??sy%4FtL+}?P) z1XqPPMeO83182ARdz%}@{uQf4n#v*Ys{%05|6SH9ydTC`owknGGrc(T{(d=4#c-2& z3MX^9;MOD>+?Q|mB;-HJQ`XmfQwX=^S(R~iOSCm7BE5_7Q!0pNP_@G({E~ZMBRs`m zH9=9U@#&EyN&Av#P+aJ2_*f}ZLrHMZGbzyyHc2xbye3`0L3ht`{8#kx)Wn1G@sc$g zsNK}UKeuX?31;{<!2zpftOs7U3-cc`qqtvh`?W)sWlpE{no7dmT{8b9nPKdr?5{ zYJ{SkG!yh&no@W|z~vUd^RMA#Dg1Dj4}V{s962BpiI>?B5KFA_$8oH2FJkwp#1iGT zO(!AY@JWotSZiT@^J-${jP~Y4awTjGeHvam$@jvsH`$B{tW$s{GNVK>V|j27&3l*l za8Pi0#is3|@?TbF7<|Xj@8?&U1h;ohUym%pFT)b1bac?F?=3JWyTMbq^;cPZtG{IIjuA95*?Tnv;-Y+bmHa#LBA>dV1l-o$Iwg4~s?^B~lyyF9C zB9P8E;<5gDa}(bx2O&WhZU5`Xgz1AToThvx3-xavXvd59qVY5KpB64}kQ(A_>q_EO zU~k3cooUkirR4NFA18vb4zu`Ew;sVd38l zz$;LMrQ@(hl0QdShMWzE1L>SLgpIFLk7eqG*Crt^H(5m~tWiSyNWy09j=!d?=8z0Q zP2}A^Ed}Iy`67qpYSg;CI8j?FOk1vpKhWh}-jN-~aZ5gG-Bff!y7Owc5$& zRniSkm#A&?y$#r4J~WeZXs~ThFuZDbR;-#TCdvltSvWI|Dw`E~zuCpsH?E_(zI@t$p zH;;GcHvj^qnj^VBkn(-uZDV1fg)1><41A8#9gCfGUn36>y-%UxPpN2s>#w&AP1K*l zH^R(AaGn=NTA#-!4q30HEs z>(}`b4rWBDC3k|Ulg%e(2s)?F!|+2uOIOf5@$!4yO@&tFVmKZXcmSSJQ)4~=nk~}m z?n=a;M!+wsP|TR2aL8Sv?Ow<|2>6TrQix&8u71I_RCAoYlzQS&U(h4K;!00VA6WD) z0!d!I>Kspv>f{M|6C2_O)eGmyxpafX+>`ZoG^Gy964|-=7;_@fygM=W4LuE%oeJ~b z_EdR#R@PFr>3e|dKtZS0FdRBEVb4>5(ExXx#5UNkf$ze%bq-&P`T-YAE5p|>WjO{p4A)fvbv%*$30U>3(0XM={D$RJ6WfgvY^%;w<3*o4 z&HXK>k>hF3pNTXQ>?6(_(R za8?}&VI#A?QHX)8mFkw@B#&K^lFxtVHZ)vv+n%boo#k-b`uM^*nOWyPw{@NMB%>sS z)5*^4M6HF2jEoFl6(}hRA;w8Wi4s$?Mtr`Kvu8 zOiAeJX-d?xbX3c$C~i|D*8fO4YG&9sM!|Vk5SIqs36oUlL~RLX5Sv6IN@|H$CO(!T z+;(H1A6&o}DU@+DqBgA1P0l)$amq+MqPDmL;kOef z9AiduZ@}9kZT(qbj38SFZO`yATqZ*fT=IX_kXTVq3L^^}Q?8Xcov^chZLj=_56TGR z>PZFI-d!myo|4oI&vh@RaD?WRm6o2$H$PRMXiSZ-I0|&_9}m5Ok&2UQWfr>=azukL zc9K?JzPZ&B_MO^nIOF-o@GD_q;ZX4pIe`W(FSz;m-he*TgvdL=A|Bep`nDw>fQR zQS1YDKKDPoF0=*Sv4g}moa+0--uq=F5E&R;SnfIvTx1g{PCf?f1xAr`i(!z>731R@ z1EveDrsL(3W@*NO?Collxy}@`OZ8FYzz0G^iykaq=Z7H50Zbh=Axsv`DS=uJo0gRa z6pTcFkU_5s(Mbm0Di;5o4A8z81jPVgK~kvGd9nlwz=ZdZJ%_fd1^_G}xe$7?`2i=c zc!&6V@uALTBb<&Cp2#!!TFC5-w$};Wm-qb-0cQ!sUUvAk3cr`MzNk<1dEOsBuD{ap z%4bz5IZdPx!MoHx<$y2o*OiM`Gjp_j_`qPEVGD)jLxcMGl@O)Zf$P(v&XSZsMY%Xi zU%Yx$yL!#?IP?1M5s!NVc~Qi?k3rZ@t;NXU8ffxcZt%9jYNFr;bz}nYgU@B8ZCC{NK0I-~l6dvUMB8Rc2Lysq$NcSy~N^>m_SOA?xVU6RG4l`FR1@|w#f zv~tKlqsL=`cycA}yK4ng{06ZD--hDs~1;SqEiL3?!62WLQkJP#&|M#%nJEnhwv`B21HbWvZ& zn0z!=>9sf2DA%;NRlWYnG>yQ9+{W75$%3Ui=v!hzstlq zx3sOdqPrA6ja5_4ZFwL6Y(`vfbJpD}FxTSIOVDK;6&=0z4lEqp#z%)N9P-&?rDf z@4w8*Tb7M!2dfCol~Z_lu6x!>A~ow9R@@9s1DN@k&DNKJ{$~2%9Xa5Rg&b@gHZaP?pOs*1s7jTchv^W(xCPOu9#8DGrDXo^wX`EswRxk^@Fv+Yb^bzdGVjpOab5tw+ z0q=f~<+pi@o6OC~VwTLsKn6-YgDNZDTDLNXNNO~dp4H?@n-S3n)h90MWP4pa*JV+U zzsK>Ea$oE(L+qE0Ge%+bs-WIo!@Q8ugi;l+tX>>|8j@wyA*a?Xft5K$SZ)vTJMn~j z{RbUsrd+TR_H$piV?6bXI(?FX@gLE1tCqA|+>Ykvn5g(98%n7Tt!A`2z{}4wa;3yN zt;ti+f0h=rgyOv%p*WQCD0ov>Dn2qi5Fl98X0RE8|2vpuy0053BJuXJmtamk-b}|Z zCdqt7VYHy8>^z=i)n>afyS2czo&>9-0Xsg-mpZ#RCC2|J8YUTX$K^K>-@Z_E+@e8q zvkJqk@yH)>rIMj%j04ul4^hBBd#WL7ALTi&8LTB$mnpBKZyGek%W;e7hwXpwSXS~K zkH60#v=F{*qRw|YQ~!8B39VskK9UC7jdE6!99thBnaJK6`Z_VTqGDndQ4fL>o!4_O zJ|$}{Q*rgD#9YHI3emTZjv)Ff6NgI#H6H-1TXpMg!J=kaZI;J3%81q;T!;mp~y-RD{ zR7DC}TeFraFRew+hs5(|-~3J`eO-RWhE>J4huG-u^eu|XXDG@iDG$Fi7>=J8kig+` zRiVws3B&j$ivFSZs_;7rw;Lu(wWpebOXQed zu!E5S0K@paEcQ9}Glw52ga2X96ok8C4S#Mywgly)S;{faPWM00pqYZU>IC&b$3#`{ z`3+zHGlx?ycoQWykPG(Zkt4+|#{n)wtR}3IDd6*qm;<5!CFH;P4Bc9=PNEaNT89|~ z$e!$e7bo8%8URep|KhM{Ps)nu`Q>RfQq6CW<(4t{oyr4b<1wj@GA$+M-v0jn!NItN zfZZI|LI|hZmPTSH5J3=<9D*LD1bk@dYg~8UF=C{(%I#6#(qBe^BMDwx8M#yx~2EAP^>j)u4HKc^TBx z5APdH2=O+#sfE|HqF3(5WC_KIsw7(;w$YHY-)selya(pZ^nW=$m$&U}Q!| zjp+hL+4}P3R!)M)XbBVo2R+sWGC(EpftsD29W?SUU%!UM1BWzbA+qBigiaM8Pf@Vw zrLq(}*n7vv_+8F!Zb1_@<_d|xMrw80i0&}5oGK&Yk-{SxaFFe#{TWBj3o{)3&wT;s z2#_mZ#8>Lk^YDxBo>S3M1m5;mh`?uIgzU~Ys-$wzc&Z|VY}fgU{=69g(!#o>_E6qi z5*^B3lUybA1BL9-d`_y}wlxR%C6g%@JtApzfR(T|KR0*0IR=Mb2D)s}8?&;q(i@-W zu>LvLc0^1g96(9h03&;^%JAeD7QmBCPJzz0h<*BFLPX4}{uhb?=xk31xyl9m6awbhhV=AXBD`>hZ)`C-I{FKO zJthzi*X(Nb5R&Xz-G4#`2m6bS+$s*lFwq-0xA`)G?6Y{t@3KUJhc!u-jPuE$=*0=G z?WZ?bq(UCYX#H_Iz}}37BjzxZHRF%`8?uTO-J#oC#8R7RCBVY@4_E&O={I43vDUq6 zAN@lH|J>Kx9W}k((HWQs(ysOY!#{9)(0Cz!0ikX1e4PK`Hxzy&vdg(#<%Yh8n@z5} z70z2V&TH>(LBG&1n`@lIF$Q3M-9)e?^#8d|+Df;epHAGjhpOL%G!>up_p2&zu@=gf z=wS0dFQRctF_yy_=!~aMPI%MLej>>+I4M#kA&PA5<#&JN zgD<=|l4oc^&xfrb;?dVNwYem=8vaVyiRH|4;g|(Q$VZc*WxbOxHA|%*F^Qo`j53ba z-3`FCO=SC|;Rz?++im#oHQNhAsv`ciOuuK!ATHO2N8u!kQQJN!y2rYlx<5@b$T5lf zG@iN`q8YzjDvnPakBg0+S_8?3d<^M@YB+6MvMqT;-uuIy{n*5OFaG6WetdFZNRRJf zt7{a*N|@EL1!+P_;+~hVaFmLZ*e^6E-eyBI2eha#>nK~9Q4P`2G`Us@TThoT{e5++gB302UE5rr+~w=CZ> z(2zLas^Ot{wC_n}Oz>MS{-faR``y|2=OybE&?b)iQF|s4IPh|C4>aPJ-inu2d=Nhj z_e{(w*9;EV>(iCPYdK{R!0o-W%5j0$sZ{EHN!if`uaw;XI_e~)eVwqM zh1_a6?DT6uWA)ak=y4pk}(*OMy`LegxL(n%Wn@A`h8 zF1Z|q7#9FA(*{cl5D1}B;-Q_WZQ`X;W*qFtkN_fJ*!HKUjUHW~SNn=P&9|CqlgUp04PRmGn-kUCUK{=(y~LJ68Cb=hnuPHP}*6&A!kfAgXB$D-=@ zt8u_q-K;m&{6yIv_a89s7LQB3&5%H84j`HIwvxve*NCqRW$y3t$h>j*9&ukJk5s5$ z^lXd4b{DOoK`m&j7*VO;aQC9_X7{=9@d;`P8hTPq8hMR)>3I$A)t_Vu>N(I1p#%i7 z&D7P_mOjevEK&s(bHrN}iH1kBC4f-bT3Hzb(IP;`htkrs>A!i@=6zMBQ%lC@Xar6_*WXB3s$WPf_O`7!eo1D$zjX|U;k+3Hp3BZ)$ zVZQwh?E%Wajl^W3FJ4u@=q?Lfhbm2PVJ-3YW(k;;TpHXL6zo&)GmuhSuP||NP(ORC zA<{6g^Vu$u!jeWxy0}4#0Le1dTJro9k!u%3QhOY2)dOKe!tZ?eeW?w^XXWT2jTv_Z ziy>hUajXISG5C->Rk5h~`Hv?+(vt~2^IZdhTvNsB8@B`nqzuqT2A>>twf8+B)XiKZy*6^l_ZSgXW@e5#GX_a?7U3RS*AS)1pF<*IQhr1-V3s>u16MVr#SDvw@2dR}v^fR4sBl;vu=Jr@#Bjd-^dR_%(`tR7Jc)crfP=Cy|J zP%!~0?F~pk0J;svnSjHh5E~mCfcU^PqQIg+s{{~Gwg7@g&wgwG4KZwCD1(2ZxA!h% zBUm+vKO^EW+nlT4PUE(D`hD@9aU}f9(K;&WNZ&&i{Wt88PGBCdBr-x#)cAo(zh^Z@ z=eTk(Bq1}>zAV{>#|eajN$4H-zd-5g%v)ujQ?19k2>u@3qsbSSBqFD)?QJ7hSBfsZ zkK4Ta1>HNkt(ky}UxdvEq0@oKYd`ShdmKz{lqXU@xK_=clKhCkyU5Hy|{= zKqc!M7~3;IDua5?(0FP&Si?r3!4=9Se3_{>h4|ww03=2+gU_iqlBl7f0TMbsF@cl+ z_O0Ltb{>#rqmx{n0#FFB8Ptj_yxFFpeuZIJ!&zwb|`N!%4f}r#N+DR0hm5 zIpH5vphtX6EJi%ZgnDmMZQ{*dLZP$gF_&okx>`~^uVvDh5tTdXOFFM77IJD*-+#RK zV^HJooF1nP8@nejCtki);$V<0d<6Fb+W?m_SvT#@T)hoQSz*(zqVW6( zBFldqZBOsH&4V6hpzoA?B0VKU`)iOWDQH>5Q~e}DZ3d7KqehXDsVNl?%RnR%Cs4ww z%?FY}QcMS9wK){_1hl_FM9|BT6)w{8g9R&k=e?a7TJ=j>2P*si`00KJ%y^rdrMob% z^@ldLIBtHyqn>lSa1Hd0=r$fAyfVk+;&_wOL2-r&0a;Uh^*J7ZU?pwh^J4*_Q|3764HF4aC~{5U@Sg&y$T~uSb54Qz!$Fwjb-mPmp2Kk#at8$o}O>T~zTU z0+JH>rSDN1{wk+rcZu_1xu}%BsytNw>_BJP@72g+@1)A0IQ#(Ojo0dtz#GXPTx>{* zXVRqj|0Cl&-3SQM-QC^YCEW-}hjhIQ&pG#= z`+LXW4~7EYwfA0otvTnK&*#CeZDUk66@^YrZF@R{n3Uz$3#$St4!AlTUZEAzi88%T z^XY=Qg$0A4XS8PgT^_*j?f6NWi3l$98Q2D(N-guB>l@B3f;=Oe_298tX+o1MONHA5cPi}y0 zyI5yO`4#>I44pzM4oOh&)9GgWO>t|h7clc_a6SrWn}x@ur>h#>vnL6~XnlL8*RC(Q$2OW*Ey~9| z_D;>8$}iAR2KOH=@&6>fgpfKPvp{Gd+U_#V=pHTfg*xlCkojv1i<+7X|1GVGs{QEc z<@Pee`QdC9YwpHb_D2ef$`Lgy%W=34>}w2VlWC%29+@4|@MmC!AdbU0J~`+4xS920 z5fGR_cPm`#PZJ8;lYw(L)K@`Ti_Mo~mh6bB|E>*uCI)MsD2t3w0jctp(7?NbEpVwiA0gOP{>}M3}F}D_+N(oU@$9r;BR_xm32qZ}#j1X?PBs~kTTEr@LI;|%&F)&gS8!=qXK zJfaPqNYIOh%nK{@1(gQ_3Z1fUo!BuzY4PMWTv^1d7vtis9j?XW7c_{Jh`q^9f5!*>_v zBxn7)VBx#yAP(udp_7sbs3Kl5>FY+65Na?aa=cLqryDoJX5j)?(i8rQ_mk7=u^ngJ z77<#V-e7BBlS}?qTaboww*Iedhn`xS`;FgrzPC;hSFOk)8Z7Ik|4rsrCo#ad8aVaJ zv7tT_C{5GEi7b0;ykWJJAdt+9{eWI5vFlSpnvYsNwSI$8jN@10H=;!DOIO$^XK)8z z{lGA2grB2Y#R_V$Znvszbu*>ST`oVYW+@4p@7#K|PsVk4#Y=-}-veT_D*0$q(BrU@ zCYL?|6}(|$QRhFkfWKb`fzYR+fq2$umm*JIew zcxWOV0?Yjgx1CFVCr*b$40gScxKiP)Wm&@U$IwrMBD7unvCS8!Vk&+Jo9%|O0f$)V znd4R0M_OZR$IZ)4f_TeJY)E{e=Xk8jhRe;Dwo_ed$Qn+99jN?{yIi_c9Yz*{8dJd& zFW|YSeD3<-S?mbL?{0|}9w!|7nkWh*2>8Qj^yCS409HA3S_j7_VYz&pm=rUY5zR{e z=K7ipqh}0F3Ft^C2deQKFY$vqgE4z5YDan5-aKn|Kaz{8_dL5`axlBJ;P3Jy4P7mdl4gcct>Nh7M0&4CA z(>yPfeEldR>V_c6!%Md&N0$Om8)}`$*Dquu?m!{}Fr6 z4*twih#zQ{gdFS^GhM!i_`56#VCsQJ{Wd$B>HON+&=DZZo<|%V!y$BKvp(OOeeH0> z??N}9ad-9g)9?-bj`(aGP>(A-9`X^hpRk6mW5aNLW^$Rr8p?Lss4<<*89ds^9flSA z;8*)tRl7$vJkcg@D0Y#B=yemcgYfuny}S<5I);736R zwz_h0?3dEgF_4OOkx`d7(Mm;s&7?6UG?+P!0B^TDI^?KMi|6USXq3=(D^2|6VmH9# zmE4(Z^LdcZc0E6gwcwb{dY3?F79H}fq@I%}mQk@uzWF;-L{)yITA>*BRTi<_HnJz8DYUbc+`jU_3S`A6c2L5sjU*XqJYxkk_+qGtP=U;j?}-d|`6 z_GRN(d8_+RE}MRH5jq)nWP6}x?pj6M8njYF^xFKQRyXT$K3}OnhjB^7r`@zZnqByV z4CQuFv6F$0emC9Uu)s?o>ohwg=-2GRf?pTKulcZrr;GDEdmnC@U>91TMB{Kfa{owo zh_aK=(SB&l9Ow!Djn>B%UUDq+F>fPx1k`6S642=7;9RtK;2V53$iEuX(W!GjuC{1_ zbHQVGk?CI!Hm&(m?iSxTr`z$W<)Uv<34O_iCI{WVQU+_g6*y~)Fa>XrVvy24O=rp* z_)O}77_|^6C|?nRpKcMHA2&)p{MYfG=(u!h(Y}w#R|l7CH_7=C{0VRTsilcP_6ArC z)fTIP{dMDUZ_T2QT5n&DQZ^|Z@VHDFGLvyNt;Lh7W|#`vL1sxNVVicw*G5KVn1n(|#<_K@JYlo|8qyRCuKs+5{*mYkGW%izY=x z$DczerpqkO+LCa|Lr{qu=j-}r20WEBT#sn&dL z3hCDbgWB~r;9tn$_oSVq?JZ&ke6&yt88oHiOM2^&?yz7CScOxCOz$OpE{ebF=4A)t zdS2Z9%%)8}T_{^_lEeIvGCmgT;W z&5*4{si|QP#2QG2bv>Gzt3A@^bUr~?_i1`6~C#g{V+K$%ukLS_}mt_lLqOVaSt|whgLLfT^`M zs~Zcl{GsY674FI)Fpgb|G`9Au61V)vz1I1=rG{9&8rCPTp8$gR(MlcXwa@D|klk4#DKM>X!IG zoxP@9{ye_9S?lL%_VG=q`41EMU>aN!5KWOl~^2i%g?-#F+oK){K|V`S|b!D;|=*}(#d9-o;B z6=!~8*yMIZ!X74ud3d|}UJyi$v%ja75kD)U$XfmOhdU&&TB#<=rEotQb8gje)Epb5 z!K51UlbR{xTs-Z)(bq-4K-&rgsm2u`VANq#{74!nPZs|k{PUeYg2{+hm+_0+&tJKu zQT5on`|RL4T05?;@?@7ofAMy(23cb6HRRbl+KJ&+i(X}gG{Bp8Rt4{~;Yrx6)a&Gk zpv#HUs?I5hV%9fkHr%A}xQ@RS9ZzRkY&bnT8%?BboHdkuI^>0qd@6s1Y9?jre=>5@ zc;1rfyJ^a}kY`cC3{8V&p4TNxp=>ve!LQH1enET3IKq8$T&m}U4V>@X zK_E*qmVO?g@q?kP3hZENBZRoZAR{rGD_1ENv+}yi|C;;FxvYjXfZ#*=(02-`0aSLl zR)RU^je&<>mD_a;;*WJs&Sk1NgXzsnhhR$FFd$VRc^zgb)%6@qZBbQXTxfaKg)ZNX z9&)cJAy?ADpg))VQQw;eGtBdpC*@x(&*)l_JSX(T!2H(qK0N%jA~~&m)mZ!E`>U&) z`(_9JAL}%6^g&uc)vjBNbmsRM1#<$G{7lK$Gb8A5s9q|bv&e3*B$8VohQ`RAHDJwD z%qdMC5$XaKm8ev$_4!LWshl!cttKrT#OOXGn^Em1kut|^zS-)sPf}CPjC+XwdDT_2 zJZyt0YvQ~g$lI1piQuNPDM=fC4#z@06g{UcgR@}|;JuVHGE@E0^ZFo#Q=~#&xgFQU zv4$>Tbq_`h;c?C(_65Q0&^4{Q$9(|mPD$$|gdli$yNZr0BJ4W-Ja*$b@mU2`* z=8doTflVQ`d_~3Eb=j2s)G*Yuj%Wb5-^ac5mqVC@y?~%PJDtX7BGhxhDaIh&rFidn zh2GM!IhgtC-VwhhnbU)hi5kvK9w3raBqXBA*Bd>LJSNhuTtYIi3nGbN2uXeLu}b4B zs7dB|tKEns0*5j_1z)`66#ETA0=lLjY!B(ihJ<2NBY!%$0wPP{BZWZf<``UZzR6|EPQnS-IZWd5C;%2-JV_Ci7j&eeZBEv zVeOVDd@*p16(X?BUxHBgR*EI>)d5y=w#=wk?4Wp1p2&2ZzDzc?c5!+-`)35d#9G=) z{p~ZeIwEgo=Dn3lmJ4gM?hvd{x@$!ldiTe1yxq=TS!5XDQ$xuPj>i^bwj!@r{Ej7V ztx-UkTsWEKaYevufB7JM9D#&b@Oy|U+(>CRrr(ZKCZ!&Z!;Wt9xTs5EAq7f2(tUrE z>%*^H)=dQVbcTWt)W`<`+2@Z|%i7dlhgkhzxp=q`y2GLMIwIcdKmf4T3VB zrwiC37mu=vo@O1}EVqQ58X(<3440RgSy=4F^_@R-_O{oZeTg)lvCjJzT37a?W=e>? zPgT8rUAB3Cx;)G=q=);TTEL)3Ok5nF*8I4yn`FgX`;O2JoC>GMbOY5-_*{9gQh zDx)*XVA`PpHVU5z3YbEi1c3pyvYge&$zWmHG&oWzSsF?vqs`N22^Gx1>PtivgnO&m zy8#1n*SBAFu{0x!7@#CWO0@kpNyGUteG2&ovn9_5YHuQ4)USd9l)O0Bmr!HYdyrE= z64)d(4fZUSEU82`2bj&yyQ<6gjSY3HAA0Q)*iBw5=kEPbNM!`{gm_|m-El4kP|XA( z#=Xni0d=;5G$mGKi_c!xcla^(#-l!zYpJ<#yZ$76g_G-c z17(7`;Dzm8 zLW!nI3kZBpaen}Ck=i5d*D;`{wjHAz;W-RUG5mch`yCYIjMWwX$pl468rIgqL8d3Y zxtrq&Y}AaqmRt;KwPhE|?S9hW(iwz-U_N`Dx6| z@^|Zc5nmcvS)0IG`|RL3@s9`LUzjOEGBoSllU;1c-Bn+}rJ9+~MrAiU=f%%AQFyJs zZO^VZ5?;EzM2)Z36$R0Zl{#yOqkFr1LCds7Cuig3W5D@wQJvLR&F0YBx?C~cs9d3i?mUXJ>1hX6OrBVMb;wR5gNUup6tqyA@^D0u~0_=1vI z6)Ltt`3FNjmn)YeZ!)xPKg2EUD5mUqo8PiqOv9a)V)qCv9?Q&44AnMZapD`ISajC; z)lA6c*)uarB=ys^Ya(dm>j<;Xm3-|DP4vv>le&2%=2dPxk(V`l!qgGJunj1z9eKP7 z-Fh9o{IN4;4fG17b$M&Fero)Q{|h|}B$i$FkOa%(Pt7sstV=zX&`%RNNE9`d3h zIaUfve#(NXfH=~QwT%gf(|{(33O4+@TWNOgd$uprG0QBTDoYw$0hd(6s)28I*zG%{ zdAIMn3tcri#buKOt>omGF5tvpOwlRZtFzw=T4r=Pa=qIjjUm$AW4FYA<4Fm_?>b?r znWFz`^Y%zc`E#c4;Z|`YC<|&-=`XFyE5ab9QV-fU&#&md0DBpETjXN7W1sV#I_ZkT zYG3?o2Wd)7hNw48dXaUe_N&JyAUX6=EO5~aToaE-b=v2%Z3~p_yY}e2nnP4hdsjQk z%GT_~c|=IV&|-%otQrS=6mrj$(edP2yTy}#~3c5zPbqlz8 z)YWSJWYURqzEGe@F8iZw**Qgf*~;sl&_w>ylZ&kkm=by{4*prvH?N|)FxDiv1_AMTxXwufVzPf)9Ep~t)W$I->#Q4fI` z$$G78v7Gfv`CQbYTzoBrIhbs@{5+!X7r(pyC`6_!>dVRO%du5mvd!|ZnNaH;d|QS% zydv^q7YM!-c8h9l_si~-s&r{1E zLwMaY&ka<;+4F|@UAUANb(IIu{O~(2FOM)#M~iB0?)f{uD8esVD8p9auPaD->-x-z z-27`DRSIVT{|~66MK^Ff4XZFXY78%5*@zZ4=(H@wz>kkDFX zp}pN`UTeM5{c~%D=R(L|4}w0Jv8>r{kD(`RVS2B2EQra}fR}-Qt~z1(ovs{OSs+0S zSi)8NCF6b{^fD6??xW*ILxoo>H%YXsl=8mu)Et{B)bjYfs(o{qA-1h+qmyHZ?&fxT zo>*JDQgsiCDe*ktac^n(d!9Xjas_!?fy(QMYCcXqORyv3GUPu_PPCIzF@brhE#aHS zn<43O)$C>QsFABY`A#Z`m`M(0WMeF-n%|!mbe(o=Vo7r8Rezh$u+Tr0Vw{h-3+pMEkntIE_t@ z;Lb5VSX}COzW+}CrlDgAq6%9%KdGSE?y_rmSV=@~-7K(?DjwzT_pb?1NXk{$x`hs zaUi1>)Z#?>qhjSjApx|yB$#ziu$S*E+=^ey~` z$Pz*+OjI-F#;cXk6XBM8bqEf&8q1YRx0N+8pzqbAEBV`k#|9fhKa$M7*YF6ba3T>wU8_Gh5;0?U|5w1T#|? zxR+WvkW980^9BliuFQPI2hX4f^$5`@gQ}5}=ltsDc9_?YXvYNChTX3uE=AX7CxOzD zz}zvu^=wf1@HpQaH=EqO_M-bfe>PJCaP1;;wN?3w`X1QGdV4BE5A~mfHT8F^9Vk&( z%FL~SJL>Pi7q+_}c3}@N8YzTmS!XOPfJI@Hb+QJTkLP@iX_fVyw1_f&lFz3w!g-$5 z3(=gsYF15IGOAGeL>_dmI#wi1+(fW(Qm)%_U^%; z{eCx5g6Bknw2l+?N^3q)#+xvT35J+dFh*4Z`q)v*gcv!dERbqF28x*<|@=i>Yy=03Y&83cTVX#M&J2kc8dunY4*^cqluHuX94po zt3kx}pP$1Dl^!hC;H}?$9baBXp&}Xag2U&9<#@gND3=TKZm9=(?{?-??ItIiY{Uxo zfcKd6)tnuA5nZZGWd4f?&qdL*V_AoBG>4hjB$#A6Z!HK2mNNL(BdZ;9L%R-jX}4r5 zVtP3dh(0lM6sRZ?!DvI3hm_KO!$dzYd-02QD4wL5qcp*$->W0g)6}|j=`|Yf4#gp9 zI!$OgEH6aw%TghUSu~)Xp4c^I)KQ}GcW-%yt~ynm;Ud!$LY~rnmK)ZAb<7+{mHAU- z%;8Enh?p)|5sMK8R8kkp-rZw<4w5G1$$4&a5`mfNFRv#_= z)FhdV=c!4<`-_n7H~_`r7QbY7x@qwhm%?UDVsq%L6{d)}c1ZcF2ap_%_Nf$aX9IH*qemIH^|6~3rw?ohG zxk{rS9Q;FEpSJF{yqr?G-5?O-c>y3uFS%@bo9y$nBb`OS5z$^A=bOc)r4E%hLVvpK z(NLfC|GvI`uOr*s-~u@))LRlyc#&J&9WC($uP3@|inMgEQ~FhzE8_Scn97{L!NIb) zN|eH^c;V~C8Zq_cT$~736F5!rQL;IyrZT1C;mFKaTM}%Mt&>_SaXDn%lx!gvZaE#y zPPDIwbtyZZW=BI%Ii(DxqV<(|wz7ro7}O@PWcLQiXGPv*pQPG4@Bh&&fpht%_Ff8D zpUyvxrKn_W%75P_&<^N zY(7L_IWX!IoBW?odpe743&7Cj0gbt|;7+PTgyjEsoPYXO%Y&Zv3PED9(aS>q)4lso zCuQIz^!fpGzS+h>`p>Ta(?cOayo`B;^qqZ~Wdr)Z=g8Jqq0Sy^a`rkb(fg8{mkvZq6NKJOP)&%_81b+bQ?j(?l|He_ggDjVyM0vrUu04sO zXSvYoWD)(-R<`vdT|HT>?}Wm|+8hif!`6kAXZyCmehnCbEAni305 z{I$2uVXqru9JYHn@9d(Lx3AgyEA>3_(Q5wqwq=RulS>vJTb;_`z8Z;L>RS(nm+$QR zjylCl-Ge{4m!fsU`9ek^SYt{{C+n?*EzE zXkKu(l;miPa9zAI7D2o^DFogSf)PagjZPa*hrr~^%1YEKMRN`c5)znP+TAYuf`b*s zY-xsd*93l>L%;dq z#O0+HG5POV_|$?N0L_`LDot!{p^k^@TO^?xg?#G4S?U-gZun9wvv;xp%0;SSGByxz3krd9oMfd)kqS#hniqUS7=xnnnh1S1r_n+5P zA`e>Mec4W9lF#h{!MvX<*EVHg1${PC&h#x_x! z%J~1ez^7|`18FBaDO7hj>o8`itle^&)NCud^nDuC;-WgPCv)Cc+aHKYXzK7kJ|Fz? zFk2R0TwMJ1t3jqKo49oRr?U&KcC6vrhf256hsT%hkHvw|&!59W!zdT4Dq99)FuQCu z{Y2jLG%>+F^)yCDRRo{XhdrTun`IqO^Iz81-`ysFJYxMcn3qVW-krTKYj&n;q*h}3 zzp~}wlghX~{&)Zh8vor?`KQK1QH1T=9P{VxhqvE#W=hYHq0LhT4M67|a3N^bYI5}$ z8sh`SNHqA!c0!Fua`)ytgQXlzuFBoyJv&YiSIs-DN;KyXmSqZyhdUpPAz0J|_8M=@ z{(sA(Ht44L?$ni*f;|vZ*0oft5n$6=LQM+eJ6!g#^r*?_c0a&HxNw)XCuw4ms|VFU zb~O_`CxbtQ-k(wQp=2s+9I6LpZ*MKi_+SFBxv^%Zm5rucgOpYB8$(#%Pz=e^P*CTp z^U*{ONXS;a@lZo!Usi9qoV5n!D!@-B5yAn@`A7Zpv`hW<<;^KV%nqDs zzC;L9cz==p?C>`v>F@t#1j?R^5F$tvu#^)&V6GzldvWK(^ybVl!)&BbZ~WL3P~Mlq zHVHbB_>1T@p27-H06>B`{1^PDh!m}twOGl)fcfu!+%5yir2k69zUfBGOsuSIF$eG zFkh#F7zu{vqkY;QgTMWM&HMr%;hB!0z;HaDv9kaF)BGwL`nQMT|^6vW>TAyVM&lZlcn3VH57a^2K`XKsI!ki1o8z%5iJdWG_r;OuFvhiI!3m;~Ou zCcZBtPUt3n8ilhnnvx$I!LPpUnhSJbZs$d%2>Q+r@#^FIg#U&mEp*;jWtW7xzVot| ze2$%0Jvu?CXKMuOoDfL?ocMO{*M~wk6w6(&rmB?5450q|EWr(ozpT{>6Q(Z&r4 ze>{|xQ+U$=g`Ieplu_e(GWS&;2KcD1^H@rteig z(YKdI4_r>bQ_KvCx(DIp|Kg8jxMtNozC%3i1F{+>C(_up0DAC{;yJLCDwOfPPdTUR{E zvFPkb)!0<#hL!9cYsxFjSzsF8e%d*{%g-XeItmGSq{27(L(cm53`mV{3ounr1e1V= z!wNY%tg<>La%o~0p=V%c7@ z#?A$%Z1_^Q3M9~o{%6Ym^^GZX(M*+b<;I|ie^*IOv?Mca1-Vpo2JTpqdab&EAU(~r z!nlH5p)sxbW^pOCTup^<^2QkzT=3QtGoKF`;^MD>^q;`(gZ^^4HJ2JfL1Bn5{2|mDncW=*tftuU*o!lnnr6 zovSkY8s7^bG(f6Bh=oPYuJ#nS3#dXaf~Bo2<#S@?oyY3{?Q^XyC%XlHzI@;0bFH%O zM(F7J{_}S{fvP<*?D>nuU!^ig247I>E(tP2KgYwuoT3s7LR2mm@&4?ivl~&fUT_mk zTIi}A_Bxu>g0?E%?wqBnA};@1G%1M=`%99ff!^@B~LG}$#h233Fw^O@Orod6r1G=qY!n%8(+3rAl)$PkA7|@aX6Jf3FPuZwAp|K zkV(HkT^MP@+{*+UA3`OrPk)}Xa*pl7`PTx)M}~4O5Uv0v7&01wuK4+_0BZrfFtKJQ zz$2IW&e{*A&rNxGc|RZ&6e<@3wM!ONTfSyJvw7>yF74GCa-%T4CEymUS@26j?^U_- zAAe)iDY1bZY5H{bdl=}`clika?62Ne;>1y3Z*bpIU-5n`?RJ=_-;KNaJ!E*>LqWK_ z$R@g8J99u`UvQ-G{*cm!AZhb%fAcX^f*C9rujw&pHfwbz$WGQI``?dB)MTiv*Q{{< zdeJ&y+*lyH&cZV7%$IrA3R8z_x~@Pi)rX(|GRC2)hWNVFG3oqnODPF0VOjoO)$H5+ z2ryB|{ciryO7>MV>8qyAiv(ZMtz%x|iPESLQ=eu7F_rB?vaUslbmO2%Mk@?>>deoW z=g{L$5{fg$ozb5cE}|rR9+Rlu)bXMH^bm;2++#}KpN7jzGO-UPac2{t!5hS5o%+T0 z8*tQyER4VIN0FA`F09mO2_>;^j=hM$q_4YpDRcM!c}j>J9Tv?P%D} z;rsDrayql@<7x%@GEZ6}tEugit^0)eAAaA@P34AlZK&qva%`>~`}wI1&6RG)dpvr- zBY(E-KD#YK8v;`JD%hIJm|X6zPJnLz zNyvM5eMSm#FQ7xn>xxw!cy)cPRcEUQ=m`M#qh4=MLE7$BrEVfn&uFv8BrJU9Q;0{TLvePNIRN+Pq@vDc9Km!~0$6Er=y(Et|G!(64wMJN&Iv%ip#j>mB}mZf^MffkIWBtsY|&(re_U-2zu7%XRKg{U}~98bmi& zyLGS1Dr<#GQqe_g55c7)QpNjO_x3@-0V}-lQ~IbuA8VRVPld%Woir=V9Qm zC0)KR6JcoF*4~m4hupU`gq!kP!r)P(7QZiLxtQLA{TBL~zK)n&lD*WuHcS@!u9#FuT(e|e31aR*x&(sk-#n6x1=v< z59|^mB>_j}c>s`x>c(Qrid~g~O@5`p5phJ8|Go+cm;pb(BLK&0wk-YU0F{rBUyI8L zq|Xnal8XXMX9kwP-`H>>$I)En_LEdFg1GAdOrurR@5#xoWOxXeLQ~8ox9#n_I)c9= zN^}8{YrOCa)a$?#0}4E;F+^O3FL6D6^3}kFiAky#juZm&#oqL5g{(G8oUd=hIm_Fb zp1%nN>wbGZpsM>Lzy=uqC{nYvg(3xrHQN+^uka@f$Ww7s2VTHO-@J4=ZzkKe1OMYx znQ;kPv(Ba0`BK`N;wyI)j#By zJz=I*IJ#j#*=6(lt<9+)E-ziy(>6m-<$A8Ot5|5MZizy7EHMlRl&Yct@XmY5Tq?>u_GzcR31;7rTJmCaMQACqo z=D~a0O}3uxQg-Sk)RY@j-RG~z2$V^~I?8duRr4Weu}!)3VN_at=;+g`Vv{6=Q`bQbljoPTfzYZ2L}i?C^5 zrhjq%3}$%!TX*!FW~=Af?|c>}&T>PE6XO>^eH~C_wcNyIXb9Y!m>B6Ig%~=xfNC+E zkY`n3jzOn|puiE3-j*7j#W#Vtxi277W4_9)+!IIxDu4l8(77-PmZ%WWumX6RTDiXH z6a&!Z8uWw)f&w5;cJ|!d9Ps?&4n9{Xk|pH_e|HBVj#h=iQvD@P0N|6EF}(oDoN3@e z0~GC^K-rnVViHFVka9BA^u^$10D(Imn>p6j`c7U8pX#pd;86Ufj+sqok4S+^>BExq zir%yJ#0+3xf^wyr1u$tA6IqhzUI4iG?yu^MfICH`wuVu+kdYzg-3_f9zHilo+~sn49Wm}ABGI}0+~`$Fm)c5gxWJzf$P_ZcdzTNso@jRTDRyzp4Ja?iCbRsho3o~hmo9;;KD7@LG_sy&> zQV-m1IX?1?vOXT&@!J%_Dl8kw6?5~V@oxD~?c?pc0#(A*DsLf;X*DH~oN0^4j#y&;%rn6x`V^JS0OZj25`?a|4x`o(g4&Q{hGaY(IK!2%Ay{uj33mNV~#E(ZH(ku_I% zDoNMFoG|%0Epe?6nQCqZYryLp_4Rw3F5^MX`iNfVFA?=&?*6H(o zEds-%G5@~$ld-F#pf(5@;pKVnz_QX1Zt0_>7eCe-Yl&#kl<0~{pFMYbk68ucEY}6bhDFuEltNa)7*XIUr(?wd^yAu>Cwt9G%2$gurgl*5wHh5}_V?ylP0LK>Ggz zhLr#Dj^!OL?)l!E-<@CJ{>CUgpi_VCeU)(%-|dFfIfULoD=o5urBs*W=fpx2$U8qwYrVd%5@y${J@x_5#6i+m-sZ zw|JH$I^8+iH&?Ia%JMpra|NZETj|&0`y`#5Vpdd}KIvZItQb!xRpykVo5U}(TPY-B z)bH!Mc#rvhETXWz9O0E2+w%R6ZMB9)9f{fwCQcCCpsa*IQzb4TrDQa;(L~m+hQ=D4 z3>++_2pNIaVn=}E!92F?F<`_2WE_X(ELs%ELxd1I@R)Qzr>5$Fqygm2J|zHU0-y)M zE-zRThv}g7HHON0zbUc)R z9G+8XQXiZ9E$u%Cuj>%r%%Aora+#7Et=xC7FFbtow$86&)nlpd7g}{B`m(K--E!XL zFUU%dpkOe7ieMaVb3@Xl+-*z7uIPU9e)jbvu*_Vq{Ao%&mF!%1lqs||GAWoC0dt{s zXFQ~?Q&g%<|NDX^8^qGsL;5^+%|{kQ&y^Iai0W3oeourJ?(lB=jIqoM{>ZqK7|bjF z!0Vnra^Gy*)k2!6JKcf8*c3}?@OJzD02MMORx2-sN_lP36-Jfh$2fRucP_8wsCnzSo!xQC6>R}nX8gh*z9xQ8&D+jqg z54_nem$S?Xo`z2~WCU_*tQ`&cU@7TyISae(kFQgYc=KO`MOK^bDKS)jDp2gHnyn>$ z9X)>Kegwb$J0DBbDnyx-p-=}eJCBd%nD%AOrDj@0>qJulCRR?F{q;VgN#*UOA@L2T z3!mwBzrfpr2yJ-(rRkJw+p%(+wDmMk=h)vKc)7%xA4)@S&gCOp0yC9gjBFSyP1VgB zUYo(Mc2TP`d0p(!(KU8c`s7t0O+1oAgAyzKO+WDRBOpmywOnez&Stt#jQg#Qj+&WQH}B3}oD6mh^Rl9W)UyB12Pc!zaS44`Rx_c*RfO=et8?=@OIdF^#U!YhQA z4(K%qc14pV+RZQDvktGU=rozt1D~KcnWW_8bbJ77O)GD`ztH%g#~@_Y@mK^yANHW7 zr6u11c!8T+IH%8JK`B!NI>+Gm@84a2asI%G8~To>lt-`5l$5P%Q#;!Msu5wj=X38= z8lD^}YqZo*QNzdQ=NsSeU)Il>&YWJWLpe@f0%cwWFMs*g6T|GWR<4ZZ zg|I@1aV?K0{fk1sSsbZA+oEds`A5ACtMZRn_pg|q;~p3knnp91L+FoAs?2#RB(rV3 zU?X6KH_)Smi?z;OhJgEuU6IhGG?Fx6d__Y9K|b``0>}BY)2#gmk6u#=s1O~FR|zHj z%wReFrL^)KR&=V4YcQ@cMBltXESfyG_7X<~mTpB>!0lBN|3NZRpF9ClOrTKFKmoNM zqJCxy<3F{4^g`WF?5pFI0bU0}#YGHV1&}XXaUSklonZLfl5>=w15B)^WM20!!#g&m z9=$HSf{WiNsa~?s>ypuLPk4Mw<=P&m&Q}8%hnKcLZD477QKt<`Gsa)t=yUF{GD+A? zuv!gcp!DWYjUJ|_j5yWU3q;ZsL_M>(udaN+>YzNB#ORBB;{o6>otHtn{zy*{lC{PEoJ<20w_%)Z#CG@J-@iD&^eU@Bs;l)fWDbL`4>h2uGwErTXyaeD%8FO z<=u}VemWwcMre0=s72S%QKDJz1Gf)89>BQ$eeLw`Y}IQlgT_k$%Vso%*HkrA3>ms} z7BE$SLmX5$uzouSHQ{t+cYI6&J>XHU-?k$jcnzEhf6XgwifFwD zj+4(C9u6B~Ct93qb;xE;_zN!s%O&b8zwviX$E8a~RoX?~rV(j{QJPKMM9MaoED;^A z`qitVG$v3C2#(HfdeiYFt zihA`!LSL~*Ht#%d`&2{gym)GEVm_m|?Bl#Mr{mp7y#%`kdH7XlFQc6KZP?_)N&jbO z=|T}su^X?BFJGv0YL1#{=Ba8N@yEKJCqFJTZSrxdk7rOGhtq{}D@_SG4n*HncUKe$ z1G_1NDY=zqi9=SlL9Nt^-G_o!;dQisC0L{We{n@%II~^9Ug9-dV&#f$%b8d0&rnENLIAXy zYAmtU{9WmoolD>4;Ql-V<@6!@foGaEW0S;0VIEKgzuE7e@DO!x{pduV75i{Z7W$Z1 z`m4}am*xqy=_`Ugu=W1yF7Y*q%H8PPJ|P225k!ht|lC-cYlPvNvWe?-UDk zGCxmtUp_iao=fj?MNA+$-?SAjE0*7ljUWtj=s(m+;on&xMu0ktJ8Uf*0d6I9%J=2* z?4l13Rgw6E@ETDsSaFZsR6J}*P;^rwp|smfdR2t7VE212)>5LRYb7}|f0S3vr?p`( zSskWW_45f&3U(av;+}h%y_ABe-eaD;D-W-9CQo z%ojuK%5>&FSA~PhJo^QTG+~9M3#h&tuA(-ma1;~3!24s`F0s9 z%!eAzzi*L4kwei47g7o##~59Qyr1`Al~ik-8^N}aseAKiITre(IV!`H=lrtef`STt zWTlh>!=cuK&F~|P0ZsPp0zF!(A?Sb|uS0=u2K;mar4nTc6i|8F2WrW+7PB+WRC1Xe z;9>$4%rrp)R?rLt8)}bhGleyih+RPedieKhzDi+ACw?94ZfgqbD7?cUi&;>ds0!Ur3 zlPxl7oQWaD#TK9w@>MDca@oR$;Pf^AdsAJ2y-73mzph{PZU%N6CmDNTYbG>7`Mus3 zt!r2yL6k2^4bN-~+xzv4g7^<>`L$OlYh`>d{f?kpM<;ef0x^tTCRuOM_ihyoXRxks z$MbZD13@J^ApS119x_e)o_*$3vNE+n7#`^?e)b``O)w_3tZeILzi0cES6%h1W>9wF?-S;a?)wR<>#m6!^shA1LPvks)||)p zmJX)ovwF1aL`h8v+8J|b%=5!@Tp zx7Pyv{gGDR0IB`fBG5kuntbk{ubRf?k~vQu_jN!#o_ao-NC=egKKAmHuYluRP&1VB z3v_@UxNnR{7l=I3^YOL6;c^b4+Y#}v05vuN*c|0Kpdc3w40{RWxg3AW^<-_F(`k#| zgDnMfxY|z8Rsr;_Nl;e0d>mOp(GExwvwPjvfYhMoWW77M^3_j`i70JBSA*VbP?`p& zu3Zx4dA>bGEEP-bK05of^z^ns>umf!o2Di&B=`q4N{2AW9D3bPJy7|dTUG8*bAGA- znJkOFZuBZL8U3H&5hN~HTSZW7)`X&&#|f#rbtI$t19GPN@M*q;f5iuIS;;a{jDfeu3P zu25w&ds}7;6f~;Js-_t@c^qO*JBT7tMG9PE9po6&TIKJIZ!bJD(MB-eYOz+SX;61wpn z!}Uvkzp#2tAnD(ETSO^sbV1WIUiz8LMaeHrU2)(#Z#xsR45#xMx_Hm}M^UsvU3#dO zFB;z|1yr5~cN6~yF!j5+`=>Ipu}5&Gu(c>Im&j*Axk^eDb)Y4uFl!)0T9#WnZeELm zKTt#dmRXsEXqw0>;`M8R(AY$wr%i;=s0IK5{tu!Me1PAW46t1bUxy--)H}XnTU-$M zVxEjftc;#_Ok}n#M^RkXW^Th8KOyS>QRFS7yo7#`azyc7y*bbZHRke|H-wW)hXgnw z6f6jtgumf8e}Qm-T5_owk@&-huPm-^Df@VW$`)^xN_J6Hz8jX33QS9UE>ewop+g1q z?WFD%rhF+s#uzx-1C-S5SMgx>KT1c$?>cb)4I29`n0%3}{Q1);tv1IQ)Z#+Yhe8 zQg(_C7Q~Uo8ZwKU8nC8V9r$Z$dhvXJnJYz8$f{Af#Kh<^7A%)nsftjw?gyPjzwOy-)wR8}L)V>sSXFQOn!4-P|_RlLJ;Bl#n-2 zC~HYK^2w~ucr20s8vAdd^>>e`1Ic}4kFuYcfZ+l7IdN&+mt!AZ{|ofDf#}!38SBiF zy16^fap)>d2$7xy_zt(9cDDY)P5rTOyoi40K?gsa?d~X3tg;h5P)~m(!FohsLfPVP zSoUy)GBIgO4TOpRKL`t%s0E7S-cCAKv6Hb{8quj3!!V=`B>rbeCM2Wc5BE~+uUV|R zIA&5Q{x9GykO=7q8{jhB6K(x>4}k#@cA|s`NT=vxJ8b+lsej|zz+VA4lI7sX`fW^W z)qkA{{s5LS1K6nObCeJIOc0TOmLmV$nZMr^0+>EZcf8E_AZrT6{$DH25Em%;(K=Be zhwKE2Y24hsu{;@zdTS5WVDk4${(f%Q1%3Bw?6&yr68~7}zhe7eLp&A%EE8|}`=vie z#otBLk@OGo!xI|dQZpbZoBxSW*I1C2e_PH@{I;^NQv7Xd^A}w5AEyI9C|Q92?970K z`qvb|0+DlYz97l|CIC%7A2$0RvJN2DI)agPsZc^b{8q!CTHnz9KOjkcM2JXIjNf#b z7cc#U{sqtc|E>i{uT_skCSO)(8TJ45E&nx&j3j<;@THQl{$GmUG{3>N z!!g&yn`<)vX8^zg1vSJe*?Dk?4-kG$2OS?j^X*V;n*Fv-{*M#spJNLNg3?dRe<*X` z2C88|xp=oCGL8GUd-*LHK)?L9KIr~aL;mln!y-Z2W3~bw=V#l4Cr5|RAv*!DVfFeN zV<2G>kT?KXoZ4#U9(@271_qDS*t{DfZI5kl%4VP;Lc=+6#JERK<8dYEo~+d84WHFY z?AI}5KdXhh>Jd6Gq+q9CEL(t>3dae5C}ABv@_eG?N9ZKb6Lw{Z@Ewbv&vg>~O^ z`TSbQPTHKIO`E7w+Vl#JdZ;}i=+QHh#JmHX1t3KAV=UI<`==Kn9e{IiD?JVO6H3Xc zt+;7FsvQZ<_zwn&&@>>Bh(G~Wi;t_jI|9LY>ygdDm`+oZ@dE}_4#+=Zj;{x+%^WZm z7Z*E&->`dHE?)8+Xs{(QI!9MmPbP|2BmE|wgQrk9_SwG@213E#?4F&m6sA@&ocAB7 z!|-|Rb{5U!i1C{6zZm^r7D~j&0w>x1kCZ>x0X47L;m9wloWMVRXKyp=qdV!GX-)O3 zm`vgjvX@b*mdhpbRk`Ba+~1iC?w0+YWI~F_B?1JdYlfA}%K>E?n5hw??sbnOPj$mA zqcpM>>ioDJ;Yv?m$qxHloz+ti@-O}vI1JGI<_gU0o^jTi)j8cA^1OVM+>d9sT2KrT zo;=+iM8-lozdm8wvUzZ^sc$1muDPup%bYN-o?qpACNNjzl(NfmaNI5XMx|^~u6?vV z1m^7G%)!YCqm8_BX7|UB)dnTZt!`-elr`L20iB$QkdO+7*dHOD^2sAZdBtokEh|$u zWyv9#p2t52Gm&G3y}_;o8FK4ti$JO<{i;vc5cj zguPTU-(f*bJook!bV>J#mZDESW|fMQ`QmA(dz9NdwCYNGi$lr+{aq!N(dgp9i{@7t z-;9g--6TQySFqCE_7Io-(6zJWsnwp3TlnoY*sRV)_4QG6z11dkKp~OBvsG$q*WYkC z{u}JgQpq-M)}8ZS=8tZMBq^ZmVKtc@qgo*%Jh#R0{M>uZ@cj|d2DLb$IizdM=^3Ky z?LPXb6(;6aw8780(rMt^{5f<6ao;N!}Y!R6_N-a{tiG=yLj)ID(!P5mB1<;FNIAV%VhH2<=2q(FpL*U z$ZLqyG1nkCczBsu%B14(*qngY2XKh@h!?FCXO zJsq?BU*Q+udQB2VxhgZ7ft5YDe+s z3>|)5Ia`z~;dP6D2}%30OZx^q1wwspde=o6((Xe@OUS2JZ`T; zOxwBQOD!l{z(g`FpGG;i1BAp!RpwGa!l91R1d<>Y38UjAs+apym+vag=;z?~Rv*T; zt0yW9QZfwH9v1Wzr=K1dx6j^@z-VxLw0P(%VNE^O{pKtq`$^-nHT+b05k223i95Wk zXNOfwE^kDS^J?3jIrUX#WPx~6By5N!gR_$p2gxlQHOS5X9I3kEgfYcuxCDHfqUz9_tpuWz zeRntZ{-j7IFl)W!bEZ|5+p)}}c#N;V{4ZTk6OVYkiukU))qWP%1X89hN zqWeyOSgEwi^fZ6f^X7Mm`1^N{7i5DYbF!435B|&u;i$y|z0LDF>&tJEfRi~AjMRa^ zTCG-D8G0uB9WjY}@t>E0Kd8z+ONean?J>%|klwU?rA^zv9?+lFF9w;4`oFjT{Q_Tf zaQK({_9}wo`8Oftzbuf@(T>moqx z{LamMr+<%Bv=90}OL3eBYx@NL1)$M$@(;dyn1YnSac{{W8p~2n?)a4DY45wmd+;=v z(5bF(KZy3oKf0WMNk{x~J|7N)&uy>&GqKQ?`k-su!V5aWZ0a;YW*M4VwQ0dpS@?jD z>+0$acb!?vs;F$T)5FdiWNw!e37}9gPE?}QuMIMfw;S(G=d#a$95EiV{`aJ_1Y~Zv zTW))5tLY}`koL>-WELNh;Ygl4L|mWqYi!{_p!uLqW}qFCGP3i_A>R4Al&>hcevjAg z77|JiOEh37Eu-BPRtHNo9BO?`tH%Bz-zV^CV|#BV&HaeWQPHyMe>vyx3>RdZ&o(%I zpM-v%Q)}9LDx-c81SedqK{Q$yKPpj87Hdqo0jvAnSh{Q~t4@zRW!R}wmghk5_P2EG zn1OF3(nWyjR-(pe(37eCbxe!X^Bjs1k$@+3w7pEhdMHs~FqRCP)wl>8>KiLIo}bC2 zKk@1b-MQRtj!BPahkTVxalg4A+>0NvT*|zhQVY*43r8D`!b>bJ9xf5@UcaBqtQ$1M zVK$ejE5SDYM6ggYh#0P10t8OslDof!ZT$S{%dEP*FpcbYu;lR*=zwB9_Yd$naz9fJ zskuBq?Sra+XvXBAuU4CH@~Y49d3M`RCKW%uY08=+7MWqjoP_iT9slnq<&Ui#2eo0? zR1~z))A2mO-}&gN+@}8Zi?i*a=#?Cs`pEjjmG-B#7%a~UhPlyEnQQq3@g>y7#o{C& z8_bvXR!#H~EI5nJsSwb11gzPGI-}Tc*po+mj_`JpXJ=vc>`2<=Kqu7j;ip>&A3a>XrsHSG1jhc3|cd=ghD1yd4qwCa`j|%~k64wIQ>ooyX2k>#?sA%CkximjdrJ8z7T$dU@GL24CE!s=88VVDqDHq*DC<_Z^`G2}e!U zMPP5%ioJCW)mW1R{be(FWYZ`cwez@saepsK_)>-<+OT{n0`ci^3@VcXFe6TTXBr+cH|M|3rYO2!UpL!O4nqrVDr;r>c_3iXFuoPPlvk4BoV-dv_cLIsMw8aXZqVG?x+pxF0|x5g7U zTPS$FNHFW?aw(0z?!(K_O;Uwd4j+1oIkdFm%a=8q-O;7qq9pZ5<`(d$w|jex9myZy ze3CRZHqL4_p@)QvI1Ql0%QDC%d!3aNmLtQ38^~k}8`;Uj4y)ob#}*-l`t+UzVQqlV zUQr$|Vx0$vk6Uj6&-eG7M9ooL4o?hx&rjJxM<#^)b84bxU~^LvXSxKJvh7-x+7?kz z49#oZAL5rqc;L1N<36C!i9oW3#|o|cQ}Br0-qP6DWK?l-@p#`719b(lSMn#@7HrkV zcEYU&i^k2DZ}fDiJuf$=$16fOSrQwNwK!qn;6$J8@9Yv|q-dzAX|_2_&c{9fBH``p}Bg%Qj3VTY$tQ@&c==y@x%fVr_boKZv( zIv?~4lB@8hqya@rN&Xl1cV#-|Wd~4@yt|~rgmF;c+tfaZ-fF+0-DHasRQ>*NO;(&qR0Gjc3Ek6EK-N(oJ9evspUY-$q;OtLvIi z@FvzazfL6h_RUbyQ%)eR7+^h&A|FP@sw> z)F+dqvG_GiWiWeSGsP7t35)))IzESx3|Q;ChKtLqbTEawGIlf~1-wd=35 z1e-Cf7GCq8Px}X!@EyM4YpT?|lq!2Z*OrI5ma`6O%CG@>&Aq7eJ$ zrKJMXTTKLcvF?K@EC;ksoOufwbqTJoLkFt{xyF}eFpoU36V(4q9)JEjU96Y+F9;=# zWgW*df-j(w=8VqBs-3+T)*Ml6g$U!`_WArX9{nrzBnm~!d)%tWOV?HIOkAp z&THkIp<=aCZ?I%AXRiEPp+@y?@>`}XO-_^VKZ(4+m(_y>r^>g>i}0*|dsTZ>Cg%3 zmLEy5oBXi%q2Y}>i(iK~18X`R8zqvZ=Z$}10Y6zJzT#3f66Njpc9pLSyi%f=*b92k z-G4TTA{<7v{!CURg5;A}1Bhp_NW9RHkn0J*!FiH=VA_5G=u>jyqka74#V6yk-^DO5!A0OD6*vOFfzb5#!>Id(U;UF=1gC@q2w9A< z5J2%b)$=2(I?5(brrSZ56+jB%Ky?{gR0g4WPQKT{F*IFWZf>m+pn2Zd>|z2JoBKpt zD|$=$aI}%&%pVZ?_Z$1I3i|3Vtop~05kZ=T@H;v>)>|(Fb(~&(yY;Rh0Hu38ed|x& z*DVzMI*v|fWpHq?v$M0m-vspcKh4aof<58Te(wfss4VOOo(0gowg93Ic*FwA4wu~q zR573HF`X6rcHOQG6DR~QDT3a2iQe1~b^`pcS6;+W??G@uy3MrQ?^iO_D zd}hWDQPWpG>Ca042hGz9^ z=T5ALp@iGh3j?Yvi~I9~@N|cdLWQw)v9}e*i!w*u1&d?%Fu?~)@# zUDDg!PJ-nQhNrJ|cqhCi+ILXhEqQ7&jiU=wFq8@A@X+6fpYTA_C542^i|f6@i;M9n zDy=r6nruVuS>Pze@;c@n!BujZe*Mh_|fa&ZUi4T|W8=Sud7Pr>Rt09hT$O_VFxfO6AQI8fh&C zK^j~Y$g!wWA^qh@kQZ7k@Y^m^nRVlCzfGz^z{-Ki>(TkTZ!=w-E;Fgamv`B)!&8!Q z8si1}3LH@qS^V_au20sFVM_XfyabOno|Xe9pQa0@$+ft-C7D@HB{&?h2hJpa9PKY0 z%9jgNew4<~;C6N!fn%bwNFYwXx;kjBanBn~9Ns44fcNX8(D7EZkEecfe?Q-8m$T8; zZ68N*w>1^|!NE8?0XAunmxvGvrlhn~-s5a1 z;ytNg@8Tlv+aBN(Xe2BQCHO%R7!-%0Q+<>$-vWehpo#Nw`wPVf`yZn~Mu*#(I`*0H zDTbQbPliQc0w?F^4R|FXHYz38IBbF$?&3s*+)j6pJB8}mp0z0Gasrg-Z>fHA+TQd$ z;kXoOf4+$?5k~c`8{KlU(_nO6*yr6m-5&7z)yd-QN;!;H*CFnNc6B*Qvt>r*yr;D7^RO3{k*iFZ zk8@~6bjOZ}3nDHOCdSZij08`$uJx#bwvs!;EZuz+ex3d3 zg6l#Fj*!?+sp`#q<0NGeE7j=sNi^O^-Ao4v7e%Cg=v2PoVWbh`v2s@35V2)<8|&4n zg4!qs9o0(G`{hN>oW8{$-`<8txVddBJW{SiX=z*ujPfsjWJew(a zB|Rd?hBh>bgYw5yBuogDq%uPIao+JWSmE&TZ{Z_fGeClTxhDh}E1&~~!3wnf{r&yN z1A$d)-^d8U;3DuxCZv_-P=oXE60nZ90u%=WSQuknmU5kTV=7?UXf|Dhz9Z%USVN%R zTyP&~%8rwhqi89n;pTfAIE ze}e`VYPtBvwn5W0+OF1N#1F2A)v$w{+cOs6+5g2 z9x|5c(eBO{I)Y?7(*Of9Cwv42IC%$zs(QHqFASyjUanVRXJrerK z=ZGEv8&ZH|&16C5F=qZbe#hBaZsrYF*2ENcNeFe%I6o4%n75~o@jCa^h!u8q$knG}(?{Rj z)sd zMz+C`n}OgmuU*H?X5wEqH)nG=N&{$Yi(J4Ya&q;NLa_j8k;Qhcw!Ni+d(G;1j zvj*+MUc!9Aoi^(S@$S<5~uy53(oaDJo{KUiKI7spzaWJYIh)yYu0GqsW=H^*juLZZxGhON8QxsOaD8@Q4iYtI}w_^{jv-(WCG&=2eornzraF z&p{N7Atxlj!nJrmxPxpEz=Xp91>!-BY(?jGtuw&k$0(1_W9rzC*}@Mm-QR;yFX2TI zo%jskowh-iwXwNLr_~e)Wm&1;8-_{ux*CH<{WlaI6&e~^yTNvSF!r6CARvNyu600A zQ56Th!jwtp#!jBd5o`B(!bcAY4t^;C-xC;8!0;}4Ff@cpY9UXKf^MljeU$}Kp#+A4 zNV<5c7DGeJ+x3GN%TtEbCT-X>?BKwhJZm&PlL>4adxiM`#e4a*Fpsjxy^ z+5I|t)TkqFtRdxT+)J~iUj{$FrkT9v^}HaJDQdmK(kevG(a?Qq?^YOLb|V|o12SW zjQWK=8kL>b8w)fdoo4lDu-Ie0i?xUMdg{ddXUY$U{>(0$X;xB&m-u80e&a2L}g0ej`AYlajIs zz;@*X0R=Va6rj@*ktkMy^hjn>YNCUb6gy;qHj$34ai`4c#49Iv-Y6f>!yB6SXX%Jnt!%9nAD;BZWXrL4OtJ(pL3c@IDVzc=Cmx;Mi zP*Z4Q!|HnMHm8$FtKr$qfpUpZ^0F$&zF?HPg;2AWE4d~R9d_&BH`QHVYXrKnP5va`PwQg@m02wxVcWHYV!J* z@X+(ZS>I=4nbNqwmVl_o&X3VF zCI$vQmZtAhQ)o#mzag*zZbizaL%a-o+uKecH764KNT}UQPTtzu3K%WAtU#p%@JEGK z%L!tyHcwn9zcR_@rGwpeZAWIbP^wXXve|E7?8m?M>sMj37Pdhw+=lqObSDKb_X+m1 z5;qDS!Ec+%JKMJ2``89D(D&Wj$s6Bc9|*ocAktWc!sNbyG_T$9N^G)6Uia6I=P^%t zJHYW=rB6ZiPAK@JiIEYw+3t4+?6OrsOPi{`i`!pmU7VhdJ76RSwNPLnjv)EX0Z8)z6Z9(RiVQZJbl`T50`&GOVM4)8 zGlG`XOb?zXp%`I$cc%0eLaxjkt06~#ELA8}%#s6Ex4t9z2D5;m~iqVt^pS31< zS_;Kfk(Zkmkr5?~#QK-kuw7c@YQGryaNM-gG`+HYdC9atWc#pxd4E5;K+|bUPK5qZ z^xG;XFm@LHV5TY@CBlGtk4`_CV4jos(i6Hg?0}sOCq6oAeRt!b>#McN3X#uIUe(|i z@;Q%l*gbAK_pvxAtcp_#K^}cA%OrvIV}~7Daqdm_$w?D4sX<{A`l5r9pFap{SIg^; z`MH^cJc9LJ)n_nS>$n>(VW%yAb6mZ%SZuBrEsdP74QKhp<)-j+*IXg}=n*zZZ8N=6#>Cd}EHX4ss^wgX3bjlFOa3EC)d>sX;Bloib*UF2gCgi1`D zAKbO3hf>1}T)h#8Ur&!X>&U1&`ofB-d3>oCSyu@`DBTjy7UHLd;|`MO!5}H zUG{x%_*ek++g+4b5u#h`5O>sPKi<{VzDP(3`PdDc!6v(NG-i6^nJ6ID+9DkEDhJZ< zofNpyv6L=F9&OO_lt-8us9Z?1w@;KDKJ`e8k!dcYSJ!ZH)tlwbU}*i&a8CMqdra*v zFQ%MitLL!vG0Rg-rTB5LH{v6pGgY~(E_~uJOAlG(_*XL%sxDXB!eU@PBfsd@H^%tyGYJ)YhJZIJ3_Pq%%>yq2anrheR zaIoP&kbjQx7F4=DFlLXke8c&ItmQLgC@`;GE6SuRB9$xL+LBQlJywbAz<@!#=3vjx zc=lzWI4u}q31dG2O039%%R+~6Oh)1BmjZ9IiOU#P?VBK68HV|;Jz4Z}zGCI`>Rt6o zOHJGpUs0+32uB8sjOFyCd8&5U_%$z%7&;ZXxtuz+5fn0*sF0>X;%W z5s_ZYMKTU2I1Y_HR;xL`jHYb1+=KmB_qNLb)Prb!Qox#cchQJ}mO0tG;?uO(O?#oy<)!tn$9Iy=$pgDMMR7 znv9HkeMrVGMckOhJyChja>cM=|4=?sA(ECk3r)#XZ^be9w3jCGlX$PBY&i>sHtwLd zd=lBti0GMRnjS3j4#nH^V+@RvkR};nqZG!h{qD1I^3|n&b>ed9f>*Cp7;M;8x2DI7 zX6+-SvR%u(2Hz&o>5`osV>Dp++1W?xL4QVr@w}0L-x=8SM;-Vn#5a1_Wqq;n^vxT$ znGmcOsWzj}A7ef&7`?zte=&>pyU|0j_Sj&fi9B0^q@wwWYG?$R-L~Nuq5G`$WAI~V z8`SGLlGzrl%M`u(8zHI3A_f{!C`LNJr@B73b65**4)bXSvq`vYy%8F1F9qUPoFFhi z_RNZPK5Lw>z+xFD=N7fH&~vrM!^+-mqi?!L+PO67>7F=IH-MjaRCa%g(-*g)sy=#n z?8~|CFsq!9F7OieE)&LqWUto=CNm>tF@~r((uqZGRE{nr)9Z7<3lzY(-&;C*RNqN5Zn=x zAu%zF<7r5gOF|YJCaSb~(o1P9GT{-neG02_zThNLJKkUO6J)3y9unn<3FSmi7=NCw ztmKxIG=&$=QLsY`8>jeS+2qJDn6{Y7W_AW7jLYHBZ^v8Qwu+SS^5Vr6m~wCs#KJ{x zPO!ytBDGdxTYs@xKOjY_=S99=AIN(j`w{UR#>yfHj!eE^%z+ulXiX^VZgw#=OIE;@ zRSoK9cmO}uKjOXnL$R~1eAken(ov}(tYofu!ldAQ@?-wKm`c`HX zk&5Pm$~DOAgdhbCnHr5{xc5>$`?)=TFcWj!$f&upDr+(|TuItCH-Z!JinolV-a=H?F!`S=I=jvCDCI)c1UCFuma46KQSp zxs%N!{jf8TA_XPyYeFd$e^Hx7443-` ztFiQXR!e?=6(9WV{wROTzExPfR)b*C!Wvw5xmDiArn9afwFDX=dv^WD`v!yl&rD23 zDs2rBu`pT*B46iO4PO5WG&w-?F|Xa95wPp-WX(ZLX2Z#@7FHcb$MXE(dl~<$oYkFW z@|0$)KFW4WVLsv^e>>^ONUrT9*7D6eN~KlfE$w1I-1dbk?E7-7{P-ybQAwWSA=47m;3<$*8pH}|H%7#dgp83>DEGbqHOqH?^p^*tV;mK^ zA&$F`4ip6y8f)PP38=f0%T*vS@Qq57r{lJRWxiy2mD{kGO5SLe}QWT(K~urI3FEC>UqQPJMi?{t}Da>zYXU2HCxtAanv);Pm{&M~Lxx&i0yzI@Rcvp}#+|$`mJz|z#Z_5dNqR5yjb#u$}95h+lv+C`BQoF@I5>%>rCN0b_ zRhOEtxMH(;6EPSlSA#+iUd*57NLE=;8prcB`EpWqdFF9Y8htxWud?vSHJQz&eZ(%0yzQgJx>utL?z3b*aw|r*#bp0!1&& zlIH!zaX3vd52P8>MUUMvBZyDwID1YPhX+HV-d zEVQo{q*{t5e^RQ}Ec%-U&Oa5~tTf;`1W z&)2Js2h+JL%~rMd58g1^ZG27VF+e0>rBVA#g(d+^#Z?M7s`Q=*j|CekR1&c6hco8+ z+(brZcLfDBIV0?@@H{SY>^UD$dwPDx?btqXld*=yWEGROL2Gu-Jgv&l;uvo#Vgf6Y6A`-jAsm10m^z)FcTfqdu!xcG~VSf|@MCD8k*mH9RinQ&85PsOl+hknsb#!u!@R! zOw#X}Sm3RVW%e!1XVzdi)JInIWk;K(QLD;k>a5J}9-?@V(~Z^z2t0gW5MPHqmsR0P zO*5-E_#)lgrSsh8xe5Jq=EU^{&pVp#QYV}2t}XFiqy9*42#B(GvdQtZrK=XR?R@9A zUE-cz3@X&4Rk{M{Vo~;YcR$!22aFb3(@U-5gI>M)Dzj}e*fmNxkc|F(gi1+pvdGC| zN(3LjKnU-h^pM@!Gs+TnI_*@182ZIE+n(uSlht~=!w%~kYb9x=br zPa*FuCF3l)^If-vXG(EZ4o1r`C3LB^S|DNi9 zot*Cxp%gxuO?E>Mi2YuF{(R!&{hK{+p?6-lcGx8U>bFd#bE{|4xwsdV0rsq#4CV!N#wmms<>aE9M zmM`62xP2P6-Hg{UO|Ig5c~W773~g*Z|#q#bBH$+L8&8WN;A_&ulDsm zBCc*FAMD!uKG>&G#cW~`sQGH#5+mg@ys?D^esO8y<5?Ivsk>RZNkJW$@%E(jj>-?1 zWvfjYW(@a3mn=A=0A0@$j&>b!et65n>$$&VlNz1>ub|kmO3Kf0u$n7vf$T>>%D*GL zrU3~&Q==kc(ay-POOw_AHMavTP~SDB_L`l>?(_D}5eINq52$9Xrf22SK=T$2h8%4u zKx|AVt<`fYkfTlGGAKx_s!yeS^}*(L11x|*yYpsQLV42cOtqHHinnT`_1&>ub$r>v z>BhE(GWIpEX?J`p7C=m%2Mv3I8O)t5UvBVN`tl;te6sFAj;wxTBQ8a`bQR+Hz}K;? z3Lo5SWT%16uXN*qsm-p>rQ;;L&U=CenGzy1s*XF>Cliq*LWP^GX7$Kl!e>CTO$~ZU z@*trhnqQfaiQGrP`+L8s9$MTe6E>|eZTY9 z9dY=NVOc&izdIyZ%V(l*ig`Dty)oYHec8nVu%(mOAA2^EBu~b zaYyZyrn^kxiLNFxC6KhdPwF^)-Y=Wc{F$#@V>wwVo!2LbUa53O_kG7OTfu#~7}rna zEE=`OPy|YUp)QQlIdY7YdW-q-z6JZiqLCwBPk$auq<+?tACt904!9OnJ@uVL>m@5k z>#-8s5>D2$HSdXbxO!qWkoyKhHAeRz+?{;U=!RMp^!LhyX02Dw$~5a_B8KXZZtkp? zgZ(~VyOJ+!YH`-vC|7DyXm4CW@gu^*B8XwZCiwFPWfsy6a-8KXik)Mj;7pV$b+gjo ztg(GJUroyl4)PW8xxErb<`LCJZ8WjkrjV!JVA=g+ts-7} z*A;`J;%aU1Rf3Iv!^8ofC)%?eP1;**1~xXU)h7AHc!UccL(WeR4^25XE>Id-av=r~ zg*uD4(mBD;Z--|OVS*q%Wo&ct-t1>igeE1KO@|rT<`yYaM&vke^|)yzlx;kb6V_|I zE>W1uSv&AROekG}bhj*@h%mIX@A#1=_CxvRY-geE?ii@Esu@uJgMWe`&Xgq_>8)Xx z?ZRFxbVyL6i}@BB5er6(^#*mZM$5)attE1h;LhxtZH z*%NN1`Gc}}%NM2Hp>P%Jb9`ouORc*|)f&(4X2gYDBzSxtFJ7a|&(6y)BT^WTPHW4{ z?K{<|_noTT-o-Km@LaOn_88KeO*gLod@>dh>F2*WKB>ldbNBHh0|RVwG^z=$(>@0j z`am46Oa3?YPjFDr`eoDlH$-Ady^x~^x9Y9=3N(t%hx46^6{(lMYAjY9hk)H*(ab*( z*6`|<=%G0&ISk2HAPNSK$RciQQI!-&{;eFvti`$nQVR%JW8llmiGOU1FT3O5Sd!|?@LIgH-)$iFIc zBoZj$2s~SctEKCfYLBi<6kDX2D-E&OXf|tG9W7qn$J7K$!)3R71r~yE-@q?d2O2Y=V{oNDkOWNdR?m0z>UNc_fjYk0Ho`qzg+VRB*jBy{J{ zTc?(F_%5w-6nqG}PyHG5)f@(Kq8CLZ3NOa`Wp%0yBCLB>M)PGxDCcZ8Z+QXA_?*vs zzo1?I`~OGWTL#s&d~3f!5-hj|2<{0M+#Q0uYjD@#9^5UsI|O%kcXxMp_dD6y*=PUX zbL!T4t8Uf(n5@NIb9VRa9zA+IzX$W5nVUO-G<;iI1;Ioqw>y2qK-ZdOA9zvE@>SX< z<-F^;@n&mmi9aRJGkU!PrF$VAnW0W>GT9i%QCHDyv@(ChNuvSEj= z10;@Un7|y|R^|Fj3+ekBw$sFQlT>+zf(dK2QDE^>VoVw4PZK8du)x5SFXp{@JWY?O z;6M>Nc>mA0xz9AWmn^zx{jek?yp#C;0%6JQVaO{!6(n(qi9<;(*dnfgyOaE0q(Iqy z`v>In?csn^22R>z*f9SDb{nf>wc;QH$wH~>$@OTgRB*!)&?!vVUM%%Y+O%M@KRi&pZS1FNMkYz29>^k1R6E5Y#49q+55O}>dzozzQXG@q&h(1Op zkwgza?p`NX(41rk`v;5EA1AiLf0f=II_kGWy&!|!N!LxxCqHWdT}Y*|#lME*;SS;+ z+vO%wvFd7T;!eqGB6oRC~hS3w10; z1?z_%DnAe}Lk-3-6exO+bA!8hjycLGMf7Za_}IQi!$p{6@j`E*mZ+XgNlDqYa_v6B zJ3sxNYk>e6Oi|WyJMj#A7~V{iOt(2z>S_xI;VHkAAZ%c2CT;kb^=iS7?yz_ciA7Z` zQtlDif*tMjPPpNcL(FZdWaIJ(wn?(`{&}-J=3CjCxQwtM5O~iCB{^(0d4?7^}eN9}nM88(_mbJau zo_O>gJp%eAg=ygqIt(IG0qCt*;$ALdPHp?kNuRdNoa((VTASVWo}#-qi3c$~tLgf|<8)dvdw zn_RM8ec-Xtf?BLF-qkHxH@YGFCqeDsBYnh5oSK8GJNU#D$26K$=TPOCIX|rsLrXiD z+*j(oK;~L=e6&!3d@hj}l_dl^JRGVcrqGZENA5Q1&0eAoTv^0y_PQ(}lOz zO3TV9WXNzoecf=s$6in2k_^c3S-jY(u6n|BU+?|Fn8Ogh8g6OX(S-umR2=ZsEt-wm zAHyw(ZZl3z{PDvt1kXVM4?EGrXs|bC>UEAoKhmG-B~z-%NJv6I;vylXFa#m1 z&P2zcX=5C8+Gk(aDL-MQ3&9>2RR{@W%b3kJ7C7fBurD*+g#mT&d)qu+41O@dQOKOB zxkG8LSO}JN*n=aX&~R|J5=hR#x~9<4AXDP0GkdFy-baX8Q(Bp~A$zqtMt8ym-nV6~ zn=&*cuG7rF7k9CJ^Z*oCb#cVoU#AI2;y|q;t5&FV5t0tCG`;MeO~f{<-fZ>9H^~JM z9BTaF>!4O^z5+IRQ&@H)$huPnF@DPp*2>W;3>IhgqKXzPbvrFPtpOHX-)V$}Wt7Sc z5pMvc3}4T%R#%T?)ySnb6_aADqQ&w@F4w*Os|HChjrjOLikMH1`-{;)u*vCgdAJ!r z0FV2&^^lb4tpUwK>Z}{>2ydNDo%w7zI#%P(&FyXg45$16;c|y{{vu~PZ>*{EwArHT z`XzCTpQP0x=exH$wVr7(>6v3#VX&X0RA*YnW(K!n_=*%P=9_U-BI0lOtyZQ&ua(LOm%h?Rys&o)GI3JRwrpRm(@(w zTQ<*XQ3o9HO?`JGv8<5ted_X)i)ape`kr+JH1|x$Wg^+Yo z;TiD#nS6yDIca|7Pt)dG7k5qdRcqFDhoKH?$5UALvBmR`=ki)Ja6`%1@rpC^3v;Xc zVKVtZ@HU%s1aUeS)u&tNN-?mh@L9UhGSi9kcC$pK=IOrZ;nuOTyu39DwLhBw$MJ5! zg~70wRhrw&oYWT{ghALVnI`uNUh5I4r z*Z5Oz1;T_!rq1=zZhxkLuewmeUmqY=Y`xsp(YHaq_=Tn7>%?2%V+Qd?s-mk45*vh? z>NN(gS$Bsv3C+EKk;D$o2{9&c=~`2*F|s#Q;+L2)JyfwZQE0ObafYw7XySEy9xbaV zU^;BAVzCtc#^%CV;(8$Xb%#o|Ne|cy-^y=q8jcJL69e=7>k{s%NxNe!)83q4PbP-twtLRmOZ$lrNG)d+!n6&z$F%8*cd;jA*veX2AeE#_vsiz@E~1 zF54BxYgzEh_;Atr7HF18hrI$OPaqzkq2Wf(b&bQNz3ckK1dQOd4RsI^)19-59s84q z%+SaE2xJ4cYNH<$Z8ovR9B!B%KR;jIBjF%A9!~lc3uA|qd>s-K|E8R2ETHRY3H@7h zHPPI^H5a6~96iubtLu|Oq>jw}6X>(#>n zAh2RJI^^C(ANjzQ<*w**J|>?J2tcL2ZMD!oB{CI<)O+G2pePhd7q#!EH=zw;vbpK5 zc)lEX7f_T6fir7M!Hb2mm=JR|1i{cAsW7O0u?PKm+Sy?JA&!M*K65XHi)lYU7A5H} z{fKZI0@_Y}^Zgpsd8#4F5@$7Co`nGh_k6W!>y~i|UMq9-f{>G=WeXJs90(OQT=3Ki zXT~Cs7;!|q+wR`jWbahUJjl^nNw+2Z%we$qbyll(tOMlf^2L|&>-KWI>97PK_|+r* zKwB#mdp)ED54@8m=cn_W(NcaWH=pTkAGPAdv6pbMyx;v02+5$@Rz^rgz|c{5i7X?> zi2AQ2nR^&Ft1>yT8x2cgw^&Xe8KsqN5^=hfV>r)9$kMX9x4oM$ib;N+$$TLrg>crz z(Ar4gP~C815R^#jTmE4}(1}Z;F|?nwHCZ=MXuWaW)Ny~qy>9q$%y<0uycCR9L9@Qn zB!y1snl@^?@_-X^Pkht!$~k0Om7ySv1-8E50o7uz@_Ajp`J>bO6i)lPmNL~(I>cwl zIh2Oe%_A|%5PsJup%ZFiKk~c74qN8!*<5h0Rt}pvSld%~s8>=N99$3A&glqLRzRFW>JLTX5m!}3bIq1o+lqJhPMgAZW@^7C@Q&_U zaE|6k!g>H{L~qK_Cz?{pn`^aVM&a>BtEC|mH11dRS7=BT>LJ$jm2#8AJNodh3ep&g zHK?ud=cTJyzD7TdpS$a44nUrSAGut2*!_?t+mkL^6g83c8%8ibpj9h8l6{M+z*v;f zLy|LEs9HgB?c+F2nK+eJ9Dxp_NPbdfJVuWJNW=+Smc_g3medp}6X2evt6&BkP&?$_ z!feK~x{RP6Oqjf_9v0K4h%aykR>0i^zUxy~#Dulq^alY~$Sh{cl}t&`RWgCI25^)mqPgRnPrBU;c!Y!u@;h z1V+HbYbw|1JAL>+DYn}Ma6^tiS9k|}%?5b>m4EII$748YSIvLS3 z@EsqAT7$foo|kQC75vL+3E`0fIA}9({v_ir?!O)j`0;Q8KqE!IYS0|VC_pk9Zv-{k z{lWo46+5tVW>t2y(!h)J`wst{jY5EmM2nEEZqR?>V18I|8T`)kXhA51j0i&M$#okx ztA_Fs`33?#E&pFBF+gC5;5n-VR}Qmhr_pAr3ZeM0D6Lrn`{zv*#8u1F0mzm}F#!@#oUnEk ziJS*MtbYxXR(J$||G=$_I%eBWC?W|$cP-s}rtCPzCtSXHo^E0fO<@;KO(G=ocAFV*+=PZGa zoC{?>VoFAAwIKH7)-pEMHld6eKrOS196kN|I8X4`$b4k>q`~C<{YW1IxW6jtCJ||* zORe%F<_0kvb>{1^vdukxJeCoAU?UsH=3fm%T(z#dUGiR$;!PjrHPt6)tSCd;m_dX3 zJt7{3K`#?y{yIG1gjDhu@7m5`mhRjmkifLszwMC_ojC3UWQt2Vd?|<^F>lo9dLyJz2qGT0*j-Nb(l@4v49j02()5QU~Qj{}ntx)QmE zoAhB}BL@5DuF12?Qf}>TWJ}?p2Mv{iuBc;_Na7H`+1fxX%fHBkzr&s|+3={=(Eu|Sp>BQl$^2SG&vxM-A+9JA5Wr(shT>{<4 zvv8Y!Oi9582dRWpRo&hdP@7Tqdakj875At@>kC7{a%3zR@{Y!NOyO zVu^Xr(E>yQ8|Flbo*4>ailmFgHyBN?Z_XnzXyyC=YQOO@TK+$|fY;MX{8JsPRjwZE zQ>XS0robsLQ>sB*?hN?@_*lZPV&TS#`413;;iUoy(88>|CyY7(JS$Qkb?AGa(lmy2 zWfQT*M!tivw%QN{;y3p|DcpwS(M&jEBV{7F*8|RKsBrs#4Xv*`;N!|-K|f6e;E{Ve zon0x1YJrlH;UE6YR}Bb9OYMc{4SG_{QSw7;y(4?QVUc+&F4J&A!S~Ek%FG7qVCC4u zQQTWqJ?AmJ04IkXQsvog_4KRA+|O<$ z(4lfUMlw9kxtBFTvVT>&asv&$jmO>aCm=aRhsvsmtN!L#VQTlNlG!181AjnI+TZ0l zQocX)RgFH(a`#u9ATpr>c1<JMv{YBblSxa9>0DIatSjSXi%d&xuA4wg@D}o%*f3 zAFbvEGEQd7=rXj3LSs-oUZ>uHu;`|afql)gqqNgYHfR$jtbyr*1x|xc;`X;&d#gO;;4RSJXH9V#>(v_~17(@H+lR?JHF zf-@y&l=?a!3*=?8ROh=q?QK2z&Kh}DMX7vutfzhF?kX;B#7lK{(j)%~iGXQ&H5PJI z>or{9{sKO(EtVKukVOI-pWvaA84wZzALjpzjf8W_68xVJHR{NlgYN+>E7;wgBJ`LW zHTn9H6$XJubbX#VW;r^bx5TK_;*f9wtLL@aW$~F!W{d_9NdJyWJT-~Khez@)Rs5s) zaKdg_h(KT0O0k~Y#+Fqll0YLf$~r}K)<@7!n1GZL1mw}Y-GVG$EP^4Z$!B&@PPcu> zAOm;7ojWP!Pj|mQ0PF8tT1P=74TSpg_OAsq*G019V!Y1^laqNPubw zwC^%U%pMmk_@8C(byn^}F0ClzN8_i6UIYK)SP(oH1q8{#0r7SM;BJAhEfNqtJLlpm zJtry7=k?FHe_i6faDuR@7VL`MnNoID?%j5X7aN#@)^?+zqg&`1MU>SDHxRxCc)*+w z+$gXptAl^09MsuZx5B(@AQ3~q03r=4IAoT)0`Tz-hsQ56Wb!T`PvJQ|nL?cZT0&QG z5fC76p?#2YBVM$Q+-r!Esb1KwE59J#;(%n!kfT608(bwm7_t6GOMe%6lN$=SBP6rF zOqk1xJxuHx;vwEvfLnTs7fqk;QTDi_T~H56{1@K=m{f9r2osSsoH;~HR^!RY0Ena~ zyp7y`Uv?D%^k3J1#D9%v@k{9`|DOIlQ}MZV{%IReAQGiLf?p%h`R8x&iV*O){(Qj$ z5X^dT|A|>%r}SVkk88o#HtKB!cVN`VMj{BOh16Zem7B->XM#Poha9B)9Tl8y2F%fab@_jN zI!^X_Tf3h4HRGfp=L!GE-+Q)*0DAeBz(h1)#H_-22ESM|3ZkWlK4gWu6hJ#>-zN!z z54RFCzq@hU!uT4UL>5oN|LYDR7b=+eP8c)|!WR!JrNx@r@bllTruRKdkfGHs&sln0kOTCy_%ZZB4BqBL#2+1gmkX1GtHeY?Iz_z z_&s>C6aTxM)nwtb!N3X&-0z=XB~p7Dn?p4oGJrxJ5*%Rh@03fxP4+l!L3+bM11`*8 zod#X4`H=TlU;g#*S)o9yuWyLj_n_+%Ed(w0)}wf_b(c=pF9P%rF=65{tUfA}?Uo*JL*4cAz`ZW3lSLrr$fU zS(jutz+5IE;$WpNnr2DHzbVG1sU#;%`9iWUo(bMd`PxLST(1#4mxqKXk|&o49xH1- z;OTRGe5_pt2yoj0yHNMLbK-_|z;L-gmO89<>>r>@p+-w1VC)T8iT{!>*xugu{U8!c z#Q~W3$mU919WO1+&9ML;17-`=uD7T7Y()6@o{6^xfLUarK43sDH9I?7I<(mjXxuv9 zkEioN%(6ROLfS%782Wm9i^b7^u&5rkFD_ye+W`hdOMv--lamv{8vwoX{A_Wep+FH0 z&^stps|%x}QNJ_;V2*C~`*Og$Ma(}$$5**Rf6qSM4e)daBy!sJ)6>&WELVQpzG(?`hb9d zfQ$RG*%t-05tI+_t=&d+1C}73%iL*6bOytKLmU_w7;OjO ztJxF$LAF4F61){?YRIq}iv;NRMq#_}Cr<)^@9LTYcA1-7 zZ&JASTeM7<){eH1mB^!sxor;bmE$(Jy>%Lz{eH}taQ4N=`Q(GFeUhN-vuDug0e`*>gg|Fn-Ss5w zWx2MN*YfG?E#`*8rE)dIJ83JK5`36?>g9m@y$6t8j_(_Y`v`KQ?9asA&G(z)GXiY= z@0FQNm+(6mXgrc?AKo*vvbbE({!As*5rs>D(91>?RpLtbu8eQ`Afh1Ur~d-$PLJDs z=Up$csyag4FgCdYVo`>^?#eGdhmk8+ zA_4>S#d4|?qRdtoNzZb*Cu;K!E{YQrS1R%*a=$zb00DN;HYK=MHA6z0xjq4Ja*vLi zB5th<_MHYjJ|e9&^>WMcQl8F>zB+D`TeTJ`ayFOagUjf;Rr(krWD2|{2ZPmqqN_@*2NWA6sbBSDqXaj}xV1$3do%Tyn%TNr(BN zgr04oy&2qpTmUcS+x1nd`58O3_C}UpjH84X9jEEA?t3n#ge9}J4^q>|M$xLg-r7Lc z&f)P!jr?|{-VVxx?F)Nz4ueHsjckP-%SzAXv3bxTTqIJgfniR)XT_3?_^-@X3sCXA zcbBfGjZf$m3#!x)nslZw!$G<$jmg*-xYi!QzjJGNQ9yQTL2o$f%igrn0zV!h5&|SR zFqzGMAdrdhhw^J|Y8vw{y#W*A=O-ef*<)j4YXB$;JQi}{^R_lNe7XzGuFlhG+@7GJ zp`pE@`a=n*n7VAz&qjTTOeOL0%DEEBgF{1Q3NfFR0nCniqr;i;)UWiu<-FiljI~b* z!0P+5^78CwX}>)f5Adyg^#P0tSwwJBHgYpK7ok=V(@A#`HA~{ySe$zF#V`hES2)qWTNPw zmn(Su*6)JSmdos5CclNTruG1M69w#9U7c?MIT9jhWc%tFKb(gfT~glkBLfr}H8on( z?Kn8F1chRosh1d$WU(Kp)51hPlti&~!9QtMz~qMLEK&;Lgv>cutX|@!T2JJbU~Gg$ z*6-NOL)PC?-L?b=M=e7-kZxXx?C4OH5cQ(!leB}tQsC!#WlL-ya)dqR8nmz^jx3RD zj>5jv2%t3^nctEUQi2ra471Yh)0xrXoBL!yFWDx5AeW^-krS` zy+Q0O#+r5FO>7%9oBfjuNZ?C!Xn7CakPHy|h-uLA5OS&~gN$g6tsmx<48OzRiea7N zgA)_+qz`T!zG;dYVxlz*if=xxKJO)FYT<98VGPfxD-SW;4k`QiD?0L%oP`(REM%iF zOPF!W-D3IdhuH(BD4k*pzJJ0V{x{%m6ggeYuY0d?A|T_-rrily>x)gIJr8i#z~8=2 zhXN)7*mgN0i-DiyUcEG1;N*wOeKC|+ssW*)`kx>lrN$VfUnbgjF4WcHyi?4j!HboC zn!SU7aDTi-6wmr5T@HxzQRQY^9{|on9v{MJ20aBp0x6U)PypOvN)-SWh!R%3m~#}( z!sFigWDyLnCxYjv)Si+}x;-;>29&>bi)Zb~_rHU{-2 zk0a)gg2BNpGyfp%CwaUY)p$L|y6MAEHuxp4FVjWJQkAF2NNV{LNqq09p+YOaQPxA5J}< z^;iaOk4^=p5RopTH)Y@e$10?W$Ny;JlWgeX<$KtI!wgo+1zlGy(eHbb!_#wVKZ`oJ zsSL_(@-TWgdcq>yIc@h*>^$F>=H}*l@)#$OsFBDfOd{P)0jN3@5rHbtAw>C}wgjdx13Qy;`#;~P#MfeAw2)|@8SgfID7K*}&lPJ<{no%VgWjc-Br#f}Ru zS^x>S@?415!tlv55cINRS3e_!4X96*=+$8ArFlZ$Hp)0wWR|B1ZR~fQXGSIw^{}%z zkN?RA0Mv*`7RkO!cEgRA@HdoC50LaG)21)aPk_-Tq-I2JGOH~G8&i4me=?DlQ^~}| z#6DBT5PS}ezACPJ@4?AJSBC`-x8${K3x=tw`KSy@|`mui_qH+>hzBGaA+BF8j- z4NSe^q`{}+yi!S&Ol>@1hsIYMba@D{^(082za{Gq%~GZnFTC9s7U)DIk>|DPJMopt z-j`~4i=|72K?B9IaB)+d0RxH`)eu%%QTegX+E~n`Tx=54*5>5iXYu?Ka+DuNZy-M= zE)Mb?3p<8{wPWMEE!VV_@76a@=+E|GH~=K?+|k7l@3{D`aWRNxmWGEqK@j*c%qc#j zjO2Gy7DSw$j^K(!D9lO$4U=T5HF7-QWq_^gM)yFaBEq~prDrdK@Yp;tOvbp$UNI0G zUN2`i$CH(vUAp#$7kRcyCG(85xQqAPE-B;rmX}ir94)dqw-Bs z*98rJ!L(9GL_ccTICwxX$Xh+7VBNKJ(JIk;FL^YqZ5xS68)uvX+%=n4{d(!1`w-n`$UNW^I@0k|Ttt%iew`oLt4jn&L(+^IVV>=#Ggz4{?` z)yw2hYR#CILcfGGqXfEgez>q$Zu}r8O-n&geCBa_nJmiNoCa960>mag=om7^THV#1 zFwfK~d;Y`(f0FMwNZ7!%u>hS($7f`$J>D!xCl@X(2vt^5-WN+a((jeHZK@7X&^T)K zMh-)jVQRMpA{9P=S#jK6jrOY{&^D;)zOiWe zUZS18c<`>8XZrh5K9+IFyS9sRLPfg@+M_0q9bCSK+n>X0hHQ2dWouY)9k|Y)&I(4p z9nV!1V$EVYYUyWFyMO%L<)6B9%*JJT<)$dK0NjK7-rcrlAw$|XVpD_GUrz@TOQlGO zDsl0LP50asvX><act$hK9A5U3+wQg20>IuF3jD`!URz>fBGzF& zkhX#hj$pmMy!56e;!L><#FSXa?d<3ZMCG#uE(}u1Ah}Z*8d8Fy*|7fnHE?*+&Qs zwQ~6AavxE1>Z1N0+hI&F=MUsvhga^wo;XKDFT<{w%r`6#zdocCi2;40ed;#!ep z(_!?51$q(VZ1{z*3cG_#5HTN4G9;IvK?($SzDCM6)fnzBn!|GW_TZtjem~-&izxMC zx)A;p&-8GO_|YYhc35kBjPjQbv$i_Kr?cs`Bizp)o^`wOI5OGn@2qo=J>ErYX;JE1 zKa_HDRE->uB};oICCob?c_`$WVobi{lj6Z-tf}CjFf{*=<65Jv7sieSQPafXe){7$ zMC~yC(`Op)!w@57$3_<-`fw2+n-kmxANhM~tg);@p_>Ff^c&;Il`h1la95rBR!2Ds z)Zq}~lp<_b_cNMW_2x9JpQmQFFKBtX6&3A77(q^9DqF)654Z^kw{LEorpUvbmQCSy zlV@|LC!#Z@gelTsw}r2=fRl0nshwplaV3p-*WkxP0UNekO>=+yaa%@_!Y}FrWZob4 zR2b_g%z#b#blwQj*zzHI_5S~vJk{|(k*8c?0whwc1?TRsx_NL$Hd9iU9f;EHSv1I*==gsAk~7^S!2qlxfCd zGS}6__Ax?GZTCc@jEi!nS65e$z|_->R;#740W$!w$K7GL7RJVbc*wN6fM2WDbI>)-lon_v3i4Vj$3y*5OUqO}o0z1GIoV-`Tzux7YrC9q zT34N+>!pz#@0P6qWxq*eF^IK!K}=h)@*uh23)PWbpAEgQV88&|PlK-Zz5hhtu|y@S<^-Lop5=q%;aRMh;U#SJjtdeoU$pjl3P_$jKcUkBbZ#){^Y(++kvigNtXmvYf zEG9t#gPZ~~E?4bf{2Da|YRm+n(MqiIsfv(0#{7h+aW{ zH=oGnSVIX7G#vel^MtD+mS7K#F)OlySd;D)-jd;u%N7ul-g{Tqz#i@9IXJz={JJ^Y zUr4*(3ziuwa`{*tK{$}!E;6_-5wTH_PBq7Y`Y!$BVP-DV_|TgsLCk^O1tq}|@yCod zU2HF6Vd&Q?G!Qu3zlw$2f;|`%4|^-tt!ud$4_A~gev`C})k?pt%_fqh4vG(<=tdEM z;P`E5^}pRgDH>NLy%Pl=e+Ob>W3EK6rGvx%Cl_!L_*~Xp=1fKU{hIb*q4n`pe6F-= zuwYCXSN`8qXkd?`g;{rLgCS7xYar5tqtz2jO7@*dLsb>DuH7q?;$?gsYup$(Sp;dX6odFaCI14I` z(TRSw&Z9CiR+Wsi!RSJ|B)ONhg#}dxBcv+xWI?JKBBIVzE{phEP#AsCs`*BhD%0j> ziHc@Nik@<5!XDu$Y*LAzEe>anqj=qsPX%NC?Ce^pde1HjZ82)*1ekE7F3arkEnJzK z7vJ8|UY#SMQURjE6dLuG)0s+Zw&tLQ%SOhW5cMghwMW5<`WIxTkMWkaii6|Fhl@GU zDyrX;E#~x6_B$$e1wJb4wfhWNVfmhaR4=+OL1)5jx7XJ=@SysG*4k&KC6^PvdoCl1 zaqNQ>%8cM@)|ILK;*^eF6K~3(1=b^n%~4P%hy+DUNTMGHPGHUgH?)b(hYkz|2l7j4 z^xr2xk7OX9iXGunyvTbtg&>|?odM4b%DQ>BO4$t$pYSO0K}6aUZ;=p|xyLskQbQEm z{w-0|FP>0+^iPO*VJ~k$;(uIhCR;Ca_ASMVbS5E|CGaun@+Af=I3-pW>dxn;+$nR_ z@#d>5QOs=ix0gtLRbn4uIuXK{oNaXbAiaaB58Llw%%xYJcKGIhP1kb2V5^iMmwp=0 zI3hG_JcnUQ(k}OzNu|(mS18&wn5xQ|t7TjV35lD<+S9fhJG>qo)VLEb1wR=GaH;#z zj#D*c97Dt75S(?~q!@^j^le92FF>w{f`USSfw3=Nws%gY#;5~sl87j7vmX$%CmD@p z6#7z9CNk9+FU@CYa5OZ#A|Ee#eJBu;`)p~geJJ`30GLuda7M6PQ7$LIv0{u})j$mN|B|fbhAaa4A7rhzNPw!Q>4qXh zlTP(|UmR3_9$v212>y^Dx%t`eY=QzE#A7p znrNfmskUi~=y6u1IP2b05dTeZ6pSw%TvF=o!eFV%JR#yOEVv9)m%Hi)`@J_q3U<|g zT&2-lfF^=g!bu+S_G1|pqx1TTSBem@k zLWmd|tD8$&*vKdQoA9y04c>hWGZN*GSOXQ6lgj%Pn9+fmQr;5r+7sD9eX%o2yG~IG z%Rk94eo3Xn4&iQuY};#Wxrlvz z_WkV@o;sE%LiSk})T>tE6}B{6`ZcTDl|=uX!QVUN19b(h7Wn@=rdG+N`2P!2i_LT2X49o9j^4pd)<_l~H(Gw1)*A@N4vpjD zI-V`t91Px%rZ(Sj*ZJRIwHUY~2`{G-bX1ys9ovrCExO3!017l2>jk%h7>4B`}|~D)pqwO@71@Uq2qm*SI~L-p?$>ne~KE5es@ zT8cB8+%Unnu|v3QQXK=wUy7`k$ny=TJXcJ%rbq)HN`B66 zPuTYx29V?;zZ9locaOS5GX=jvS3p1yDT{{*OY ze?eMQL6_uCw&KcyZ=|8J!g<^qaeJ}D1&PJ)`;+?_f!&G5?$$^O4?GX!mF!A$JGvua0WHXh}wt*n1K4-1bw4V4Bl1v@^<~Q^D(Ls>8 zra=z~`WR>XjrNt>wk1QI1*{>(KLi>m{RQKmTJE<)256aT3Dg_QTdJa2N_H~hcnY*l zVh~_WsPvD5w$apF$o%|tTy(ZXh7ZkSPK%Vxc~0uL7pRH8YhpaD#LOZ&zP%2xm#yG? zFEVI(MN8MAw4x-0wY&)@wm;h{I1{{Fz9oCI>@QJKq((j%A2sDC9{;12VeR=TZ8#Yp zpHPSwm(wKXun#%$`Up5y$44f0+n=MmKK(WkNnFR9zBx&56-_~f#b|l!qC|rF@U0_~ zBFgyof5vDflwneZjo4U=)|Rq3Ic3gPfkl@*eP$i1#w%pE)Y1jP;{tue{>pi$0DK z_sWh}im=U1sY?;a`F6L*>5N8YiFw3Y-?SWMPyIPC`rYNNVMqvx)~O}7h6iQ|-|_w% zNo)SnObafgxfH%?+kWi?+YIa}x$F9&dtvazsBc~~*?=i4pHWPmt@r+n!tW4n{$f87 z=7<){#Mk;8wJ1g+-5P~T60)pWPt{m=o}mS%{*!44*yD#uB{r;|)7r<=h|@|aUy7pM z9zb0VJg6+GYr}7K&Dqi9X{xZ1vwJ@88T(bx9oYq!=PTWsteUO9*Y|iwrFV&|ddu;ieq^I(?&ickj>eM^#cfaQyrg&0Euv-PT1nv$ZBeN4J_Iq$V$LLfqZ$Ka zmfB5MVaI)UD?vpGc5$?nn}!}!829s6SdMa$hADD(?G(SCEiMgq=r?`jk$oxN&(0;@*&XvY z3Sda76%5-LgI{Gx(w^o-=lq=}I6=<;OZ)WKG6{5aIMk~;2@2jxf91OYAQftmG$+}M^wET_Pda1h$84eZ*ank}o zKc6+~j860R00f2G#kJR1Sr$-@i${qZH#(hR^tL1G_#S^+z}k3a@Mlc&%Rn>B-^8tq z|3=(0$uq(y2!Dor#1FF?Ke;*G!%cYf%Zctg6N>ompZYRkkIPwhziB$Fp}zOR%uN!7 ze(^bP;?YM$$zikWQ#^g3+vVlmLCwhvsO}SSDH&(eJ!bWBgPw(hgB-x00VK!UhlA_{ zUHkd3x7UPlYKgpgYrRuCymS86XIlFRCd#&dMak&E?B1oQ!y@VQM2wh1hCiI6p-n}9 ztN*O92=?bB5vY3zkoj_lWuOFPT^=!i^SDaP9vj@n#Jnp=;4Q|oB%rCXx_v)BpN`SZ z9L|{*R*fi^^>e8&Upc$n&em}?^{*rWP9c<<6{swdOW$o1lK$iZGI&z?00x#P_H8XW zjNKti0-nyY)USi5I%q2HK>+gsaHwSUDFJ`i`w{UBEFY5(mgN#d{aYgFCGt%f@%h(h zjL9Ickf`6i3{>y|bwyl(u_S=t4o?<=o9LQ;HCiYFG+w)=rBOH&*^oX75dMzDHJtZV z#NNLPuqrGRzqn8Ffl;e-GgxVhx^Lo=jwR`JsW~3lKb!;vtZb?WPkxe1bvrM}7rVav zJ)P<1I%fYabiaLgRogub8VL}b8bJL|$gl(TCbyfGy`Tr!Wbmi?kOqxreGSzSyC%nn zZ(H?89X&%T^~M81u@=gDs}E_gs@K}RtI`wbR2NOoFA)*|W6Ydrh-NCs>>*vuTtIgr z{F@iZ=ERQFYzyq8KkMe%1iB$FP`=`sBa+SOwBEiMFWMui?67)jBnFwyPq0*dK=TvK zSJD&9*tUEn;*Cyn60@t(@w)9S4EtjBgJlvCj=BlsVG^wcF-2kFN+SegUf7*Q3e|`s zfXOkn>D~Pxs$dTH0xG^DNFk2FXh-6b!fbZ-+>yIR=cMe2b_(5BuZ=Sp(sT2OL#BZOzUZ*c_dEgLNFwh!N$tiE8b zsHcBJq|w?suVOp>pg*8s!E@L{Ax+Y&YYEk!A-HWfb{@jq2__`gg@C~?*kwBJrZwr! zf>-w!%*?rjp@9l*9OA9BtFSq>p!BLk+smGfBEbub&N5)bPHl*gOCk}Q1Rsz*PoP1e zUSm{a5^8#UcVQ?W@bdj+QX7zZW{WsfnyS=%O@FiiYvC-yL_}>ey+Xq-cNCpoxjVlT z!_J}%#u0it$jH_CB-6u8cVPpU|<@9+;ON)cJLRI+YKe zOAw){oc6@-8a4F{1?;ZR(BFQk3?G`e^}ORT30rB&%}<@DxZ98xk9nT`d9XqP!Q z#K4*rQpOg}KT@4Z%go}1nkkLsn)q$^@|ew*GcglkUynX;xX9$IvLye1*n7*kESL6CTj`Q60qK$kk?!si>5%U3Zjc5M=>}<#F6nL&kdjX6 zZeb6)Tx&hgf4}?V`(^Ks{J8J?ikWNXoVm{9IJaKGC13mdwtpY0*6hXRdrf=Ek1*YQ z&*6Tu?i4_Qzeqabes@fNDNr64E!e)pzQ@LlM(PrRwYrMosNER$TS&GfGbxp~JROU% z>7wWwrM}mMF|8Ns>kLG4z#vj)-r4>qB6gz4VY0neB8_>Xvyie+a_m~l9nh_U9=?KLzmypp;z&SsPqo&g!K2(HBSC;u2&i)yNgKfl4XgF`LU&@fMF z^n*U$^q-T5(5XoF#VL1aY+PDxXPZ$1q$+yL0^EGP_Y(r>w*qbK90*eJ=F62&G6Fg^ z*a}zGbK4dIsO;7u;-IKbazYs1We^KIq~?P0ka!$DGm&ka(0$gmhnzUB-)7!hp-$yB zc}>xOYRN?V!rEZ|XvvlZqQ@-)OWv;kwvxr>1zq|rAf`%T(yu9U_@rQ;HE5OH$z}m5 z8Htn1FDF^otr+y<2#>q(sG9i2_4Su?E<|iao39Ez3y+PYC(0C`GUIkUa(?qeNpv|N z+QqH5{{wjZTb(u^3+?YUp;Y1hWC@X08H(r|FV3Y(`5Kr3r#O9mgCYp`63y`kN`v=K zOHfd~{6+2C3VdLGArn{msRPE-X9r5%;l$_XG|PS*A(Lbh-luDv`dGE0AW^(hZF%-( zk%(xwCo*!-@$Quc?(2MGEX#ba;$X!w=JEy8SL<#Ln_YH57e=T^o$V!(|7PcP$H`to z>RKLc-SOt|WSvP9i;gJl&+-=x0$Vyyf?RP^g6a*&z0WezBAwO|bZpT%M}2W@fI7n6 z$?8?9RKrH3#Z>WLq%=%lWe1UjlEPQ0rz~MH(;V`I!FDXkCz%Hfs84G z&jVi8o{u=aOQ;0&FNLQ@_V!n^X~5)GYpNw~5<_2%!N+#_{e1r$Ook>~pfQ!m^8{KY zzI_f`O=rUDii#qgJc5mhMGrO;Dy>}C^VCqYBzd_ui_s3~H#v;=kx!XC6vnOygHFpx#HkM_m_jWDO4Ouv%EBp=u zV(ty+F~WzB*X)g=pA9K}VD}?JrG8MAB|oUjY85JFwF@DkFAb=M17uRFgr){n96bbI zaAIzKh4&Xa7kfl!G7$oLwmyla^5jr^wzeA)9B3J{ z^SaoS%zvUEKp77LpCn~b>+}D#dzso$tZ)4k#EyNCd!1P`PgZ?Z0WW!lv(*jtCtjDL zg^*#gEYcQ8d7|Q6O~OW}lZbr2U#b|pgi;K#&Kw&60}I+=ov9KmA!%t*)zOJhSZcb3 zGg+aw7wj9|Z^gJh+qs!H>?lzkzN4GPuV;IMuRIA^OHSHMU1czaBW$~HdE3X9?Vgk} zrKH2Zn!Hl)Y!W)KwjzIPbF0i#OX!dtAJW1mnS|U1=&} z$ZG$?W&eiEEoz6jWM(v;hfv<-yJEY}w42gNPOpZN~= zA^9yzx6RDN4z9Pj=6Q|2vXxNNN+k~o*Q*bD^k_yj!E!`xo~c4)E2NU_8b2v88uJ+BWf#$1OVlQf(QpVmGH77Wd_l zX7W1i5AkT6aNZwOx^zr&wlPf#D;PJ%F^jWQtE7x7N=bWkJ zB6%HN!6o?UqfMOFGlR4$j_r4QZ+n+$qVRSFmC6(fFftOvUKG|F4wHt0B$uJ@w-F0q z{!lcQ=h-hH#{%Z27}Vgl{@iA+;rvmO{T_uaBp_(KdShS^6r_e0+Ts?h;&XX}l5zfw z>&L2gmPkbhc=j5#$^=&Mh(w{j?gmotSti*?vATaB)ooe6I5f+5mQ5wtb2`D@o#zaP z<_LW{$w&!`_ppG(Dg;qzAyMl2V@M&xJQ0a!#- z3m1cOTN~T{r&GYQRi@Q?0~Q2Hg$4Qz@7}V3E)=G`4HUa*6qO%ZD=<@1u;^l7-Cu&z(@~gs%kU+*oPPmO>Do?`Ipb?5lTf`AEOQZ-6JRx402BAg=UxFqwlypk%LGN;l=N>XE zjM7k*0`NfM*X~05lz5zWL1z@LqsibU{xlt@4qKzV5+(Y?NWk6YH_c7kh)Ak9Rskec zT}K+LO|&F}Dm6+;xqNRdzpi@k^)!EWvqyk}aPCMbhm1oG>?scHjnwo$I#McsH=C$J z$JYB2?flw*!6RBPOMw3Bgu!JXe!EfU)|fWPNctO2rO)V%KK6Jv&#OY zFGypo;U>yomC6)m!x^ZQ%nxjycsN;fuG_00xcv`()m~;@UDcIt^tn`?{ZxxVN-dG= z1)l`vxOWh|`zx~kQZ*1Yh@E++^LW&l&!6wq?QagQ8pmI@%pj~wZS0hSELfqQb-UWN?ua2df~ZDszEvyA2C^R7 zf>8pjEr7hMy>0aVdA57khk|@MiNjh;jf=CCiyig@PUqv5kj$m`duJYK@lK}WxQ{ub z=1*{J?xvcb;U{bi#g;~>GHZoSS6mb@aF+9-&wxWX^n?nbu z9O`!|+c;iu*988`FWAcBK6Tk>(8RFgME7>TgxE#=G4t4qYr|G=pIc%(xZSSTgqWQ5 zwtKLy5gtgBk{mHvFJ-b%=~klJaIqxf!}5-v^4VRJZXeq$dLYT#cPzL@i1235)Zn{Z z@q0(nN-^D?5%J0h{X>o_$P6yqZW#a+7xQr-DsWS(bJ>s@PWxJ8>pRS!0|{^s@&V+} zR5P+On}p$%Ij67FeqR{VUwBL0mwo(5id3lFg2`I&2^2oN8^)g!n-@TlMWFpwprUvB zMF-J1@)>_6qrcd>vqGR68O&MRT4I&TN>vk_+-!|`z2QC-^>V0-5#=%vctsn3okpkq zNIZUzKbvX&@>`~(r2NpE>-82D%crt|6qbxqUaQ}&Io+MjURn&mP2aK``;N#I30Iu{ z*$Xg<8=f&Uy)WBJd*QV9ww<@J+9vqvEfF;4^Y=th3MSAvh;1>YnwshzgjeRZp_Yf= zf8=C7zDF*_uaKI*HFdTe$9<6l!ED&7Xt&YGyWJ`^1Ch2s^B&`JPW!*U{A;)9 zmL8%S8I1`btQuqr5~BZugq9eEVu?M#95>DmkkzDkc-i*P^?*MNnIKvT#*LW>tDk{b z?a!tB`3OKG!R-j|4g2sfH~rt+RErPWREuG8lsDQ?rs*OOJcO!wN>nO^zs~E=PY^>a zlK8$7CuAHCa!s=CT)e^rq7tBC`ei!0jS`>u4>ghi6gt>_l6uVl`_rMl$q1w|$Z%jG z$`>6SZuO&W>U4$l>Q@N#`zV0K6DU-IhxSYrGv3n1vyRf&5GI|VgfI*7{iQidaK0sx zXF+>BOM~|3v|^CqyLzOChD3gRInuRH(x27s5Dy4#%OLYbwB#Wi6|w}oCnuXKSxKOg zFJD8jrvG_6HcO0(_LK}eWd#cG`(~Xvt!vO=M-iTtUKq;z{Uh(E%c}1R`$XDS71eHX zPW!;u{Hi5oLrH{qUu?F z+5E&I>FF<1md#F5<@np&W%vf7`sG6d3DCeTRWp$Y5>mykh$yxhKxm|Ltw6D03BPy` z-(CH5+xDw53*qBi6?8bLj~^*(zv%E1j!Djw+S zf@-Z&c=t~?0iE&oIm8b`o%3qc{I`D@lU{lGCuJc$|2V7=0&J~*@Jk7p-me7@x&Pzv z;G4dWFh^4h}{2vkchP(zNt;bXP*vt%L`HcU*DGqco=m8V1u+k zZy@%BAnA;BvEquQ?l>EU5(l>pC~E|f&)pD*1$fvAT0 z`wZVaXb{9IV*as$NR&hM**x?XAYo7jM;=xVNn!itq5b^~_?1Kb#`^mnJ^c3(Y;5hH z%ltJwfGyxJyWp^iN z3DDcu?Yi|}hNCi%T`o6rZwGN%ib<3~97k(uMR$LxU;XF4{Phx@;*E(xDBW9SnofAb z#`!LJE;;5sdH)G$d+2*Ie=bkt=}ajxmFqp3x9B88EQ`J)SkgZr0SD z%-6ya81hv~0Mh+#~d7Pu;%v?Z^l`YK_2@ z!qOGs&rMo-bH9ddhWmGa5rAqTAx1sKLZFZ%YaKH_g-K&DIVF?1ksgJ5FO{c2EHTPW zycjBgMJFH=~g*olVmO>L@ENeROAuPG!RT@EZC=hKt{L{f?|36 zc$W0{almBwm(vYs9K63f0kS^zY2@$j_xndfP=EirKr&DlSS52HtwH_k6j>M^&pv(l zdkF>X|DB_BNbRjzNPrJmgiBNohx6vWotn|Mr8w{RRdDhwRe-?EJqQd6w+Kx4=bN{YTUB*PZ%x zg|{pZCV{6UvWNNbUv7UN?$>?%ef@rhpf*ej60Q=4-zk_N{!4w56ag+MY1en$89eT9 z;DI^oU*lK|$-`GkkjbomX-f__;l2$0>-Qx(AI6zZ*buD;_XsR}mxUqPc0EXLt}BXB zEgCfwSwhnC2Wd~R?5Cv-G)iPX<*|I@68q*W)`l|e-#!Umc|_41&kg6tVK@A9*juNE zC9cz2H8I*{CzSPK3$NSp8YuFdXPgFr@|){xKqoQ1>@k}W`!CywS+6DsWWo~e_kcLt zvkoSlTgrzc zQ^v49L6dj^wK1B(Z@1FL?Xr)1X1X_915QD^&idILH=yVlv>SJ)D*~+UMBG3YKHf`n z4sLFf{&#sGfggxbZbK!#?Ia?^u63R5%}z9pDy* z!x;66jg|Fur8}H77B0D!5+RaB=Go2Ehnq;mb}NqiH29bBc$E$KHltx^3PADj z4PA`?7M1MjIy^r^teDZTBncwH`!SgNbe6XhmflK1T34mk^nC~U(`@O|*p>lQ{4Cku zPvkEhVZPhLOmZbGf{gB`OU48WWk1L(PvlcM{E}ut33*DXiMTkx9amdSjR56{d^%6F z#|1Ky4BKm5Lc%CX7!<+?P7(^K_W~!!>x1)+PPDI!-sj|yy~m0XXCQKetZK06=+ykvYaOK zNg75*Mt=U*1LTRPbl}VY*XMGu@B|St;CP|g16WT)^8kAd1T35``&u$GLuWfvCZp-| z07%(VZvb)>K>gNP&K!fQl+WM;o{@4uQf-cAn0Q2fV2S)*kp6nV)$_Z^8>O+Tp&xTN z7;Cdrn{xBjpRU_BnCiEEnxtAOb5!J-j@B6L8?Nm)Mko@m{%!q`60uZ{p6OI5|6Xoa z-av+;!}*wkoP*S{qmk1oxCXyLe|v89AdA!aCmp5d?FQ#|Vwg7CS?;^9*vdTzg$!E7 z)}UxT!el|fjFz-pmQJISN1lwc(cZw5wAo$UOaA+ukT2Z>XOTN+FB;9`Sr}NMlAAnS zDq$?$oX51-W^T^Uhu3AdpQW4=oiev)$PXt~e6%_VSQT&eu|>g4!(9ujJO2^I5HI9y z)roic$)t;T2r|-|-tieOx4qkHBMBo!Cdy}zn=gUPYNoFTd+hYG4#jmD=yZ|r$=)HM zl6}biXA#4K@R%*&og+IyRk(~ABg~u@9!fcZYFVkA4#Ca6u6;2ipkbujm8OCg@zS_m z;>R3 zXe}MNay#z|B%15%+g~2)byb7btf{Q@59y71W)RZ$x@0a}G#osKBp*dTs+Oum0x7Lre3O1voW0H`J+FMDy!9L2V2Ng`J+tI zJ8lAb$1YQ4LZG|xN!@#9qqg%q2r<@%PPwLy4)IGZUH(Zct}W%cr`(adGpkHh}M zDJkp7w94Oef4GOO{a|j96WscOpbK`k9H)@!9Z;YN~-6UesQ<^NXBs@EEleG4UK})sAFs)7M7;e+o)Z6*yra3xDqV` zuXm!-d~uHllH-pQW4B)SV~u6-HN?{ynRj;`+J#<3a<3U~R1fbDtezMMJ-O#@r%wCC z$HQZ9YZjnkG0VDX$_igG>yh6HxriVm>yYrg7tg>rD=EpT*3$Ase8BOVA`y zAyinv_K7ol;8h)C_RemzG&PAaW%fcO7eT$}O56G>AoRxUDpY^kL>{nqwPoscYlOqd zJ)La1$GX=PFH5Vf12s77uC1~R^F$t_m=X(XUIc%1Y+os$qUyKutJq9>VMKEmW|dU% za^;zW)1&8K`YsNJ_AHs@N|l0ne9|d0Vw<9#*^&>aP%rI4RwZ^>WWaF`I`2jVZs%Z# zXBm<$e-bbr=|ee~puuWFXp9JJpzkDcnK_R9IPxaXw3D*LXe>B#*vc|mCXHG?;#{vV zM#?}~DJ*8jFW9Ka4;ML??O|c^dl8WizXWyG5rilaLZ?v;N3s27%jRwVVkQ^(#M5Ab zP;?5Q!V5v#1GBgXB_O#iF9*a*r<;n4X$OE|F34N*6hx@>Bz{-s3blyM{8Z40EEg@= zJU{m`p1v@CBebO`1ng($R`+HBnK*1*Xm){(jo$0;7N6uvO=dYG2ELDhhNL7h@wi)f zohI8mOYbH1I=#*y{=S%sD^F0gRFVCnOt+7ozYK2MMKbpY-hQUI>i`!05PCiQePvZ8 zujBe!ns3O3?&VFhtD%M7@N84l#)&=S#+yzkj}l6==PPh=G&OiFYMNII{2x_R+-Q~E z-Oq>eUJpjeBoT+crB*7|aa~I3ypN3Q5%KtDlj`XIX{vmYzaGany`Myrs-+!~El;Cb z@a}wNATJ}G$N7ZDYI(`k>F4$i{uEILb37F)W|2A~TYqR$yi?g%BZz}}Z;unPnAZF7 za2&d{>OyY^?xyS2`*4J7SNjneBu2Fy%7Fk3vBmF|XmQe{iK-^TCti{-V-Dm+vHvWB zylEf*s4!Y?J}Dq;X{p(&lar703IPH9;$x9{5#pcd0O>t1Q6Gwn1S~sPJ*16As;M(y zEG__T;`VFGHH+EzZtdklS*CNfdvR3qU|BIytjdVwXlp9~gB72FeLfcuMaVk~yelCn zL{jAFbVWC{=|I?o#W=F|LbKZRu?-m+8BoC4p&|3-e#(AJ%R1|EJwidE`=v|_gYiN? zh6P&sJ*^hY;Yn}XD3Rm2u*O+sP4%5kCr{GX%fUEVS((`>Qy7o=G#Nu678A6a2Iiz19B=HGwV;u;xV%?-t}aM2n8?rGeaB{kOh}kb#O|4dMSiZ) zx?F6by3)}>b9S5IafZhdDiRx`;Ia!9P$zs8)KLPB*xcau^GjESy_x3~!~AebwIIhv z;n(8whMM8RtD)YHM-%EZykXZw{QAaL<8M|lcS;zTBm_NSP#CqUM&_F8hzNNx&yL6l zzB~mZTfEic^TU0sp^f+KK6{D=-OlGO7yFG(CMK5p9};V18g5C5pUaCj|J_1CzG8TB zw$9C5$2&g1)CHMdm(*u3iiH*=DT9ijvvcPZi^KjWh zB!5l=L}rRUKd+s@Z3i$oA|^GH{hEX+um-#WvO}8JMV}PcfqilaJ)=l;YE*Lkqb#@6 zc3=gV<{31q3xa|~e|*iuXEh~Gun-;qp*D$qa2$xE>#C|892`#0&ljppP^hl>HwZ8= zqKM7z{qN!!80Kw^MtE=r&PR56&u7CrIn%15cR03oNsZ<35sQUiuG`!Rj>ly4NzuVO{*$s|wm|Yht0Owp20}1#c?^OV0j9tCSjrW$zGq z>>GQZ@-IW5l}7KKX6l=V-^GjKvv!crAYhsCndt3TVkv|u?=HZe^R%=L_0-PnLN{L! zYT-%pISV^~?&5442+hTy@`{o-(}NCFqvQoDxVL zNuDzPF?Am*iv1zp<81Gfxp4HJ$C#0|fyMGxpr|yPMUY>fMy=p{4)TfHpk|hR+z*Gl zx_fHY5op9L9DlCh9DOZUV}eJ_3kgqas!c%DrbI~`?@$yS*0;!uq-5qQQWrGVdtll+ zLBH-dQB0N@73#M4<0+T-XStkM2^}mN%m&9oxj1Lq%F9DP!YnH~;W-UaBpN*4y7<%6 zr%$Va?1kLOw| zl^nxU`RO%`kGzr`2AH}~_37md4&m@SXb8u!LmZGlC$dzIF7Ulz%v7PWm{cu(aQ#b( zb`v(5$ zQtz*&Y8L>T53v7=IDXH|!@gLu+S;MHh-n=l3Lp>sd3$TfqHbxq3)D337yHA`6slqM zLa+-{o|g8;W(p{Evh_U&X?NT7qp7s|>9%)8{qJAGKpa;m*&kG!ksh+c8-A`S!or$7 zL3b*#u5}7@TClu@oHClu5$aZVWNO)%?xP_iH9q)2{5|MhJi|#&?9^ocBo)Gz!OBaD z>k#44u7i?!bfge;B|X!wTdyHn+?@Z0?6DpX0zQR%BvK6em|08vv+m`@9{R*Vvoc!} zIy9&%rkA!UdeG4Exf#N}FCXsgty6^&Oi<@&QWN=6#HxbBHC^QMq%9<|nl!ARw`3>A z;*NAYs3@|_3wqNXdz%q+34~8w#5UQ)yi_ecF1{5^GB-I_e6XXEN6^-mMPMo?MB1J` zd+i6o6|2)aG7IIj^=LiiYhFOelUF}@wb6MzIZnAkTRoqiGjltCrcr{z5_>-Y5Xx4Y z?}<6e+e406>-q8#b}L^a?6&Wc-b&7j6U$Uk7cuUpoe=H)LxOATz%1dHUt;=*!_w zG~;1k?i_ls?RDq^ua@G_nLVlIP-3&2J_w)YHFV9!#P9iv&C&|#eM!Lt!9g}9ez4l; z?)8~@VLT^};?XVPhi648do8J-wjN$i&y|zgi>pTxo)Z%+XnoGik8gN8XQ1d< zEwY+Kt8RjBBK5kxuCC7fE4leR*As>)D)O$x4Cs~7Ui#{KL5W!r{OQ;yU_w-duqUFyE& z|A6alz4xNc)}1|ZTz28?*>qe*8av%nS#z;0ZT}Erxz=PC;$ z{kgVAj)IKVFJ{c!V4?~++*KSR1FuMVw>bYl*?OQ+{hh0`r9a7HAeC_A=WB$EOx20C5myf;s;*%@+2aPca@hjW(&#y-2s2XmRLK9z* zsyJ)~TbjPG)3h1?5HE8x@q&McN|m~%OmaP0OZ^fH0X}>a?I95!$=p(>HKM@bNfmI2 zPGzvDe-U{pUOI-PhKBK65%diDH3!Qst%xAF%T$7>As&ij^G!X-I_MjU_So(3Bc9G2 zn%|yN6zOVId*w!|dM^jRlBqqse$@?lP^_ONjo(;7P6(e ztFGMIAQt9%ft5;CAbf`bxzj*t>uK8<4MdrC$Nx3wkk#CK%_|BP>B<<9A7Yyrn_Z8(< zxXH!>m6WrB+{R-EaOyZ%D6trMo4@6{T9JE*8YL&P;}2Ik^^l|Lr7H=c*yy!~73_#8 z*FMJ>;NwAwJRbHc0e8r^@slmqNpOIu&XZDi`l&whuub-?K-((_V{{Z7KMOQms!d!v zNhRXLb#W4CjO}0BYq@U!6RS74tlLNA;6W^VP7vT>tJL<>Zn2)UOr4~x9#{2!3YqPa ztxu=V-u(y3%3=cx2w2NF3mqiQkv?u&?8i=E6Zvos?zZmbNRGVPYQJJ}lw^tuzzeO9 zw&T#%zo6~tpHQ{%A;9zv2X`0DP;?qh)M5v3_V|$$?IY$4qUc%ki}4UVD}UJ&BWsd( zq5J&9X)Vjmf{hW~HKp3RhZt930Q90Q^iY=|u2yM5=sif0uxwRDAP+%XVR=R%SNe{W z-1Vo91=&G-@5-`gMT?%e^*}HyRu!9tywr|-1l@Pql5L3%>rLEHHmsp@y!UgAQq00h zg3C+33X7Rjna^$QD$HkCzzU%t5}$r&a@EUCU*aj=z`fGcld(R-tkquF>&wsfE}#rO zp1V^7TU<$0%K2kCuFvj8HdVr{wluf z?Sq*Jl=>1Bcxy>HH56)+7I%;sa*!%UPPOEr(<|92-N?oao>%9LPrv6;V$O|K0iW~WLBZ)6AA#iNfSGYoe)6brA} z$SyRVe20rvnMP`<&H71IXfTU>EgtPF7=QJYO+oR$nR=K16I0LT{(l)$Zxt;kD2H-c z9)+xDb8RFY)h2Sb&&+S3Grp~zg;wv@@eYjv=ls}2HR(E`RV$XW2rubq)mkGfNQ@z# zKqJ%hqOaOsQ!U$H>ANMSG23$`EGHEv6uMXn;}o^N0s~9N_~)pX8&of#n`CB0Q~u+P zZXX8}-EjTeb(Lq)8TAzVr(RcKIY%b@gB85@bpuZMx#N91?Ww{{zQ zY@EIm`uNk`t>n%w(k9V>i>{nRa>BQ|Xl{G*yW6W#NLWf9&n;Ffyt$x2tBLEgkHAd* zyxE&~xgB!LNIs(|CkO4zfbQqF^G!JJS5+oogkxlXPSlk%$rDzw7=2;Itih91ts-Bp z$eKxDGY%G^Q_qf-kU2JAoIK4NKh#~{xv{@@fH#@yrTc;2^s%+CIIGab1lMl3bhyYR zoS%cydj8GTUgr_)M&AK}UwQ_8#_`WM5W8UBZN}RW33Z0Kt?Ds_r;n*QyTOV*PuJQo z8H|=(sf`q;RH-y+WS};q#F#^@To+IH3#otXq!M@~<)A!}xXx=d zbuKYl(w%BN8OhOu_bLhE@m{nz0``O`cth$d^XF9`n1?_jnvAK%Sc(60p)W0i`p&v? zm$)P3oK!a99#3=K4>e|h_sej?eS^2N>Oz7Lnnt{?Qh*L&)sNNyLRdN7Iym(Ee$6lq z4w~Ey_65lh)5_$s?f*mS|Nlkmlh}z7j^DGEewA}}!g&uDuV<+@#JnY`MA;_Ykm3$@ zoG#~~O!@wPyRy^roe%{T&f#(#dD zm0X5Dl~?6XO*5-AcrV-Cp$lmPX~G1_nz%gcc|+e>>SUAMu_oDV)EmX~_;DGPeDVi| z(nX7@R{qoL4oOchW>vb8$~S`P;?eduH=7)eeMWO^>7`a5f)JnO%dMOAcZ?ACC1XJj z)4moOFLJV&0KSs~VFD`I0lTF~G$kC2I;l@$ndX*kyC#cG7V8*C$Mf9?`A1rOS~~;b z39=5QP2Ty4Zk&hTKCA1k)UR9OTbZFdZfo;CBCF!M7iOHA=rCWR?4?JG zO6lA)UaU@XOtvsX;q59hmKR@qgUf9liT+x@MdI5;e#+`c1+`f@&fXel*5Wb9=1+#* zxyoLw!{%rDDb(Gilw2h@zRR{qFH&4pLeTYRJSga%eQT-1i@8iKW$t|=_KxN8-l)!i z*u<|KxJw);Q`x_p_;^WMX_S6?k?+}en7lt5t@gmM{qNEH!vwhR_3Jq3c-Eg1l?va1GTZ1dS$e@J-k-F6 z%HIFN@V)u(^AGqu_0Qh97K-KkEQ3%ns6O=}07PZD8#e3gP00JVZnuPdKZWB=-kA~c zdfi>`-LzJzd-lcMVS1`-+>{@DXkK1cq)+))sGFZ$_2NV;t~THfBr6l2p#1^ztuNLQ z5lXvfaVU4*w^n@pHg|fZ5wgg!yqF}Vocos8!#SX4Xdr%7T@##jPgIccIIX^~LC-lqQz>pGn!6{Ff0v^2o7fMPO?zA>2&!T`0=)YH zSFiCFm)M#@qyV+XQ`kJNV#dZ*%jVJnxc|He|BN=iU~Bs56*gdaB-tguY@*Ude*XCv z+kahSs}5zbGf|>d=6IwrNt>Kxo*_9tEE6vRp$ujTfnP~Oun&n?u&|+8Ao)f>{88-W zc&gDbAiyZIRK=y2Nxx{SEhU zJ(AE1=lERkBfwe!oyB5txHcp0*;AxK2a?pQ@M?D#3cGz5o=L|an$A>P#|m97!g#+q zqt0k`=XSWG@r^;EDG%I#ir-g95#mTx1?u>>!pECV7RvHBm99Ba zdwjOHrwz1B#hO(E{w6k&a5vc^d<+8++5 ze4!pT;B$impU)8tR$u;TRz-y!U=?%9FreQ2hVY$D=lg~yDfsvVr}Byulaff?e|&FI z2ONI+{O1s2@u{=6`=o$o?QdQAM9aPnNoI9X^qxg3hd!8@;dy9ZtQWm}jAhIc|l zMTT`N3DFRZeR(r_1H8_P)|d7Qt5gxNhUSXQ=A#8O09pqFDS;sH-QM_Msu(iYRdM4b zE}Tc8kRZ?%G}9(HIerQci_&g%N7P^4h}=(CHew_55&5p2IY zZlu`bbv%`E6;a;VI0MYl)}58B*_#MaNS)7RDm7Z=WmW)3v~xTs?`dP2YurJN>Dc6Y zNwe6pdC>GaMdal)GMy7C8+!_m^PBuySsB@+@*m?rf*>AWRt;aeK94H=5_qKnEpo}J zt*yq3%uI98!o!kA9B<@ew?F-n8Rpu0=4M~I03JVWZ8QL-R6YTDSd_A3-J-TzI!PWb zYQo0=cA{8&a;cwpyeT@R8A_G*nWxcY|nw$Wy7OW$-g1ty3qJD)4H^XfWU;Xfvt*H#1gTZDF z)u^nj=vC{J(Xz!x8$FW!@n(9`P8g@+^}g8nw1LbL-QFhUBT~5L&r+_$JO&;w@sKw} zeB0R+H*EX2)A`wjbj#nR17b56#{T^FWkk`dDyh)ypxHWeT&!m&+r!*jBybIAJJ-te z(V5W9=09f_B#zwT4?R;77p0%V32~P|SJaFxd`f1F*6d#qHNR07np!WeLkmOsu~?(^ zL%+GH#%VNTb0xmq#&{$H>OHF<_A?CF(8#zpX1Lnmz~%4V7AG6dr3$s=tT1d9?=CIX z)1(qk9Y-_pRWaVgRK8J6bh4hR7OM$+dlD-W86Mv1b)lEz&KEzBK%-j=gLLF#O@=1FdPm@`r1^(7{d0^N$(j4*9lS!E-o=e2Jc8FFu8$-7~vf_}anC#hn zlP112B6As?KtDsEQaY~l#%Ka!=pvxC_B7ew4X*czcETLJfQnyR1F{pFMK8;-%bgc< zd0`&P#Y))q?vB<$1boh66@Nke%4&kXPZCiX65u2DEK6dYd-9Pbe}qIQp0aE)ht!K1 zT{?^&FpE*-i{tz$pUn+XZU2$7ZE&I~e;C6LNor|jJq0wvoo=+VL|WdbZXn}$Yr=zQ zks<3e_`~1yWZlB*GNGd_S6dGGJXVqUiw7oyZ`;PvE6Ns8y0HEy{@W--{F?(wX@f>W zaMSo$hTI9|GvNK7+uI}S|3LDib8{*=I3>uB`g%$CpCCUGhYP8Q0a$H^8qTY%k+9Oz zm-wzZW+o_94%WVqHz>*fte8?we2q+rqETL}6);_M}dFu{RgQ|yTgO*j$ z$sQ3yLdqb0Z*S%(@Pq6MQQI{`s+cfnrSO?_x1qfPA?jP>&&pveMi0!t`t<|z5AO-N zN+)+-zjb&gT{fM`-mn4S>NhX-wuOBCeL1tOajE`k6;!`d0bbq>SUp_ZNBK5Fq(7%I}U788Sw1DZ8dI{cxj)nXqURhkeOUlgY~&gEQ3Nv|oOvB~C*W zL=C4Dp<@&7Kt<#Jnm=XzJx&S($r3d=ifD#CB>d!h*kglUJ$fr`(BQNFd=FATeDq*q zd-_Y$h5FhkB$^NI7dw?OK-AK~tm61owRSMm^N7Y41RMaCt+5*O-DAN@f`fus>zSeS z$m`r9zr<~$07IuU$$P>eMB-x}+skSb0B;{RIa#*Ly|Z`QUx|E@a`DLEhf;dKdeNjB zO~Z)c84n?fr=vfG+W6Wj*gksLSN#<`w&_x~rS|`fr7%+hq2%2&Kb{6H4;P!8-K*jp zDhBd1|G{$F133QR<7le`zw?=Qb`*w%{vk-c_6nyTJn{ z(RT*8)=W_FuX8nD-Hl-7c6>kCe6Cm>16(H(1>451m(&9HJqBqytsU$3l}1iNMc4*T z{%w+rlnw3(0x?G)@-EX@)zi`-7QK|cLgRElBRD#K5{63ouE8)<37A$C2&yNRw%U*I zK=+&I=^twmPU)HFuJOdbd@Ly^jks~7nA@V4;s41-V*tz#(rhL&;azmtlkmseFa}nZ zB}=%pB`;uLEMFBWmCn~AR%^1A4w_E`W6!!-8*Ob=7Yk|I_XhhmJFS zm&K|=)1N(uzj=5^kLor)mNYj|j)Oq$GAm#B%Ud{K&0kH`{oOr zvMXNCuO*6mxyJowQE82?J0rpo&93X;mJLk8ap<9fVS2!tBIJ!zn;=e9PCzq#8Coij z$JJQe=9kq(q4K!FseJ*Tvz}%UNGBZ880+a-8`Bi2m60P4k2H(>U92Sy*2`p8-H(MW z22i0(dIs53WVCuhj*?iaV251J-w@YdgNXAocr;)?SxDKD?!B#3s*(Z$ zyRXV8w0E*por09*dI54Hi2ZCwnf6uDRxrJX>L27kjul~&C?%Qe*gg@1vkW1W zk&6Y_pF?lyo+~L#1h|bD3|d^p0>~5nWXHu`qJ1iz`Q-4Q48Hz|mUZw`e#fV9=%4!t zTD(uZ!D66SPUkiTHw<^0d`boxjS8j{k@s@+NOF9$F7$x0)L5G63r1J$tp_ym@LD z*7dn1zsoFj>aZ$}uKAD8p`ier8}$cjzVf|S@UjdEH$$4pU`nYP|8l22#%;3Q zhZf-BXtsz1a~BN}_P^-*3aG4}=WlqVrMp8?x}-}=8tLxtl5UW00g;lDmhKV+q*J=P zyBpq%{r&yV%XtpxfqU=X-PxJh+1dHbp!XmJ$(e|F4}2%*)w7}g?llE3AK;K1{Zq622+*GynK5Yo@_{x_llnFEzmap}9fwT!≧(VyFMg$ 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ⅇ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 F695tgq#XbN literal 0 HcmV?d00001 diff --git a/e2e_settings_05_storage.png b/e2e_settings_05_storage.png new file mode 100644 index 0000000000000000000000000000000000000000..8cd65d6b848963fa5400d1e9a34073c32fa156fb GIT binary patch literal 146217 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

2{q9Y- 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 ia%)m` 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 S=K|mCF}-Gawfy%xPyP*~*1zBY literal 0 HcmV?d00001 diff --git a/e2e_settings_08_migration.png b/e2e_settings_08_migration.png new file mode 100644 index 0000000000000000000000000000000000000000..0bcdc7442062634bf049770aec908b8563c0841f GIT binary patch literal 239096 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

`hH|g?=8xCYy))_crReg0_77filGsMQE|N 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�T?5oMWxG0&D=TCdv8 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%0Ax+54c%J7ja|DF_wM4mSNp75`v{)7M%N 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

Wy|34I>~$ATmt1Q>^)t| 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 uLEQyHF3j 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 literal 0 HcmV?d00001 diff --git a/e2e_settings_09_features.png b/e2e_settings_09_features.png new file mode 100644 index 0000000000000000000000000000000000000000..d28b9d6d8f0afd4db33ce0824f9b989b3ab3353c GIT binary patch literal 148260 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

hAL9c{}h3T-SR>f4VTDR{wB-C8q^5o%) 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�MLFfdJ5yzr6C@ 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�oP^f4Ni7;K-VA5 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 z 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

hAL9c{}h3T-SR>f4VTDR{wB-C8q^5o%) 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�MLFfdJ5yzr6C@ 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 Ayn2yI=wX~?H$Cy7< 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 literal 0 HcmV?d00001 diff --git a/e2e_settings_12_roles.png b/e2e_settings_12_roles.png new file mode 100644 index 0000000000000000000000000000000000000000..9d827f7c057fa966051f817d7a957cc904979a6a GIT binary patch literal 183328 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

  • 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 qkS7quG%fOJm#j%g@?$_M} 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%0DH*TlgfO5L-}KZJAL)FxOZj`{m}+s7UqupmX*X} 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
  • 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

    KsPH~(gE?ouH%vO$7T`l;`gW+n_2F+( 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 z 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 { - healthStore.refresh(); - // Refresh every 5 minutes - const interval = setInterval(() => healthStore.refresh(), 5 * 60 * 1000); - - // Fetch feature flags for sidebar filtering + // Fetch feature flags first, then conditionally refresh health fetchApi("/settings/features") .then((res) => { features = res; + if (res.health_monitor) { + healthStore.refresh(); + // Refresh every 5 minutes + const interval = setInterval(() => healthStore.refresh(), 5 * 60 * 1000); + cleanupInterval = interval; + } }) .catch(() => { // Graceful degradation: default to {} (all features visible) features = {}; + // On error, try health anyway + healthStore.refresh(); + const interval = setInterval(() => healthStore.refresh(), 5 * 60 * 1000); + cleanupInterval = interval; }); - return () => clearInterval(interval); + return () => { + if (cleanupInterval) clearInterval(cleanupInterval); + }; }); diff --git a/frontend/src/lib/components/translate/BulkCorrectionSidebar.svelte b/frontend/src/lib/components/translate/BulkCorrectionSidebar.svelte index f2ebda82..7f683aa8 100644 --- a/frontend/src/lib/components/translate/BulkCorrectionSidebar.svelte +++ b/frontend/src/lib/components/translate/BulkCorrectionSidebar.svelte @@ -1,23 +1,15 @@ - + + + + + + + + +