From b464b48f53e6eda17813d684909254819ac599e3 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 11 Jan 2026 20:32:27 +0100 Subject: [PATCH 0001/1854] Merge pull request #20581 from Classic298/fix/db-pool-memory-update fix(db): release connection before embedding in memory /{memory_id}/update --- backend/open_webui/routers/memories.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/routers/memories.py b/backend/open_webui/routers/memories.py index e0ba36c76f..b05e0c7a7c 100644 --- a/backend/open_webui/routers/memories.py +++ b/backend/open_webui/routers/memories.py @@ -252,8 +252,11 @@ async def update_memory_by_id( request: Request, form_data: MemoryUpdateModel, user=Depends(get_verified_user), - db: Session = Depends(get_session), ): + # NOTE: We intentionally do NOT use Depends(get_session) here. + # Database operations (update_memory_by_id_and_user_id) manage their own + # short-lived sessions. This prevents holding a connection during + # EMBEDDING_FUNCTION() which makes external API calls (1-5+ seconds). if not request.app.state.config.ENABLE_MEMORIES: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, @@ -269,7 +272,7 @@ async def update_memory_by_id( ) memory = Memories.update_memory_by_id_and_user_id( - memory_id, user.id, form_data.content, db=db + memory_id, user.id, form_data.content ) if memory is None: raise HTTPException(status_code=404, detail="Memory not found") From 3fc866117da65c4a3e05e1a2add40b193933fd97 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 11 Jan 2026 20:32:40 +0100 Subject: [PATCH 0002/1854] fix(db): CRITICAL - prevent pool exhaustion in memory /reset (#20580) Remove Depends(get_session) from POST /reset to prevent catastrophic connection pool exhaustion. This endpoint was holding a SINGLE database connection while executing N PARALLEL embedding API calls via asyncio.gather(). For a user with 100 memories, this meant one connection blocked for potentially MINUTES (100 calls * 1-5 seconds each, even in parallel due to rate limits). A single user triggering /reset could completely starve the connection pool, causing QueuePool timeout errors across the entire application. The Memories.get_memories_by_user_id() function now manages its own short-lived session, releasing the connection immediately before the massive parallel embedding operation begins. --- backend/open_webui/routers/memories.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/routers/memories.py b/backend/open_webui/routers/memories.py index b05e0c7a7c..3738d1681e 100644 --- a/backend/open_webui/routers/memories.py +++ b/backend/open_webui/routers/memories.py @@ -157,8 +157,15 @@ async def query_memory( async def reset_memory_from_vector_db( request: Request, user=Depends(get_verified_user), - db: Session = Depends(get_session), ): + """Reset user's memory vector embeddings. + + CRITICAL: We intentionally do NOT use Depends(get_session) here. + This endpoint generates embeddings for ALL user memories in parallel using + asyncio.gather(). A user with 100 memories would trigger 100 embedding API + calls simultaneously. With a session held, this could block a connection + for MINUTES, completely exhausting the connection pool. + """ if not request.app.state.config.ENABLE_MEMORIES: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, @@ -175,7 +182,7 @@ async def reset_memory_from_vector_db( VECTOR_DB_CLIENT.delete_collection(f"user-memory-{user.id}") - memories = Memories.get_memories_by_user_id(user.id, db=db) + memories = Memories.get_memories_by_user_id(user.id) # Generate vectors in parallel vectors = await asyncio.gather( From 182d5e8591560dcc5a58f49068f91ad46c605952 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 11 Jan 2026 20:32:56 +0100 Subject: [PATCH 0003/1854] fix(db): release connection before embedding in process_files_batch (#20576) Remove Depends(get_session) from POST /process/files/batch endpoint to prevent database connections from being held during batch embedding API calls (5-60+ seconds for large batches). The save_docs_to_vector_db() function makes external embedding API calls. Post-embedding file updates (Files.update_file_by_id) manage their own short-lived sessions internally, releasing connections promptly. --- backend/open_webui/routers/retrieval.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/routers/retrieval.py b/backend/open_webui/routers/retrieval.py index db3f80f149..763a9aacc3 100644 --- a/backend/open_webui/routers/retrieval.py +++ b/backend/open_webui/routers/retrieval.py @@ -2626,10 +2626,14 @@ async def process_files_batch( request: Request, form_data: BatchProcessFilesForm, user=Depends(get_verified_user), - db: Session = Depends(get_session), ) -> BatchProcessFilesResponse: """ Process a batch of files and save them to the vector database. + + NOTE: We intentionally do NOT use Depends(get_session) here. + The save_docs_to_vector_db() call makes external embedding API calls which + can take 5-60+ seconds for batch operations. Database operations after + embedding (Files.update_file_by_id) manage their own short-lived sessions. """ collection_name = form_data.collection_name @@ -2690,7 +2694,7 @@ async def process_files_batch( # Update all files with collection name for file_update, file_result in zip(file_updates, file_results): Files.update_file_by_id( - id=file_result.file_id, form_data=file_update, db=db + id=file_result.file_id, form_data=file_update ) file_result.status = "completed" From 826e9ab317d5376c6eeb93870481dad3bf99ae96 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 11 Jan 2026 20:33:04 +0100 Subject: [PATCH 0004/1854] fix(db): release connection before embeddings in knowledge /metadata/reindex (#20577) Remove Depends(get_session) from POST /metadata/reindex endpoint to prevent database connections from being held during N embedding API calls. This endpoint is CRITICAL as it loops through ALL knowledge bases and calls embed_knowledge_base_metadata() for each one. With the original code, a single connection would be held for the entire duration (potentially minutes for large deployments), completely exhausting the pool. The Knowledges.get_knowledge_bases() function manages its own short-lived session, releasing the connection before the embedding loop begins. --- backend/open_webui/routers/knowledge.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/backend/open_webui/routers/knowledge.py b/backend/open_webui/routers/knowledge.py index 9fc30424ca..c38c5e0bdf 100644 --- a/backend/open_webui/routers/knowledge.py +++ b/backend/open_webui/routers/knowledge.py @@ -345,10 +345,15 @@ async def reindex_knowledge_files( async def reindex_knowledge_base_metadata_embeddings( request: Request, user=Depends(get_admin_user), - db: Session = Depends(get_session), ): - """Batch embed all existing knowledge bases. Admin only.""" - knowledge_bases = Knowledges.get_knowledge_bases(db=db) + """Batch embed all existing knowledge bases. Admin only. + + NOTE: We intentionally do NOT use Depends(get_session) here. + This endpoint loops through ALL knowledge bases and calls embed_knowledge_base_metadata() + for each one, making N external embedding API calls. Holding a session during + this entire operation would exhaust the connection pool. + """ + knowledge_bases = Knowledges.get_knowledge_bases() log.info(f"Reindexing embeddings for {len(knowledge_bases)} knowledge bases") success_count = 0 From 242625782f03a2ee9c529b4df69a9d55481e6854 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 11 Jan 2026 20:33:17 +0100 Subject: [PATCH 0005/1854] fix(db): release connection before embedding in memory /add (#20578) Remove Depends(get_session) from POST /add endpoint to prevent database connections from being held during embedding API calls (1-5+ seconds). The Memories.insert_new_memory() function manages its own short-lived session internally, releasing the connection before the slow EMBEDDING_FUNCTION() call begins. --- backend/open_webui/routers/memories.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/routers/memories.py b/backend/open_webui/routers/memories.py index 3738d1681e..96b4716987 100644 --- a/backend/open_webui/routers/memories.py +++ b/backend/open_webui/routers/memories.py @@ -69,8 +69,11 @@ async def add_memory( request: Request, form_data: AddMemoryForm, user=Depends(get_verified_user), - db: Session = Depends(get_session), ): + # NOTE: We intentionally do NOT use Depends(get_session) here. + # Database operations (insert_new_memory) manage their own short-lived sessions. + # This prevents holding a connection during EMBEDDING_FUNCTION() + # which makes external embedding API calls (1-5+ seconds). if not request.app.state.config.ENABLE_MEMORIES: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, @@ -85,7 +88,7 @@ async def add_memory( detail=ERROR_MESSAGES.ACCESS_PROHIBITED, ) - memory = Memories.insert_new_memory(user.id, form_data.content, db=db) + memory = Memories.insert_new_memory(user.id, form_data.content) vector = await request.app.state.EMBEDDING_FUNCTION(memory.content, user=user) From d0c2bfdbff2b12e8190379cef8f442b1cf210470 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 11 Jan 2026 20:34:11 +0100 Subject: [PATCH 0006/1854] fix(db): release connection before LLM call in OpenAI /chat/completions (#20572) Remove Depends(get_session) from the /chat/completions endpoint to prevent database connections from being held during the entire duration of LLM calls (30-60+ seconds for streaming responses). Previously, the database session was acquired at request start and held until the streaming response completed. Under concurrent load, this exhausted the connection pool, causing QueuePool timeout errors for other database operations. The fix allows Models.get_model_by_id() and has_access() to manage their own short-lived sessions internally, releasing the connection immediately after the quick authorization checks complete - before the slow external LLM API call begins. --- backend/open_webui/routers/openai.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/backend/open_webui/routers/openai.py b/backend/open_webui/routers/openai.py index ec4ce2f4a8..44575e57f2 100644 --- a/backend/open_webui/routers/openai.py +++ b/backend/open_webui/routers/openai.py @@ -801,8 +801,11 @@ async def generate_chat_completion( user=Depends(get_verified_user), bypass_filter: Optional[bool] = False, bypass_system_prompt: bool = False, - db: Session = Depends(get_session), ): + # NOTE: We intentionally do NOT use Depends(get_session) here. + # Database operations (get_model_by_id, has_access) manage their own short-lived sessions. + # This prevents holding a connection during the entire LLM call (30-60+ seconds), + # which would exhaust the connection pool under concurrent load. if BYPASS_MODEL_ACCESS_CONTROL: bypass_filter = True @@ -812,7 +815,7 @@ async def generate_chat_completion( metadata = payload.pop("metadata", None) model_id = form_data.get("model") - model_info = Models.get_model_by_id(model_id, db=db) + model_info = Models.get_model_by_id(model_id) # Check model info and override the payload if model_info: @@ -842,7 +845,6 @@ async def generate_chat_completion( user.id, type="read", access_control=model_info.access_control, - db=db, ) ): raise HTTPException( From 0b5aa6dd60c5502ad98a0bea903142763a1e3f91 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 11 Jan 2026 20:34:23 +0100 Subject: [PATCH 0007/1854] fix(db): release connection before LLM call in Ollama /api/chat (#20571) Remove Depends(get_session) from the /api/chat endpoint to prevent database connections from being held during the entire duration of LLM calls (30-60+ seconds for streaming responses). Previously, the database session was acquired at request start and held until the streaming response completed. Under concurrent load, this exhausted the connection pool, causing QueuePool timeout errors for other database operations. The fix allows Models.get_model_by_id() and has_access() to manage their own short-lived sessions internally, releasing the connection immediately after the quick authorization checks complete - before the slow external LLM API call begins. --- backend/open_webui/routers/ollama.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/backend/open_webui/routers/ollama.py b/backend/open_webui/routers/ollama.py index 0af35de38f..b269aa329a 100644 --- a/backend/open_webui/routers/ollama.py +++ b/backend/open_webui/routers/ollama.py @@ -1257,8 +1257,11 @@ async def generate_chat_completion( user=Depends(get_verified_user), bypass_filter: Optional[bool] = False, bypass_system_prompt: bool = False, - db: Session = Depends(get_session), ): + # NOTE: We intentionally do NOT use Depends(get_session) here. + # Database operations (get_model_by_id, has_access) manage their own short-lived sessions. + # This prevents holding a connection during the entire LLM call (30-60+ seconds), + # which would exhaust the connection pool under concurrent load. if BYPASS_MODEL_ACCESS_CONTROL: bypass_filter = True @@ -1279,7 +1282,7 @@ async def generate_chat_completion( del payload["metadata"] model_id = payload["model"] - model_info = Models.get_model_by_id(model_id, db=db) + model_info = Models.get_model_by_id(model_id) if model_info: if model_info.base_model_id: @@ -1307,7 +1310,6 @@ async def generate_chat_completion( user.id, type="read", access_control=model_info.access_control, - db=db, ) ): raise HTTPException( From 2faab409d346a7abf88c9085b44e6bc73f2a14a0 Mon Sep 17 00:00:00 2001 From: TOM <46499476+BLACKTHOMAS@users.noreply.github.com> Date: Sun, 11 Jan 2026 20:35:01 +0100 Subject: [PATCH 0008/1854] i18n(pl-PL): Add missing keys and update existing translations (#20562) * Added lacking translations to Polish locale and improved some existing ones for better clarity. * fix: add missing newline at EOF --------- Co-authored-by: Tim Baek Co-authored-by: joaoback <156559121+joaoback@users.noreply.github.com> --- src/lib/i18n/locales/pl-PL/translation.json | 372 ++++++++++---------- 1 file changed, 186 insertions(+), 186 deletions(-) diff --git a/src/lib/i18n/locales/pl-PL/translation.json b/src/lib/i18n/locales/pl-PL/translation.json index 3b7dd22217..34ff2618a7 100644 --- a/src/lib/i18n/locales/pl-PL/translation.json +++ b/src/lib/i18n/locales/pl-PL/translation.json @@ -1,5 +1,5 @@ { - "-1 for no limit, or a positive integer for a specific limit": "-1 oznacza brak limitu lub dodatnia liczba całkowita dla konkretnego limitu", + "-1 for no limit, or a positive integer for a specific limit": "-1 oznacza brak limitu, liczba dodatnia oznacza konkretny limit", "'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "'s', 'm', 'h', 'd', 'w' lub '-1' dla braku wygaśnięcia.", "(e.g. `sh webui.sh --api --api-auth username_password`)": "(np. `sh webui.sh --api --api-auth username_password`)", "(e.g. `sh webui.sh --api`)": "(np. `sh webui.sh --api`)", @@ -23,7 +23,7 @@ "{{NAMES}} reacted with {{REACTION}}": "{{NAMES}} zareagował(a) {{REACTION}}", "{{user}}'s Chats": "Czaty użytkownika {{user}}", "{{webUIName}} Backend Required": "Wymagany backend {{webUIName}}", - "*Prompt node ID(s) are required for image generation": "*Wymagane są identyfikatory węzłów Prompt do generowania obrazów", + "*Prompt node ID(s) are required for image generation": "*Do generowania obrazów wymagane jest ID węzła promptu", "1 Source": "1 źródło", "A collaboration channel where people join as members": "Kanał współpracy, do którego użytkownicy dołączają jako członkowie", "A discussion channel where access is controlled by groups and permissions": "Kanał dyskusyjny, do którego dostęp jest kontrolowany przez grupy i uprawnienia", @@ -47,7 +47,7 @@ "Activate this command by typing \"/{{COMMAND}}\" to chat input.": "Aktywuj tę komendę, wpisując \"/{{COMMAND}}\" w polu czatu.", "Active": "Aktywny", "Active Users": "Aktywni użytkownicy", - "Activity": "", + "Activity": "Aktywność", "Add": "Dodaj", "Add a model ID": "Dodaj identyfikator modelu", "Add a short description about what this model does": "Dodaj krótki opis działania tego modelu", @@ -55,14 +55,14 @@ "Add Arena Model": "Dodaj model Arena", "Add Connection": "Dodaj połączenie", "Add Content": "Dodaj treść", - "Add content here": "Dodaj treść tutaj", + "Add content here": "Dodaj tutaj treść", "Add Custom Parameter": "Dodaj parametr niestandardowy", "Add Custom Prompt": "Dodaj niestandardowy prompt", "Add Details": "Dodaj szczegóły", "Add Files": "Dodaj pliki", "Add Member": "Dodaj członka", "Add Members": "Dodaj członków", - "Add Memory": "Dodaj pamięć", + "Add Memory": "Dodaj wpis do pamięci", "Add Model": "Dodaj model", "Add Reaction": "Dodaj reakcję", "Add Tag": "Dodaj tag", @@ -70,7 +70,7 @@ "Add text content": "Dodaj zawartość tekstową", "Add User": "Dodaj użytkownika", "Add User Group": "Dodaj grupę użytkowników", - "Add webpage": "Dodaj stronę www", + "Add webpage": "Dodaj stronę WWW", "Additional Config": "Dodatkowa konfiguracja", "Additional configuration options for marker. This should be a JSON string with key-value pairs. For example, '{\"key\": \"value\"}'. Supported keys include: disable_links, keep_pageheader_in_output, keep_pagefooter_in_output, filter_blank_pages, drop_repeated_text, layout_coverage_threshold, merge_threshold, height_tolerance, gap_threshold, image_threshold, min_line_length, level_count, default_level": "Dodatkowe opcje konfiguracji dla markera. Powinien to być ciąg JSON z parami klucz-wartość, np. '{\"key\": \"value\"}'. Obsługiwane klucze: disable_links, keep_pageheader_in_output, keep_pagefooter_in_output, filter_blank_pages, drop_repeated_text, layout_coverage_threshold, merge_threshold, height_tolerance, gap_threshold, image_threshold, min_line_length, level_count, default_level.", "Additional Parameters": "Dodatkowe parametry", @@ -78,20 +78,20 @@ "Adjusting these settings will apply changes universally to all users.": "Zmiana tych ustawień wpłynie na wszystkich użytkowników.", "admin": "administrator", "Admin": "Administrator", - "Admin Contact Email": "", + "Admin Contact Email": "Adres e-mail administratora", "Admin Panel": "Panel administracyjny", "Admin Settings": "Ustawienia administratora", "Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "Administratorzy mają zawsze dostęp do wszystkich narzędzi; użytkownicy muszą mieć przypisane narzędzia do modelu w obszarze roboczym.", "Advanced Parameters": "Zaawansowane parametry", "Advanced parameters for MinerU parsing (enable_ocr, enable_formula, enable_table, language, model_version, page_ranges)": "Zaawansowane parametry parsowania MinerU (enable_ocr, enable_formula, enable_table, language, model_version, page_ranges).", "Advanced Params": "Zaawansowane parametry", - "After updating or changing the embedding model, you must reindex the knowledge base for the changes to take effect. You can do this using the \"Reindex\" button below.": "Po aktualizacji lub zmianie modelu embeddingów musisz przeindeksować Bazę wiedzy. Użyj przycisku \"Reindeksuj\" poniżej.", + "After updating or changing the embedding model, you must reindex the knowledge base for the changes to take effect. You can do this using the \"Reindex\" button below.": "Po aktualizacji lub zmianie modelu embeddingów musisz przeindeksować bazę wiedzy. Użyj przycisku \"Reindeksuj\" poniżej.", "AI": "AI", "All": "Wszystkie", - "All chats have been unarchived.": "Wszystkie czaty zostały odarchiwizowane.", + "All chats have been unarchived.": "Wszystkie czaty zostały przywrócone.", "All models deleted successfully": "Wszystkie modele zostały pomyślnie usunięte.", - "Allow Call": "Zezwól na wywoływanie", - "Allow Chat Controls": "Zezwól na kontrolę czatu", + "Allow Call": "Zezwól na rozmowy głosowe", + "Allow Chat Controls": "Zezwól na ustawienia czatu", "Allow Chat Delete": "Zezwól na usuwanie czatu", "Allow Chat Deletion": "Zezwól na usuwanie czatu", "Allow Chat Edit": "Zezwól na edycję czatu", @@ -99,7 +99,7 @@ "Allow Chat Params": "Zezwól na parametry czatu", "Allow Chat Share": "Zezwól na udostępnianie czatu", "Allow Chat System Prompt": "Zezwól na prompt systemowy czatu", - "Allow Chat Valves": "Zezwól na Valves w czacie", + "Allow Chat Valves": "Zezwól na valves w czacie", "Allow Continue Response": "Zezwól na kontynuację odpowiedzi", "Allow Delete Messages": "Zezwól na usuwanie wiadomości", "Allow File Upload": "Zezwól na przesyłanie plików", @@ -107,15 +107,15 @@ "Allow non-local voices": "Zezwól na głosy nielokalne", "Allow Rate Response": "Zezwól na ocenianie odpowiedzi", "Allow Regenerate Response": "Zezwól na regenerację odpowiedzi", - "Allow Speech to Text": "Zezwól na Speech-to-Text", + "Allow Speech to Text": "Zezwól na zamianę mowy na tekst (STT)", "Allow Temporary Chat": "Zezwól na czat tymczasowy", - "Allow Text to Speech": "Zezwól na Text-to-Speech", + "Allow Text to Speech": "Zezwól na syntezę mowy (TTS)", "Allow User Location": "Zezwól na lokalizację użytkownika", - "Allow Voice Interruption in Call": "Zezwól na przerywanie w trakcie wywoływania", + "Allow Voice Interruption in Call": "Zezwól na przerywanie w trakcie rozmowy", "Allowed Endpoints": "Dozwolone punkty końcowe", "Allowed File Extensions": "Dozwolone rozszerzenia plików", "Allowed file extensions for upload. Separate multiple extensions with commas. Leave empty for all file types.": "Dozwolone rozszerzenia plików. Oddziel przecinkami. Pozostaw puste dla wszystkich typów.", - "Already have an account?": "Masz już konto?", + "Already have an account?": "Posiadasz już konto?", "Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out.": "Alternatywa dla top_p, zapewniająca balans między jakością a różnorodnością. Parametr p to minimalne prawdopodobieństwo tokena względem najbardziej prawdopodobnego tokena. Np. przy p=0.05 i max prawdopodobieństwie 0.9, wartości poniżej 0.045 są odrzucane.", "Always": "Zawsze", "Always Collapse Code Blocks": "Zawsze zwijaj bloki kodu", @@ -131,7 +131,7 @@ "and {{COUNT}} more": "i {{COUNT}} więcej", "and create a new shared link.": "i utwórz nowy link udostępniania.", "Android": "Android", - "Anyone": "", + "Anyone": "Każdy", "API Base URL": "Bazowy adres URL API", "API Base URL for Datalab Marker service. Defaults to: https://www.datalab.to/api/v1/marker": "Bazowy adres URL API dla usługi Datalab Marker. Domyślnie: https://www.datalab.to/api/v1/marker", "API Key": "Klucz API", @@ -151,11 +151,11 @@ "Archive All Chats": "Zarchiwizuj wszystkie czaty", "Archived Chats": "Zarchiwizowane czaty", "archived-chat-export": "eksport-zarchiwizowanych-czatow", - "Are you sure you want to clear all memories? This action cannot be undone.": "Czy na pewno chcesz wyczyścić wszystkie wspomnienia? Tej operacji nie można cofnąć.", + "Are you sure you want to clear all memories? This action cannot be undone.": "Czy na pewno chcesz wyczyścić całą pamięć? Tej operacji nie można cofnąć.", "Are you sure you want to delete \"{{NAME}}\"?": "Czy na pewno chcesz usunąć \"{{NAME}}\"?", "Are you sure you want to delete this channel?": "Czy na pewno chcesz usunąć ten kanał?", "Are you sure you want to delete this message?": "Czy na pewno chcesz usunąć tę wiadomość?", - "Are you sure you want to unarchive all archived chats?": "Czy na pewno chcesz odarchiwizować wszystkie czaty?", + "Are you sure you want to unarchive all archived chats?": "Czy na pewno chcesz przywrócić wszystkie czaty?", "Are you sure?": "Czy na pewno?", "Arena Models": "Modele Arena", "Artifacts": "Artefakty", @@ -164,8 +164,8 @@ "Ask a question": "Zadaj pytanie", "Assistant": "Asystent", "Async Embedding Processing": "Asynchroniczne przetwarzanie embeddingów", - "Attach File From Knowledge": "Dołącz plik z Bazy wiedzy", - "Attach Knowledge": "Dołącz Bazę wiedzy", + "Attach File From Knowledge": "Dołącz plik z bazy wiedzy", + "Attach Knowledge": "Dołącz bazę wiedzy", "Attach Notes": "Dołącz notatki", "Attach Webpage": "Dołącz stronę www", "Attention to detail": "Dbałość o szczegóły", @@ -177,7 +177,7 @@ "Authenticate": "Uwierzytelnij", "Authentication": "Uwierzytelnianie", "Auto": "Auto", - "Auto (Random)": "", + "Auto (Random)": "Auto (Losowo)", "Auto-Copy Response to Clipboard": "Automatycznie kopiuj odpowiedź do schowka", "Auto-playback response": "Automatyczne odtwarzanie odpowiedzi", "Autocomplete Generation": "Generowanie autouzupełniania", @@ -186,7 +186,7 @@ "AUTOMATIC1111 Api Auth String": "Ciąg autoryzacji API AUTOMATIC1111", "AUTOMATIC1111 Base URL": "Bazowy adres URL AUTOMATIC1111", "AUTOMATIC1111 Base URL is required.": "Bazowy adres URL AUTOMATIC1111 jest wymagany.", - "Automatically inject system tools in native function calling mode (e.g., timestamps, memory, chat history, notes, etc.)": "", + "Automatically inject system tools in native function calling mode (e.g., timestamps, memory, chat history, notes, etc.)": "Automatycznie wstrzykuj narzędzia systemowe w trybie natywnego wywoływania funkcji (np. znaczniki czasu, pamięć, historia, notatki).", "Available list": "Dostępna lista", "Available Tools": "Dostępne narzędzia", "available users": "dostępni użytkownicy", @@ -203,9 +203,9 @@ "Base Model List Cache speeds up access by fetching base models only at startup or on settings save—faster, but may not show recent base model changes.": "Cache listy modeli bazowych przyspiesza dostęp, pobierając je tylko przy starcie lub zapisie ustawień – szybciej, ale może nie pokazać ostatnich zmian w modelach.", "Bearer": "Bearer", "before": "przed", - "Being lazy": "Bezczynny", + "Being lazy": "Zbyt ogólnikowy", "Beta": "Beta", - "Bing": "", + "Bing": "Bing", "Bing Search V7 Endpoint": "Punkt końcowy Bing Search V7", "Bing Search V7 Subscription Key": "Klucz subskrypcji Bing Search V7", "Bio": "Bio", @@ -214,21 +214,21 @@ "Bocha Search API Key": "Klucz API Bocha Search", "Bold": "Pogrubienie", "Boosting or penalizing specific tokens for constrained responses. Bias values will be clamped between -100 and 100 (inclusive). (Default: none)": "Wzmacnianie lub karanie tokenów. Wartości bias (obciążenia) są ograniczone do zakresu -100 do 100. (Domyślnie: brak)", - "Brave": "", + "Brave": "Brave", "Brave Search API Key": "Klucz API Brave Search", - "Builtin Tools": "", + "Builtin Tools": "Wbudowane narzędzia", "Bullet List": "Lista punktowana", "Button ID": "ID Przycisku", "Button Label": "Etykieta przycisku", "Button Prompt": "Prompt przycisku", - "by {{name}}": "", + "by {{name}}": "przez {{name}}", "By {{name}}": "Przez {{name}}", "Bypass Embedding and Retrieval": "Pomiń Embedding i Retrieval", "Bypass Web Loader": "Pomiń Web Loader", "Cache Base Model List": "Cachuj listę modeli bazowych", "Calendar": "Kalendarz", - "Call": "Wywołanie", - "Call feature is not supported when using Web STT engine": "Funkcja wywołania nie jest obsługiwana przy użyciu silnika Web STT", + "Call": "Rozmowa", + "Call feature is not supported when using Web STT engine": "Funkcja rozmowy nie jest obsługiwana przy użyciu przeglądarkowego silnika STT", "Camera": "Kamera", "Cancel": "Anuluj", "Cannot create an empty note.": "Nie można utworzyć pustej notatki.", @@ -249,8 +249,8 @@ "Character limit for autocomplete generation input": "Limit znaków dla wejścia autouzupełniania", "Chart new frontiers": "Poznawaj nowe możliwości", "Chat": "Czat", - "Chat Background Image": "Obraz tła czatu", - "Chat Bubble UI": "UI dymków czatu", + "Chat Background Image": "Tło czatu", + "Chat Bubble UI": "Wygląd dymków czatu", "Chat Controls": "Ustawienia czatu", "Chat Conversation": "Rozmowa", "Chat direction": "Kierunek czatu", @@ -264,10 +264,10 @@ "Check for updates": "Sprawdź dostępność aktualizacji", "Checking for updates...": "Sprawdzanie aktualizacji...", "Choose a model before saving...": "Wybierz model przed zapisaniem...", - "Chunk Min Size Target": "", + "Chunk Min Size Target": "Docelowy min. rozmiar chunka", "Chunk Overlap": "Chunk Overlap", "Chunk Size": "Chunk Size", - "Chunks smaller than this threshold will be merged with neighboring chunks when possible. Set to 0 to disable merging.": "", + "Chunks smaller than this threshold will be merged with neighboring chunks when possible. Set to 0 to disable merging.": "Fragmenty mniejsze niż ten próg będą łączone z sąsiednimi. Ustaw 0, aby wyłączyć łączenie.", "Ciphers": "Szyfry", "Citation": "Cytat", "Citations": "Cytaty", @@ -303,7 +303,7 @@ "Code Block": "Blok kodu", "Code Editor": "Edytor kodu", "Code execution": "Wykonywanie kodu", - "Code Execution": "", + "Code Execution": "Wykonywanie kodu", "Code Execution Engine": "Silnik wykonywania kodu", "Code Execution Timeout": "Limit czasu wykonywania kodu", "Code formatted successfully": "Sformatowano kod pomyślnie", @@ -346,7 +346,7 @@ "Contact Admin for WebUI Access": "Skontaktuj się z administratorem, aby uzyskać dostęp.", "Content": "Treść", "Content Extraction Engine": "Silnik ekstrakcji treści", - "Content lengths (character counts only)": "", + "Content lengths (character counts only)": "Długość treści (liczba znaków)", "Continue Response": "Kontynuuj odpowiedź", "Continue with {{provider}}": "Kontynuuj przez {{provider}}", "Continue with Email": "Kontynuuj przez Email", @@ -367,7 +367,7 @@ "Copy link": "Kopiuj link", "Copy Link": "Kopiuj link", "Copy to clipboard": "Kopiuj do schowka", - "Copy URL": "", + "Copy URL": "Kopiuj URL", "Copying to clipboard was successful!": "Pomyślnie skopiowano do schowka!", "CORS must be properly configured by the provider to allow requests from Open WebUI.": "Dostawca musi poprawnie skonfigurować CORS, aby zezwolić na żądania z Open WebUI.", "Create": "Utwórz", @@ -391,7 +391,7 @@ "Created At": "Data utworzenia", "Created by": "Utworzone przez", "Created by you": "Utworzone przez Ciebie", - "Created on {{date}}": "", + "Created on {{date}}": "Utworzono {{date}}", "CSV Import": "Import CSV", "Ctrl+Enter to Send": "Ctrl+Enter aby wysłać", "Current Model": "Obecny model", @@ -406,7 +406,7 @@ "Database": "Baza danych", "Datalab Marker API": "API Datalab Marker", "DD/MM/YYYY": "DD/MM/YYYY", - "DDGS Backend": "", + "DDGS Backend": "DDGS Backend", "December": "Grudzień", "Decrease UI Scale": "Zmniejsz skalę UI", "Deepgram": "Deepgram", @@ -447,13 +447,13 @@ "delete this link": "usuń ten link", "Delete tool?": "Usunąć narzędzie?", "Delete User": "Usuń użytkownika", - "Deleted": "", + "Deleted": "Usunięto", "Deleted {{deleteModelTag}}": "Usunięto {{deleteModelTag}}", "Deleted {{name}}": "Usunięto {{name}}", "Deleted User": "Usunięty użytkownik", "Deployment names are required for Azure OpenAI": "Nazwy wdrożeń są wymagane dla Azure OpenAI", "Desc": "Opis", - "Describe your knowledge base and objectives": "Opisz bazę wiedzy i cele", + "Describe your knowledge base and objectives": "Opisz bazę wiedzy i jej cele", "Description": "Opis", "Detect Artifacts Automatically": "Wykrywaj artefakty automatycznie", "Dictate": "Dyktuj", @@ -466,7 +466,7 @@ "Directory selection was cancelled": "Anulowano wybór katalogu", "Disable Code Interpreter": "Wyłącz interpreter kodu", "Disable Image Extraction": "Wyłącz ekstrakcję obrazów", - "Disable image extraction from the PDF. If Use LLM is enabled, images will be automatically captioned. Defaults to False.": "Wyłącz wyciąganie obrazów z PDF. Jeśli używasz LLM, obrazy będą automatycznie opisywane. Domyślnie Fałsz.", + "Disable image extraction from the PDF. If Use LLM is enabled, images will be automatically captioned. Defaults to False.": "Wyłącz wyciąganie obrazów z PDF. Jeśli używasz LLM, obrazy będą automatycznie opisywane. Domyślnie Wyłączone.", "Disabled": "Wyłączone", "Discover a function": "Odkryj funkcję", "Discover a model": "Odkryj model", @@ -489,7 +489,7 @@ "Dive into knowledge": "Zanurz się w wiedzy", "Do not install functions from sources you do not fully trust.": "Nie instaluj funkcji z niezaufanych źródeł.", "Do not install tools from sources you do not fully trust.": "Nie instaluj narzędzi z niezaufanych źródeł.", - "Do you want to sync your usage stats with Open WebUI Community?": "", + "Do you want to sync your usage stats with Open WebUI Community?": "Czy chcesz zsynchronizować statystyki użycia ze społecznością Open WebUI?", "Docling": "Docling", "Docling Parameters": "Parametry Docling", "Docling Server URL required.": "Wymagany URL serwera Docling.", @@ -498,7 +498,7 @@ "Document Intelligence endpoint required.": "Wymagany endpoint Document Intelligence.", "Document Intelligence Model": "Model Document Intelligence", "Documentation": "Dokumentacja", - "Documents": "", + "Documents": "Dokumenty", "does not make any external connections, and your data stays securely on your locally hosted server.": "nie nawiązuje połączeń zewnętrznych, a Twoje dane zostają lokalnie.", "Domain Filter List": "Lista filtrowania domen", "don't fetch random pipelines from sources you don't trust.": "nie pobieraj pipeline'ów z niezaufanych źródeł.", @@ -509,20 +509,20 @@ "Done": "Gotowe", "Download": "Pobierz", "Download & Delete": "Pobierz i usuń", - "Download as JSON": "", + "Download as JSON": "Pobierz jako JSON", "Download as SVG": "Pobierz jako SVG", "Download canceled": "Pobieranie anulowane", "Download Database": "Pobierz bazę danych", - "Downloading stats...": "", - "Draw": "Rysuj", + "Downloading stats...": "Pobieranie statystyk...", + "Draw": "Remis", "Drop any files here to upload": "Upuść pliki tutaj, aby przesłać", - "DuckDuckGo": "", + "DuckDuckGo": "DuckDuckGo", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "np. '30s','10m'. Jednostki: 's' (sek), 'm' (min), 'h' (godz).", "e.g. \"json\" or a JSON schema": "np. \"json\" lub schemat JSON", "e.g. 60": "np. 60", "e.g. A filter to remove profanity from text": "np. Filtr usuwający wulgaryzmy", "e.g. about the Roman Empire": "np. o Imperium Rzymskim", - "e.g. alloy, echo, shimmer": "", + "e.g. alloy, echo, shimmer": "np. stal, echo, poświata", "e.g. en": "np. pl", "e.g. My Filter": "np. Mój Filtr", "e.g. My Tools": "np. Moje Narzędzia", @@ -551,7 +551,7 @@ "edited": "edytowano", "Edited": "Edytowano", "Editing": "Edytowanie", - "Eject": "Wysuń (Odładuj)", + "Eject": "Odładuj", "ElevenLabs": "ElevenLabs", "Email": "Email", "Embark on adventures": "Wyrusz na przygodę", @@ -579,11 +579,11 @@ "Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "Upewnij się, że plik CSV ma 4 kolumny: Nazwa, Email, Hasło, Rola.", "Enter {{role}} message here": "Wpisz wiadomość roli {{role}} tutaj", "Enter a detail about yourself for your LLMs to recall": "Wpisz szczegóły o sobie, aby LLM je zapamiętał", - "Enter a title for the pending user info overlay. Leave empty for default.": "Wpisz tytuł ekranu oczekującego użytkownika. Zostaw puste dla domyślnego.", + "Enter a title for the pending user info overlay. Leave empty for default.": "Wpisz tytuł nakładki informacyjnej dla użytkownika oczekującego na aktywację. Zostaw puste dla domyślnego.", "Enter a watermark for the response. Leave empty for none.": "Wpisz znak wodny odpowiedzi. Zostaw puste dla braku.", - "Enter additional headers in JSON format": "Wprowadź dodatkowe nagłówki (JSON)", + "Enter additional headers in JSON format": "Wprowadź dodatkowe nagłówki w formacie JSON", "Enter additional headers in JSON format (e.g. {\"X-Custom-Header\": \"value\"}": "Wprowadź nagłówki w JSON (np. {\"X-Custom-Header\": \"value\"})", - "Enter additional parameters in JSON format": "Wprowadź dodatkowe parametry (JSON)", + "Enter additional parameters in JSON format": "Wprowadź dodatkowe parametry w formacie JSON", "Enter api auth string (e.g. username:password)": "Wprowadź ciąg auth API (np. user:pass)", "Enter Application DN": "Wprowadź DN aplikacji", "Enter Application DN Password": "Wprowadź hasło DN aplikacji", @@ -592,31 +592,31 @@ "Enter Bocha Search API Key": "Wprowadź klucz API Bocha Search", "Enter Brave Search API Key": "Wprowadź klucz API Brave Search", "Enter certificate path": "Wprowadź ścieżkę certyfikatu", - "Enter Chunk Min Size Target": "", + "Enter Chunk Min Size Target": "Docelowy min. rozmiar chunka", "Enter Chunk Overlap": "Wprowadź Chunk Overlap", "Enter Chunk Size": "Wprowadź Chunk Size", "Enter comma-separated \"token:bias_value\" pairs (example: 5432:100, 413:-100)": "Wprowadź pary \"token:bias\" po przecinku (np. 5432:100, 413:-100)", - "Enter content for the pending user info overlay. Leave empty for default.": "Wprowadź treść ekranu oczekiwania. Zostaw puste dla domyślnej.", + "Enter content for the pending user info overlay. Leave empty for default.": "Wpisz treść nakładki informacyjnej. Zostaw puste dla domyślnej.", "Enter coordinates (e.g. 51.505, -0.09)": "Wprowadź współrzędne (np. 51.505, -0.09)", "Enter Datalab Marker API Base URL": "Wprowadź Base URL Datalab Marker API", "Enter Datalab Marker API Key": "Wprowadź klucz API Datalab Marker", "Enter description": "Wprowadź opis", "Enter Docling API Key": "Wprowadź klucz API Docling", "Enter Docling Server URL": "Wprowadź URL serwera Docling", - "Enter Document Intelligence Endpoint": "Wprowadź endpoint Document Intelligence", + "Enter Document Intelligence Endpoint": "Wprowadź punkt końcowy Document Intelligence", "Enter Document Intelligence Key": "Wprowadź klucz Document Intelligence", "Enter Document Intelligence Model": "Wprowadź model Document Intelligence", - "Enter domains separated by commas (e.g., example.com,site.org,!excludedsite.com)": "Wprowadź domeny po przecinku (np. example.com,!exclude.com)", + "Enter domains separated by commas (e.g., example.com,site.org,!excludedsite.com)": "Wprowadź domeny oddzielone przecinkami (np. example.com,!exclude.com)", "Enter Exa API Key": "Wprowadź klucz API Exa", - "Enter External Document Loader API Key": "Wprowadź klucz API External Document Loader", - "Enter External Document Loader URL": "Wprowadź URL External Document Loader", - "Enter External Web Loader API Key": "Wprowadź klucz API External Web Loader", - "Enter External Web Loader URL": "Wprowadź URL External Web Loader", - "Enter External Web Search API Key": "Wprowadź klucz API External Web Search", - "Enter External Web Search URL": "Wprowadź URL External Web Search", - "Enter Firecrawl API Base URL": "Wprowadź Base URL Firecrawl API", + "Enter External Document Loader API Key": "Wprowadź klucz API zewnętrznego silnika ładowania dokumentów", + "Enter External Document Loader URL": "Wprowadź URL zewnętrznego silnika ładowania dokumentów", + "Enter External Web Loader API Key": "Wprowadź klucz API zewnętrznego silnika ładowania stron", + "Enter External Web Loader URL": "Wprowadź URL zewnętrznego silnika ładowania stron", + "Enter External Web Search API Key": "Wprowadź klucz API zewnętrznego wyszukiwania WWW", + "Enter External Web Search URL": "Wprowadź URL zewnętrznego wyszukiwania WWW", + "Enter Firecrawl API Base URL": "Wprowadź bazowy adres URL API Firecrawl", "Enter Firecrawl API Key": "Wprowadź klucz API Firecrawl", - "Enter Firecrawl Timeout": "", + "Enter Firecrawl Timeout": "Wprowadź limit czasu Firecrawl", "Enter folder name": "Wprowadź nazwę folderu", "Enter function name filter list (e.g. func1, !func2)": "Wprowadź listę filtrów funkcji (np. func1, !func2)", "Enter Github Raw URL": "Wprowadź Github Raw URL", @@ -625,7 +625,7 @@ "Enter hex color (e.g. #FF0000)": "Wprowadź kolor hex (np. #FF0000)", "Enter ID": "Wprowadź ID", "Enter Image Size (e.g. 512x512)": "Wprowadź rozmiar obrazu (np. 512x512)", - "Enter Jina API Base URL": "", + "Enter Jina API Base URL": "Wprowadź Jina API Base URL", "Enter Jina API Key": "Wprowadź klucz API Jina", "Enter JSON config (e.g., {\"disable_links\": true})": "Wprowadź konfigurację JSON (np. {\"disable_links\": true})", "Enter Jupyter Password": "Wprowadź hasło Jupyter", @@ -634,7 +634,7 @@ "Enter Kagi Search API Key": "Wprowadź klucz API Kagi Search", "Enter Key Behavior": "Zachowanie klawisza Enter", "Enter language codes": "Wprowadź kody języków", - "Enter MinerU API Key": "", + "Enter MinerU API Key": "Wprowadź klucz MinerU API", "Enter Mistral API Base URL": "Wprowadź Base URL Mistral API", "Enter Mistral API Key": "Wprowadź klucz API Mistral", "Enter Model ID": "Wprowadź ID modelu", @@ -746,7 +746,7 @@ "External Web Loader URL": "URL External Web Loader", "External Web Search API Key": "Klucz API External Web Search", "External Web Search URL": "URL External Web Search", - "Fade Effect for Streaming Text": "Efekt zanikania dla strumieniowanego tekstu", + "Fade Effect for Streaming Text": "Efekt zanikania generowanego tekstu", "Failed to add file.": "Nie udało się dodać pliku.", "Failed to add members": "Nie udało się dodać członków", "Failed to clear status": "Nie udało się wyczyścić statusu", @@ -760,7 +760,7 @@ "Failed to generate title": "Nie udało się wygenerować tytułu", "Failed to import models": "Nie udało się zaimportować modeli", "Failed to load chat preview": "Nie udało się załadować podglądu czatu", - "Failed to load Excel/CSV file. Please try downloading it instead.": "", + "Failed to load Excel/CSV file. Please try downloading it instead.": "Nie udało się załadować pliku Excel/CSV. Spróbuj go pobrać.", "Failed to load file content.": "Nie udało się załadować zawartości pliku.", "Failed to move chat": "Nie udało się przenieść czatu", "Failed to process URL: {{url}}": "Nie udało się przetworzyć URL: {{url}}", @@ -777,7 +777,7 @@ "Features": "Funkcje", "Features Permissions": "Uprawnienia funkcji", "February": "Luty", - "Feedback": "", + "Feedback": "Opinia", "Feedback deleted successfully": "Opinia usunięta pomyślnie", "Feedback Details": "Szczegóły opinii", "Feedback History": "Historia opinii", @@ -786,7 +786,7 @@ "File": "Plik", "File added successfully.": "Plik dodany pomyślnie.", "File content updated successfully.": "Treść pliku zaktualizowana pomyślnie.", - "File Context": "", + "File Context": "Kontekst pliku", "File Mode": "Tryb pliku", "File not found.": "Plik nie znaleziony.", "File removed successfully.": "Plik usunięty pomyślnie.", @@ -802,22 +802,22 @@ "Fingerprint spoofing detected: Unable to use initials as avatar. Defaulting to default profile image.": "Wykryto spoofing (Fingerprint): Nie można użyć inicjałów jako awatara. Używam domyślnego obrazka.", "Firecrawl API Base URL": "Base URL Firecrawl API", "Firecrawl API Key": "Klucz API Firecrawl", - "Firecrawl Timeout (s)": "", - "Floating Quick Actions": "Pływające szybkie akcje", + "Firecrawl Timeout (s)": "Timeout Firecrawl (s)", + "Floating Quick Actions": "Podręczne szybkie akcje", "Focus Chat Input": "Skupienie na polu czatu", "Folder": "Folder", "Folder Background Image": "Tło folderu", "Folder deleted successfully": "Folder usunięty pomyślnie", - "Folder Max File Count": "", + "Folder Max File Count": "Maks. liczba plików w folderze", "Folder Name": "Nazwa folderu", "Folder name cannot be empty.": "Nazwa folderu nie może być pusta.", "Folder name updated successfully": "Nazwa folderu zaktualizowana pomyślnie", "Folder updated successfully": "Folder zaktualizowany pomyślnie", "Folders": "Foldery", - "Follow up": "Kontynuacja", - "Follow Up Generation": "Generowanie pytań kontynuacyjnych", - "Follow Up Generation Prompt": "Prompt generowania kontynuacji", - "Follow-Up Auto-Generation": "Automatyczne generowanie kontynuacji", + "Follow up": "Pytania nawiązujące", + "Follow Up Generation": "Generowanie pytań nawiązujących", + "Follow Up Generation Prompt": "Prompt generowania pytań nawiązujących", + "Follow-Up Auto-Generation": "Automatyczne generowanie pytań nawiązujących", "Followed instructions perfectly": "Instrukcje wykonane idealnie", "Force OCR": "Wymuś OCR", "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "Wymuś OCR na wszystkich stronach PDF. Może pogorszyć wyniki, jeśli PDF ma już dobry tekst. Domyślnie Fałsz.", @@ -863,13 +863,13 @@ "Get started with {{WEBUI_NAME}}": "Rozpocznij z {{WEBUI_NAME}}", "Global": "Globalne", "Good Response": "Dobra odpowiedź", - "Google": "", + "Google": "Google", "Google Drive": "Google Drive", "Google PSE API Key": "Klucz API Google PSE", "Google PSE Engine Id": "ID silnika Google PSE", "Gravatar": "Gravatar", "Grid": "Siatka", - "Grokipedia": "", + "Grokipedia": "Grokipedia", "Group": "Grupa", "Group Channel": "Kanał grupowy", "Group created successfully": "Grupa utworzona pomyślnie", @@ -906,8 +906,8 @@ "I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "Potwierdzam, że rozumiem konsekwencje. Jestem świadomy ryzyka wykonywania dowolnego kodu i zweryfikowałem zaufanie do źródła.", "ID": "ID", "ID cannot contain \":\" or \"|\" characters": "ID nie może zawierać \":\" ani \"|\"", - "iframe Sandbox Allow Forms": "iframe Sandbox Allow Forms", - "iframe Sandbox Allow Same Origin": "iframe Sandbox Allow Same Origin", + "iframe Sandbox Allow Forms": "Zezwól na formularze w iframe", + "iframe Sandbox Allow Same Origin": "Zezwól na 'Same Origin' w iframe", "Ignite curiosity": "Rozpal ciekawość", "Image": "Obraz", "Image Compression": "Kompresja obrazu", @@ -923,7 +923,7 @@ "Image Prompt Generation": "Generowanie promptu dla obrazu", "Image Prompt Generation Prompt": "Prompt generujący prompt dla obrazu", "Image Size": "Rozmiar obrazu", - "Images": "", + "Images": "Obrazy", "Import": "Importuj", "Import Chats": "Importuj czaty", "Import Config from JSON File": "Importuj konfigurację z JSON", @@ -942,21 +942,21 @@ "Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive.": "Wpływa na szybkość reakcji algorytmu na feedback. Niższy 'learning rate' to wolniejsze zmiany, wyższy to szybsza reakcja.", "Info": "Info", "Initials": "Inicjały", - "Inject file content into conversation context": "", - "Inject the entire content as context for comprehensive processing, this is recommended for complex queries.": "Wstrzyknij całą treść jako kontekst (zalecane dla złożonych zapytań).", + "Inject file content into conversation context": "Dołącz treść pliku do kontekstu rozmowy", + "Inject the entire content as context for comprehensive processing, this is recommended for complex queries.": "Dołącz całą treść jako kontekst (zalecane dla złożonych zapytań).", "Input": "Wejście", "Input Key (e.g. text, unet_name, steps)": "Klucz wejściowy (np. text, unet_name, steps)", "Input Variables": "Zmienne wejściowe", "Insert": "Wstaw", "Insert Follow-Up Prompt to Input": "Wstaw prompt kontynuacji do wejścia", - "Insert Prompt as Rich Text": "Wstaw prompt jako Rich Text", + "Insert Prompt as Rich Text": "Wstaw prompt jako sformatowany tekst", "Insert Suggestion Prompt to Input": "Wstaw sugerowany prompt do wejścia", "Install from Github URL": "Zainstaluj z URL Githuba", - "Instant Auto-Send After Voice Transcription": "Natychmiastowe wysyłanie po transkrypcji głosu", + "Instant Auto-Send After Voice Transcription": "Wyślij natychmiast po transkrypcji głosu", "Integration": "Integracja", "Integrations": "Integracje", "Interface": "Interfejs", - "Interface Settings Access": "", + "Interface Settings Access": "Dostęp do ustawień interfejsu", "Invalid file content": "Nieprawidłowa zawartość pliku", "Invalid file format.": "Nieprawidłowy format pliku.", "Invalid JSON file": "Nieprawidłowy plik JSON", @@ -970,7 +970,7 @@ "is typing...": "pisze...", "Italic": "Kursywa", "January": "Styczeń", - "Jina API Base URL": "", + "Jina API Base URL": "Jina API Base URL", "Jina API Key": "Klucz API Jina", "join our Discord for help.": "dołącz do Discorda po pomoc.", "JSON": "JSON", @@ -980,7 +980,7 @@ "June": "Czerwiec", "Jupyter Auth": "Autoryzacja Jupyter", "Jupyter URL": "URL Jupyter", - "JWT Expiration": "Wygaśnięcie JWT", + "JWT Expiration": "Wygasanie tokena JWT", "JWT Token": "Token JWT", "Kagi Search API Key": "Klucz API Kagi Search", "Keep Follow-Up Prompts in Chat": "Zachowaj prompty kontynuacji w czacie", @@ -994,17 +994,17 @@ "Knowledge Base": "Baza wiedzy", "Knowledge created successfully.": "Wiedza utworzona pomyślnie.", "Knowledge deleted successfully.": "Wiedza usunięta pomyślnie.", - "Knowledge Description": "Opis Wiedzy", - "Knowledge exported successfully": "", - "Knowledge Name": "Nazwa Wiedzy", - "Knowledge Public Sharing": "Publiczne udostępnianie Wiedzy", + "Knowledge Description": "Opis wiedzy", + "Knowledge exported successfully": "Wiedza wyeksportowana pomyślnie", + "Knowledge Name": "Nazwa wiedzy", + "Knowledge Public Sharing": "Publiczne udostępnianie wiedzy", "Knowledge reset successfully.": "Wiedza zresetowana pomyślnie.", - "Knowledge Sharing": "Udostępnianie Wiedzy", + "Knowledge Sharing": "Udostępnianie wiedzy", "Knowledge updated successfully": "Wiedza zaktualizowana pomyślnie", "Kokoro.js (Browser)": "Kokoro.js (Przeglądarka)", "Kokoro.js Dtype": "Typ danych Kokoro.js", "Label": "Etykieta", - "Landing Page Mode": "Tryb Landing Page", + "Landing Page Mode": "Tryb strony startowej", "Language": "Język", "Language Locales": "Lokalizacje językowe", "Last Active": "Ostatnio aktywny", @@ -1022,7 +1022,7 @@ "Leave empty to include all models from \"{{url}}/api/tags\" endpoint": "Zostaw puste, aby dołączyć wszystkie modele z \"{{url}}/api/tags\"", "Leave empty to include all models from \"{{url}}/models\" endpoint": "Zostaw puste, aby dołączyć wszystkie modele z \"{{url}}/models\"", "Leave empty to include all models or select specific models": "Zostaw puste, aby uwzględnić wszystkie, lub wybierz konkretne", - "Leave empty to use first admin user": "", + "Leave empty to use first admin user": "Pozostaw puste, aby użyć konta pierwszego administratora", "Leave empty to use the default model (voxtral-mini-latest).": "Zostaw puste, aby użyć domyślnego modelu (voxtral-mini-latest).", "Leave empty to use the default prompt, or enter a custom prompt": "Zostaw puste dla domyślnego, lub wpisz własny", "Leave model field empty to use the default model.": "Zostaw puste, aby użyć modelu domyślnego.", @@ -1062,13 +1062,13 @@ "Manage your account information.": "Zarządzaj informacjami o koncie.", "March": "Marzec", "Markdown": "Markdown", - "Markdown Header Text Splitter": "", + "Markdown Header Text Splitter": "Markdown Header Text Splitter", "Max Speakers": "Maks. mówców", "Max Upload Count": "Maks. liczba plików", "Max Upload Size": "Maks. rozmiar pliku", - "Maximum number of files allowed per folder.": "", - "Maximum number of files per folder is {{max}}.": "", - "Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maksymalnie 3 modele mogą być pobierane jednocześnie. Spróbuj później.", + "Maximum number of files allowed per folder.": "Maksymalna liczba plików dozwolona w jednym folderze.", + "Maximum number of files per folder is {{max}}.": "Maksymalna liczba plików w folderze wynosi {{max}}.", + "Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maksymalnie 3 modele mogą być pobierane jednocześnie. Spróbuj ponownie później.", "May": "Maj", "MBR": "MBR", "MCP": "MCP", @@ -1077,17 +1077,17 @@ "Member removed successfully": "Członek usunięty pomyślnie", "Members": "Członkowie", "Members added successfully": "Członkowie dodani pomyślnie", - "Memories": "", - "Memories accessible by LLMs will be shown here.": "Wspomnienia dostępne dla LLM pojawią się tutaj.", + "Memories": "Pamięć", + "Memories accessible by LLMs will be shown here.": "Informacje z pamięci dostępne dla LLM pojawią się tutaj.", "Memory": "Pamięć", - "Memory added successfully": "Wspomnienie dodane pomyślnie", + "Memory added successfully": "Wpis pamięci dodany pomyślnie", "Memory cleared successfully": "Pamięć wyczyszczona pomyślnie", - "Memory deleted successfully": "Wspomnienie usunięte pomyślnie", - "Memory updated successfully": "Wspomnienie zaktualizowane pomyślnie", + "Memory deleted successfully": "Wpis pamięci usunięty pomyślnie", + "Memory updated successfully": "Wpis pamięci zaktualizowany pomyślnie", "Merge Responses": "Połącz odpowiedzi", "Merged Response": "Połączona odpowiedź", "Message": "Wiadomość", - "Message counts and response timestamps": "", + "Message counts and response timestamps": "Liczba wiadomości i znaczniki czasu odpowiedzi", "Message rating should be enabled to use this feature": "Ocenianie wiadomości musi być włączone, aby użyć tej funkcji", "Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "Wiadomości wysłane po utworzeniu linku nie będą udostępniane. Użytkownicy z linkiem zobaczą udostępniony czat.", "Microsoft OneDrive": "Microsoft OneDrive", @@ -1120,11 +1120,11 @@ "Model Name": "Nazwa modelu", "Model name already exists, please choose a different one": "Nazwa modelu już istnieje, wybierz inną", "Model Name is required.": "Nazwa modelu jest wymagana.", - "Model names and usage frequency": "", + "Model names and usage frequency": "Nazwy modeli i częstotliwość użycia", "Model not selected": "Nie wybrano modelu", "Model Params": "Parametry modelu", "Model Permissions": "Uprawnienia modelu", - "Model responses or outputs": "", + "Model responses or outputs": "Odpowiedzi lub wyniki modelu", "Model unloaded successfully": "Model odładowany pomyślnie", "Model updated successfully": "Model zaktualizowany pomyślnie", "Model(s) do not support file upload": "Model(e) nie obsługują przesyłania plików", @@ -1135,7 +1135,7 @@ "Models imported successfully": "Modele zaimportowane pomyślnie", "Models Public Sharing": "Publiczne udostępnianie modeli", "Models Sharing": "Udostępnianie modeli", - "Mojeek": "", + "Mojeek": "Mojeek", "Mojeek Search API Key": "Klucz API Mojeek Search", "More": "Więcej", "More Concise": "Bardziej zwięzły", @@ -1157,10 +1157,10 @@ "New Prompt": "Nowy prompt", "New Temporary Chat": "Nowy czat tymczasowy", "New Tool": "Nowe narzędzie", - "New Webhook": "", + "New Webhook": "Nowy webhook", "new-channel": "nowy-kanal", "Next message": "Następna wiadomość", - "No activity data": "", + "No activity data": "Brak danych aktywności", "No authentication": "Brak autoryzacji", "No chats found": "Nie znaleziono czatów", "No chats found for this user.": "Nie znaleziono czatów dla tego użytkownika.", @@ -1169,9 +1169,9 @@ "No content found": "Nie znaleziono treści", "No content to speak": "Brak treści do wymówienia", "No conversation to save": "Brak rozmowy do zapisania", - "No distance available": "Brak dostępnego dystansu", - "No expiration can pose security risks.": "Brak wygaśnięcia może stanowić ryzyko bezpieczeństwa.", - "No feedback found": "", + "No distance available": "Brak wyniku dopasowania", + "No expiration can pose security risks.": "Brak wygasania może stanowić ryzyko bezpieczeństwa.", + "No feedback found": "Nie znaleziono informacji zwrotnej", "No file selected": "Nie wybrano pliku", "No files in this knowledge base.": "Brak plików w tej bazie wiedzy.", "No functions found": "Nie znaleziono funkcji", @@ -1180,13 +1180,13 @@ "No inference engine with management support found": "Nie znaleziono silnika wnioskowania ze wsparciem zarządzania", "No knowledge bases found.": "Nie znaleziono baz wiedzy.", "No knowledge found": "Nie znaleziono wiedzy", - "No memories to clear": "Brak wspomnień do wyczyszczenia", + "No memories to clear": "Brak danych w pamięci do wyczyszczenia", "No model IDs": "Brak ID modeli", "No models found": "Nie znaleziono modeli", "No models selected": "Nie wybrano modeli", "No Notes": "Brak notatek", "No notes found": "Nie znaleziono notatek", - "No one": "", + "No one": "Nikt", "No pinned messages": "Brak przypiętych wiadomości", "No prompts found": "Nie znaleziono promptów", "No results": "Brak wyników", @@ -1197,10 +1197,10 @@ "No suggestion prompts": "Brak sugerowanych promptów", "No tools found": "Nie znaleziono narzędzi", "No users were found.": "Nie znaleziono użytkowników.", - "No valves": "Brak Valves", - "No valves to update": "Brak zaworów do aktualizacji", - "No webhooks yet": "", - "Node Ids": "ID Węzłów", + "No valves": "Brak valves", + "No valves to update": "Brak valves do aktualizacji", + "No webhooks yet": "Brak webhooków", + "Node Ids": "ID węzłów", "None": "Brak", "Not factually correct": "Merytorycznie niepoprawne", "Not helpful": "Niepomocne", @@ -1211,8 +1211,8 @@ "Notes": "Notatki", "Notes Public Sharing": "Publiczne udostępnianie notatek", "Notes Sharing": "Udostępnianie notatek", - "Notification Sound": "Dźwięk powiadomienia", - "Notification Webhook": "Webhook powiadomień", + "Notification Sound": "Dźwięk powiadomień", + "Notification Webhook": "Powiadomienia webhook", "Notifications": "Powiadomienia", "November": "Listopad", "OAuth": "OAuth", @@ -1239,7 +1239,7 @@ "Only invited users can access": "Tylko zaproszeni użytkownic mają dostęp", "Only markdown files are allowed": "Tylko pliki markdown są dozwolone", "Only select users and groups with permission can access": "Tylko wybrani użytkownicy z uprawnieniami mają dostęp", - "Only sync new/updated chats": "", + "Only sync new/updated chats": "Synchronizuj tylko nowe/zaktualizowane czaty", "Oops! Looks like the URL is invalid. Please double-check and try again.": "Ups! URL wygląda na nieprawidłowy. Sprawdź i spróbuj ponownie.", "Oops! There are files still uploading. Please wait for the upload to complete.": "Ups! Pliki wciąż się przesyłają. Poczekaj na zakończenie.", "Oops! There was an error in the previous response.": "Ups! Wystąpił błąd w poprzedniej odpowiedzi.", @@ -1256,7 +1256,7 @@ "Open WebUI can use tools provided by any OpenAPI server.": "Open WebUI może używać narzędzi z dowolnego serwera OpenAPI.", "Open WebUI uses faster-whisper internally.": "Open WebUI używa wewnętrznie faster-whisper.", "Open WebUI uses SpeechT5 and CMU Arctic speaker embeddings.": "Open WebUI używa SpeechT5 i embeddingów CMU Arctic.", - "Open WebUI version": "", + "Open WebUI version": "Wersja Open WebUI", "Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "Wersja Open WebUI (v{{OPEN_WEBUI_VERSION}}) jest niższa niż wymagana (v{{REQUIRED_VERSION}})", "OpenAI": "OpenAI", "OpenAI API": "API OpenAI", @@ -1281,8 +1281,8 @@ "page": "strona", "Paginate": "Stronicowanie", "Parameters": "Parametry", - "Parent message not found": "", - "Participate in community leaderboards and evaluations! Syncing aggregated usage stats helps drive research and improvements to Open WebUI. Your privacy is paramount: no message content is ever shared.": "", + "Parent message not found": "Nie znaleziono wiadomości nadrzędnej", + "Participate in community leaderboards and evaluations! Syncing aggregated usage stats helps drive research and improvements to Open WebUI. Your privacy is paramount: no message content is ever shared.": "Weź udział w rankingach społeczności! Synchronizacja zagregowanych statystyk pomaga w rozwoju Open WebUI. Twoja prywatność jest najważniejsza: treść wiadomości nigdy nie jest udostępniana.", "Password": "Hasło", "Passwords do not match.": "Hasła nie pasują do siebie.", "Paste Large Text as File": "Wklej duży tekst jako plik", @@ -1290,8 +1290,8 @@ "PDF Extract Images (OCR)": "Wyodrębnij obrazy z PDF (OCR)", "pending": "oczekuje", "Pending": "Oczekujące", - "Pending User Overlay Content": "Treść ekranu oczekującego użytkownika", - "Pending User Overlay Title": "Tytuł ekranu oczekującego użytkownika", + "Pending User Overlay Content": "Treść nakładki dla oczekującego użytkownika", + "Pending User Overlay Title": "Tytuł nakładki dla oczekującego użytkownika", "Permission denied when accessing media devices": "Odmowa dostępu do urządzeń multimedialnych", "Permission denied when accessing microphone": "Odmowa dostępu do mikrofonu", "Permission denied when accessing microphone: {{error}}": "Odmowa dostępu do mikrofonu: {{error}}", @@ -1304,11 +1304,11 @@ "Pin": "Przypnij", "Pinned": "Przypięte", "Pinned Messages": "Przypięte wiadomości", - "Pioneer insights": "Odkrywaj nowe wglądy", + "Pioneer insights": "Przełomowe wnioski", "Pipe": "Pipe", "Pipeline deleted successfully": "Pipeline usunięty pomyślnie", "Pipeline downloaded successfully": "Pipeline pobrany pomyślnie", - "Pipelines": "", + "Pipelines": "Pipelines", "Pipelines are a plugin system with arbitrary code execution —": "Pipelines to system wtyczek z wykonywaniem dowolnego kodu —", "Pipelines Not Detected": "Nie wykryto Pipeline'ów", "Pipelines Valves": "Pipelines Valves", @@ -1367,7 +1367,7 @@ "Quick Actions": "Szybkie akcje", "RAG Template": "Szablon RAG", "Rating": "Ocena", - "Re-rank models by topic similarity": "Re-rank models by topic similarity", + "Re-rank models by topic similarity": "Rerankowanie modeli wg podobieństwa tematycznego", "Read": "Czytaj", "Read Aloud": "Czytaj na głos", "Read more →": "Czytaj więcej →", @@ -1479,7 +1479,7 @@ "Searched {{count}} sites": "Przeszukano {{count}} stron", "Searching": "Wyszukiwanie", "Searching \"{{searchQuery}}\"": "Szukanie \"{{searchQuery}}\"", - "Searching Knowledge for \"{{searchQuery}}\"": "Przeszukiwanie Wiedzy dla \"{{searchQuery}}\"", + "Searching Knowledge for \"{{searchQuery}}\"": "Przeszukiwanie wiedzy dla \"{{searchQuery}}\"", "Searching the web": "Przeszukiwanie sieci...", "Searxng Query URL": "URL zapytania Searxng", "Searxng search language (all, en, es, de, fr, etc.)": "Język wyszukiwania Searxng (all, en, pl, de...)", @@ -1547,7 +1547,7 @@ "Sets the stop sequences to use. When this pattern is encountered, the LLM will stop generating text and return. Multiple stop patterns may be set by specifying multiple separate stop parameters in a modelfile.": "Ustawia sekwencje stop. Gdy wystąpią, LLM przerywa generowanie.", "Setting": "Ustawienie", "Settings": "Ustawienia", - "Settings Permissions": "", + "Settings Permissions": "Uprawnienia ustawień", "Settings saved successfully!": "Ustawienia zapisane pomyślnie!", "Share": "Udostępnij", "Share Chat": "Udostępnij czat", @@ -1589,9 +1589,9 @@ "Source": "Źródło", "Speech Playback Speed": "Prędkość odtwarzania mowy", "Speech recognition error: {{error}}": "Błąd rozpoznawania mowy: {{error}}", - "Speech-to-Text": "Speech-to-Text", - "Speech-to-Text Engine": "Silnik Speech-to-Text", - "Split documents by markdown headers before applying character/token splitting.": "", + "Speech-to-Text": "Silnik zamiany mowy na tekst (STT)", + "Speech-to-Text Engine": "Silnik zamiany mowy na tekst (STT)", + "Split documents by markdown headers before applying character/token splitting.": "Podziel dokumenty według nagłówków markdown przed podziałem na znaki/tokeny.", "Start a new conversation": "Rozpocznij nową rozmowę", "Start of the channel": "Początek kanału", "Start Tag": "Tag startowy", @@ -1602,7 +1602,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Kroki (Steps)", "Stop": "Przerwij", - "Stop Download": "", + "Stop Download": "Zatrzymaj pobieranie", "Stop Generating": "Przerwij generowanie", "Stop Sequence": "Sekwencja stop", "Stream Chat Response": "Strumieniuj odpowiedź czatu", @@ -1623,14 +1623,14 @@ "Support": "Wsparcie", "Support this plugin:": "Wesprzyj ten plugin:", "Supported MIME Types": "Obsługiwane typy MIME", - "Sync": "", - "Sync Complete!": "", + "Sync": "Synchronizuj", + "Sync Complete!": "Synchronizacja zakończona!", "Sync directory": "Katalog synchronizacji", - "Sync Failed": "", - "Sync Usage Stats": "", - "Syncing stats...": "", - "Syncing...": "", - "Syncs only chats with updates after your last sync timestamp. Disable to re-sync all chats.": "", + "Sync Failed": "Synchronizacja nieudana", + "Sync Usage Stats": "Synchronizuj statystyki użycia", + "Syncing stats...": "Synchronizowanie statystyk...", + "Syncing...": "Synchronizowanie...", + "Syncs only chats with updates after your last sync timestamp. Disable to re-sync all chats.": "Synchronizuje tylko czaty zaktualizowane po ostatniej synchronizacji. Wyłącz, aby zsynchronizować wszystkie.", "System": "System", "System Instructions": "Instrukcje systemowe", "System Prompt": "Prompt systemowy", @@ -1647,12 +1647,12 @@ "Tavily API Key": "Klucz API Tavily", "Tavily Extract Depth": "Tavily Extract Depth", "Tell us more:": "Powiedz nam więcej:", - "Temperature": "Temperature", + "Temperature": "Temperatura", "Temporary Chat": "Czat tymczasowy", "Temporary Chat by Default": "Domyślnie czat tymczasowy", "Text Splitter": "Text Splitter", - "Text-to-Speech": "Text-to-Speech", - "Text-to-Speech Engine": "Silnik Text-to-Speech", + "Text-to-Speech": "Silnik syntezy mowy (TTS)", + "Text-to-Speech Engine": "Silnik syntezy mowy (TTS)", "Thanks for your feedback!": "Dzięki za opinię!", "The Application Account DN you bind with for search": "DN konta aplikacji do wyszukiwania", "The base to search for users": "Baza wyszukiwania użytkowników", @@ -1675,7 +1675,7 @@ "The Weight of BM25 Hybrid Search. 0 more semantic, 1 more lexical. Default 0.5": "Waga BM25 w wyszukiwaniu hybrydowym. 0 = semantyczne, 1 = leksykalne. Domyślnie 0.5", "The width in pixels to compress images to. Leave empty for no compression.": "Szerokość (px) do kompresji obrazów. Zostaw puste dla braku kompresji.", "Theme": "Motyw", - "There was an error syncing your stats. Please try again.": "", + "There was an error syncing your stats. Please try again.": "Wystąpił błąd podczas synchronizacji statystyk. Spróbuj ponownie.", "Thinking...": "Myślę...", "This action cannot be undone. Do you wish to continue?": "Tej akcji nie można cofnąć. Kontynuować?", "This channel was created on {{createdAt}}. This is the very beginning of the {{channelName}} channel.": "Ten kanał utworzono {{createdAt}}. To początek kanału {{channelName}}.", @@ -1714,7 +1714,7 @@ "To access the available model names for downloading,": "Aby zobaczyć nazwy modeli do pobrania,", "To access the GGUF models available for downloading,": "Aby zobaczyć modele GGUF do pobrania,", "To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Aby uzyskać dostęp, skontaktuj się z administratorem.", - "To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "Aby dołączyć Bazę wiedzy, dodaj ją najpierw w obszarze \"Knowledge\".", + "To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "Aby dołączyć Bazę wiedzy, dodaj ją najpierw w obszarze \"Wiedza\".", "To learn more about available endpoints, visit our documentation.": "Odwiedź dokumentację, aby poznać dostępne endpointy.", "To learn more about powerful prompt variables, click here": "Kliknij tutaj, aby poznać zmienne promptów", "To select toolkits here, add them to the \"Tools\" workspace first.": "Aby wybrać narzędzia, dodaj je najpierw w obszarze \"Narzędzia\".", @@ -1754,12 +1754,12 @@ "Type": "Typ", "Type here...": "Pisz tutaj...", "Type Hugging Face Resolve (Download) URL": "Wpisz URL Hugging Face Resolve (Pobieranie)", - "Uh-oh! There was an issue with the response.": "Ojej! Wystąpił problem z odpowiedzią.", - "UI": "Interfejs (UI)", - "UI Scale": "Skala UI", - "Unarchive All": "Odarchiwizuj wszystko", - "Unarchive All Archived Chats": "Odarchiwizuj wszystkie czaty", - "Unarchive Chat": "Odarchiwizuj czat", + "Uh-oh! There was an issue with the response.": "O nie! Wystąpił problem z odpowiedzią.", + "UI": "Interfejs", + "UI Scale": "Skala interfejsu", + "Unarchive All": "Przywróć wszystko", + "Unarchive All Archived Chats": "Przywróć wszystkie czaty", + "Unarchive Chat": "Przywróć czat", "Underline": "Podkreślenie", "Unknown": "Nieznany", "Unknown User": "Nieznany użytkownik", @@ -1789,7 +1789,7 @@ "Upload Pipeline": "Prześlij Pipeline", "Upload Progress": "Postęp przesyłania", "Upload Progress: {{uploadedFiles}}/{{totalFiles}} ({{percentage}}%)": "Postęp: {{uploadedFiles}}/{{totalFiles}} ({{percentage}}%)", - "Uploaded files or images": "", + "Uploaded files or images": "Przesłane pliki lub obrazy", "Uploading file...": "Przesyłanie pliku...", "URL": "URL", "URL is required": "URL jest wymagany", @@ -1807,8 +1807,8 @@ "User Groups": "Grupy użytkowników", "User location successfully retrieved.": "Lokalizacja użytkownika pobrana pomyślnie.", "User menu": "Menu użytkownika", - "User ratings (thumbs up/down)": "", - "User Status": "", + "User ratings (thumbs up/down)": "Oceny użytkowników (kciuki w górę/dół)", + "User Status": "Status użytkownika", "User Webhooks": "Webhooki użytkownika", "Username": "Nazwa użytkownika", "users": "użytkownicy", @@ -1817,9 +1817,9 @@ "Uses OAuth 2.1 Dynamic Client Registration": "Używa OAuth 2.1 Dynamic Client Registration", "Using Entire Document": "Używanie całego dokumentu", "Using Focused Retrieval": "Używanie Focused Retrieval", - "Using the default arena model with all models. Click the plus button to add custom models.": "Używanie domyślnego modelu arena. Kliknij plus aby dodać własne.", + "Using the default arena model with all models. Click the plus button to add custom models.": "Używanie domyślnego modelu arena. Kliknij przycisk plus aby dodać własny model.", "Valid time units:": "Poprawne jednostki czasu:", - "Validate certificate": "Waliduj certyfikat", + "Validate certificate": "Potwierdź certyfikat", "Valves": "Valves", "Valves updated": "Valves zaktualizowane", "Valves updated successfully": "Valves zaktualizowane pomyślnie", @@ -1838,20 +1838,20 @@ "Voice mode": "Tryb głosowy", "Voice Mode Custom Prompt": "Własny prompt trybu głosowego", "Voice Mode Prompt": "Prompt trybu głosowego", - "Warning": "Ostrzeżenie", - "Warning:": "Ostrzeżenie:", - "Warning: Enabling this will allow users to upload arbitrary code on the server.": "Ostrzeżenie: Włączenie tego pozwoli na przesyłanie dowolnego kodu na serwer.", - "Warning: Jupyter execution enables arbitrary code execution, posing severe security risks—proceed with extreme caution.": "Ostrzeżenie: Jupyter umożliwia wykonanie dowolnego kodu (ryzyko bezpieczeństwa).", + "Warning": "Uwaga", + "Warning:": "Uwaga:", + "Warning: Enabling this will allow users to upload arbitrary code on the server.": "Uwaga: Włączenie tego pozwoli użytkownikom na przesyłanie dowolnego kodu na serwer.", + "Warning: Jupyter execution enables arbitrary code execution, posing severe security risks—proceed with extreme caution.": "Uwaga: Jupyter umożliwia wykonanie dowolnego kodu (ryzyko bezpieczeństwa) – zachowaj szczególną ostrożność.", "Web": "Web", "Web API": "Web API", - "Web Loader Engine": "Silnik Web Loader", - "Web Search": "Wyszukiwanie w sieci", - "Web Search Engine": "Silnik wyszukiwania", + "Web Loader Engine": "Silnik ładowania stron", + "Web Search": "Wyszukiwanie WWW", + "Web Search Engine": "Wyszukiwarka", "Web Search in Chat": "Wyszukiwanie w czacie", "Web Search Query Generation": "Generowanie zapytań wyszukiwania", - "Webhook Name": "", + "Webhook Name": "Nazwa webhooka", "Webhook URL": "URL Webhooka", - "Webhooks": "", + "Webhooks": "Webhooki", "Webpage URLs": "Adresy URL stron", "WebUI Settings": "Ustawienia WebUI", "WebUI URL": "URL WebUI", @@ -1860,21 +1860,21 @@ "WebUI will make requests to \"{{url}}/chat/completions\"": "WebUI będzie wysyłać żądania do \"{{url}}/chat/completions\"", "What are you trying to achieve?": "Co chcesz osiągnąć?", "What are you working on?": "Nad czym pracujesz?", - "What is NOT shared:": "", - "What is shared:": "", + "What is NOT shared:": "Co NIE jest udostępniane:", + "What is shared:": "Co jest udostępniane:", "What's New in": "Co nowego w", "What's on your mind?": "O czym myślisz?", - "When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "Gdy włączone, model odpowiada w czasie rzeczywistym.", + "When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "Gdy włączone, model odpowiada w czasie rzeczywistym. Tryb przydatny w czacie na żywo, ale może obciążać słabszy sprzęt.", "wherever you are": "gdziekolwiek jesteś", - "Whether to paginate the output. Each page will be separated by a horizontal rule and page number. Defaults to False.": "Czy stronicować wyjście. Domyślnie Fałsz.", + "Whether to paginate the output. Each page will be separated by a horizontal rule and page number. Defaults to False.": "Określa, czy wyniki mają być stronicowane. Strony są oddzielone linią i numerem. Domyślnie wyłączone.", "Whisper (Local)": "Whisper (Lokalny)", - "Who can share to this group": "", + "Who can share to this group": "Kto może udostępniać w tej grupie", "Why?": "Dlaczego?", "Widescreen Mode": "Tryb szerokoekranowy", "Width": "Szerokość", - "Wikipedia": "", + "Wikipedia": "Wikipedia", "Won": "Wygrano", - "Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text.": "Działa razem z top-k. Wyższa wartość = większa różnorodność.", + "Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text.": "Działa razem z top-k. Wyższa wartość (np. 0.95) = większa różnorodność, niższa = tekst bardziej spójny i zachowawczy.", "Workspace": "Obszar roboczy", "Workspace Permissions": "Uprawnienia obszaru roboczego", "Write": "Pisz", @@ -1884,18 +1884,18 @@ "Yacy Instance URL": "URL instancji Yacy", "Yacy Password": "Hasło Yacy", "Yacy Username": "Nazwa użytkownika Yacy", - "Yahoo": "", - "Yandex": "", + "Yahoo": "Yahoo", + "Yandex": "Yandex", "Yesterday": "Wczoraj", "Yesterday at {{LOCALIZED_TIME}}": "Wczoraj o {{LOCALIZED_TIME}}", "You": "Ty", "You are currently using a trial license. Please contact support to upgrade your license.": "Używasz licencji próbnej. Skontaktuj się ze wsparciem.", "You can only chat with a maximum of {{maxCount}} file(s) at a time.": "Możesz rozmawiać z maksymalnie {{maxCount}} plikami naraz.", - "You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "Możesz personalizować interakcje dodając wspomnienia przyciskiem 'Zarządzaj'.", + "You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "Możesz personalizować interakcje, dodając informacje do pamięci za pomocą przycisku 'Zarządzaj', dzięki czemu odpowiedzi będą lepiej dopasowane do Ciebie.", "You cannot upload an empty file.": "Nie możesz przesłać pustego pliku.", - "You do not have permission to edit this model": "", - "You do not have permission to edit this prompt.": "", - "You do not have permission to save this prompt.": "", + "You do not have permission to edit this model": "Nie masz uprawnień do edycji tego modelu", + "You do not have permission to edit this prompt.": "Nie masz uprawnień do edycji tego promptu.", + "You do not have permission to save this prompt.": "Nie masz uprawnień do zapisania tego promptu.", "You do not have permission to send messages in this channel.": "Nie masz uprawnień do wysyłania wiadomości w tym kanale.", "You do not have permission to send messages in this thread.": "Nie masz uprawnień do wysyłania wiadomości w tym wątku.", "You do not have permission to upload files to this knowledge base.": "Nie masz uprawnień do przesyłania plików do tej bazy wiedzy.", @@ -1906,9 +1906,9 @@ "You're now logged in.": "Zalogowano pomyślnie.", "Your Account": "Twoje konto", "Your account status is currently pending activation.": "Twoje konto oczekuje na aktywację.", - "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Cała wpłata trafia do twórcy pluginu; Open WebUI nie pobiera prowizji.", - "Your message text or inputs": "", - "Your usage stats have been successfully synced.": "", + "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Cała wpłata trafia do twórcy pluginu; Open WebUI nie pobiera prowizji. Wybrana platforma płatnicza może jednak naliczać własne opłaty.", + "Your message text or inputs": "Treść wiadomości lub dane wejściowe", + "Your usage stats have been successfully synced.": "Twoje statystyki użycia zostały pomyślnie zsynchronizowane.", "YouTube": "YouTube", "Youtube Language": "Język YouTube", "Youtube Proxy URL": "URL Proxy YouTube" From 84263fc6a6435226e6a2ac29b421b41fad632067 Mon Sep 17 00:00:00 2001 From: Aleix Dorca Date: Sun, 11 Jan 2026 20:35:11 +0100 Subject: [PATCH 0009/1854] i18n: Updated the Catalan translation file (#20566) * Update translation.json * Update catalan translation.json --- src/lib/i18n/locales/ca-ES/translation.json | 230 ++++++++++---------- 1 file changed, 115 insertions(+), 115 deletions(-) diff --git a/src/lib/i18n/locales/ca-ES/translation.json b/src/lib/i18n/locales/ca-ES/translation.json index a48916e5a3..d76e107e79 100644 --- a/src/lib/i18n/locales/ca-ES/translation.json +++ b/src/lib/i18n/locales/ca-ES/translation.json @@ -12,10 +12,10 @@ "{{COUNT}} Available Tools": "{{COUNT}} eines disponibles", "{{COUNT}} characters": "{{COUNT}} caràcters", "{{COUNT}} extracted lines": "{{COUNT}} línies extretes", - "{{COUNT}} files": "", + "{{COUNT}} files": "{{COUNT}} arxius", "{{COUNT}} hidden lines": "{{COUNT}} línies ocultes", "{{COUNT}} Replies": "{{COUNT}} respostes", - "{{COUNT}} Rows": "", + "{{COUNT}} Rows": "{{COUNT}} files", "{{COUNT}} Sources": "{{COUNT}} fonts", "{{COUNT}} words": "{{COUNT}} paraules", "{{LOCALIZED_DATE}} at {{LOCALIZED_TIME}}": "{{LOCALIZED_DATE}} a les {{LOCALIZED_TIME}}", @@ -47,7 +47,7 @@ "Activate this command by typing \"/{{COMMAND}}\" to chat input.": "Activa aquest comanda escrivint \"{{COMMAND}}\" en el xat", "Active": "Actiu", "Active Users": "Usuaris actius", - "Activity": "", + "Activity": "Activitat", "Add": "Afegir", "Add a model ID": "Afegir un ID de model", "Add a short description about what this model does": "Afegeix una breu descripció sobre què fa aquest model", @@ -70,7 +70,7 @@ "Add text content": "Afegir contingut de text", "Add User": "Afegir un usuari", "Add User Group": "Afegir grup d'usuaris", - "Add webpage": "", + "Add webpage": "Afegir pàgina web", "Additional Config": "Configuració addicional", "Additional configuration options for marker. This should be a JSON string with key-value pairs. For example, '{\"key\": \"value\"}'. Supported keys include: disable_links, keep_pageheader_in_output, keep_pagefooter_in_output, filter_blank_pages, drop_repeated_text, layout_coverage_threshold, merge_threshold, height_tolerance, gap_threshold, image_threshold, min_line_length, level_count, default_level": "Opcions de configuració addicionals per al marcador. Hauria de ser una cadena JSON amb parelles clau-valor. Per exemple, '{\"key\": \"value\"}'. Les claus compatibles inclouen: disable_links, keep_pageheader_in_output, keep_pagefooter_in_output, filter_blank_pages, drop_repeated_text, layout_coverage_threshold, merge_threshold, height_tolerance, gap_threshold, image_threshold, min_line_length, level_count, default_level", "Additional Parameters": "Paràmetres addicionals", @@ -78,7 +78,7 @@ "Adjusting these settings will apply changes universally to all users.": "Si ajustes aquesta preferència, els canvis s'aplicaran de manera universal a tots els usuaris.", "admin": "administrador", "Admin": "Administrador", - "Admin Contact Email": "", + "Admin Contact Email": "Afegir correu electrònic de contacte", "Admin Panel": "Panell d'administració", "Admin Settings": "Preferències d'administració", "Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "Els administradors tenen accés a totes les eines en tot moment; els usuaris necessiten eines assignades per model a l'espai de treball.", @@ -131,7 +131,7 @@ "and {{COUNT}} more": "i {{COUNT}} més", "and create a new shared link.": "i crear un nou enllaç compartit.", "Android": "Android", - "Anyone": "", + "Anyone": "Algú", "API Base URL": "URL Base de l'API", "API Base URL for Datalab Marker service. Defaults to: https://www.datalab.to/api/v1/marker": "URL base de l'API per al servei de marcadors de Datalab. Per defecte: https://www.datalab.to/api/v1/marker", "API Key": "clau API", @@ -140,7 +140,7 @@ "API keys": "Claus de l'API", "API Keys": "Claus de l'API", "API Mode": "Mode API", - "API Timeout": "", + "API Timeout": "Temps d'espera de l'API", "API Version": "Versió de l'API", "API Version is required": "Versió API requerida", "Application DN": "DN d'aplicació", @@ -159,7 +159,7 @@ "Are you sure?": "Estàs segur?", "Arena Models": "Models de l'Arena", "Artifacts": "Artefactes", - "Asc": "", + "Asc": "Ascendent", "Ask": "Preguntar", "Ask a question": "Fer una pregunta", "Assistant": "Assistent", @@ -177,7 +177,7 @@ "Authenticate": "Autenticar", "Authentication": "Autenticació", "Auto": "Automàtic", - "Auto (Random)": "", + "Auto (Random)": "Automàtic (aleatori)", "Auto-Copy Response to Clipboard": "Copiar la resposta automàticament al porta-retalls", "Auto-playback response": "Reproduir la resposta automàticament", "Autocomplete Generation": "Generació automàtica", @@ -186,7 +186,7 @@ "AUTOMATIC1111 Api Auth String": "Cadena d'autenticació de l'API d'AUTOMATIC1111", "AUTOMATIC1111 Base URL": "URL Base d'AUTOMATIC1111", "AUTOMATIC1111 Base URL is required.": "Es requereix la URL Base d'AUTOMATIC1111.", - "Automatically inject system tools in native function calling mode (e.g., timestamps, memory, chat history, notes, etc.)": "", + "Automatically inject system tools in native function calling mode (e.g., timestamps, memory, chat history, notes, etc.)": "Injecta automàticament les eines del sistema en el mode de crida de funcions natives (per exemple, marques de temps, memòria, historial de xat, notes, etc.)", "Available list": "Llista de disponibles", "Available Tools": "Eines disponibles", "available users": "usuaris disponibles", @@ -205,7 +205,7 @@ "before": "abans", "Being lazy": "Essent mandrós", "Beta": "Beta", - "Bing": "", + "Bing": "Bing", "Bing Search V7 Endpoint": "Punt de connexió a Bing Search V7", "Bing Search V7 Subscription Key": "Clau de subscripció a Bing Search V7", "Bio": "Bio", @@ -214,14 +214,14 @@ "Bocha Search API Key": "Clau API de Bocha Search", "Bold": "Negreta", "Boosting or penalizing specific tokens for constrained responses. Bias values will be clamped between -100 and 100 (inclusive). (Default: none)": "Potenciar o penalitzar tokens específics per a respostes limitades. Els valors de biaix es fixaran entre -100 i 100 (inclosos). (Per defecte: cap)", - "Brave": "", + "Brave": "Brave", "Brave Search API Key": "Clau API de Brave Search", - "Builtin Tools": "", + "Builtin Tools": "Eines integrades", "Bullet List": "Llista indexada", "Button ID": "ID del botó", "Button Label": "Etiqueta del botó", "Button Prompt": "Indicació del botó", - "by {{name}}": "", + "by {{name}}": "per {{name}}", "By {{name}}": "Per {{name}}", "Bypass Embedding and Retrieval": "Desactivar l'Embedding i el Retrieval", "Bypass Web Loader": "Ometre el càrregador web", @@ -231,7 +231,7 @@ "Call feature is not supported when using Web STT engine": "La funció de trucada no s'admet quan s'utilitza el motor Web STT", "Camera": "Càmera", "Cancel": "Cancel·lar", - "Cannot create an empty note.": "", + "Cannot create an empty note.": "No es pot crear una nota buida.", "Capabilities": "Capacitats", "Capture": "Captura", "Capture Audio": "Capturar àudio", @@ -241,7 +241,7 @@ "Channel deleted successfully": "Canal suprimit correctament", "Channel Name": "Nom del canal", "Channel name cannot be empty.": "El nom del canal no pot estar buit.", - "Channel name must be less than 128 characters": "", + "Channel name must be less than 128 characters": "El nom del canal ha de tenir menys de 128 caràcters", "Channel Type": "Tipus de canal", "Channel updated successfully": "Canal actualitzat correctament", "Channels": "Canals", @@ -264,10 +264,10 @@ "Check for updates": "Comprovar si hi ha actualitzacions", "Checking for updates...": "Comprovant actualitzacions...", "Choose a model before saving...": "Triar un model abans de desar...", - "Chunk Min Size Target": "", + "Chunk Min Size Target": "Objectiu de mida mínima del fragment", "Chunk Overlap": "Solapament de blocs", "Chunk Size": "Mida del bloc", - "Chunks smaller than this threshold will be merged with neighboring chunks when possible. Set to 0 to disable merging.": "", + "Chunks smaller than this threshold will be merged with neighboring chunks when possible. Set to 0 to disable merging.": "Els fragments més petits que aquest llindar es fusionaran amb els fragments veïns sempre que sigui possible. Establiu-ho a 0 per desactivar la fusió.", "Ciphers": "Xifradors", "Citation": "Cita", "Citations": "Cites", @@ -303,7 +303,7 @@ "Code Block": "Bloc de codi", "Code Editor": "Editor de codi", "Code execution": "Execució de codi", - "Code Execution": "", + "Code Execution": "Execució de codi", "Code Execution Engine": "Motor d'execució de codi", "Code Execution Timeout": "Temps màxim d'execució de codi", "Code formatted successfully": "Codi formatat correctament", @@ -313,7 +313,7 @@ "Collaboration channel where people join as members": "Canal de col·laboració on la gent s'uneix com a membres", "Collapse": "Col·lapsar", "Collection": "Col·lecció", - "Collections": "", + "Collections": "Col·lecccions", "Color": "Color", "ComfyUI": "ComfyUI", "ComfyUI API Key": "Configurar la clau API de ComfyUI", @@ -346,7 +346,7 @@ "Contact Admin for WebUI Access": "Posa't en contacte amb l'administrador per accedir a WebUI", "Content": "Contingut", "Content Extraction Engine": "Motor d'extracció de contingut", - "Content lengths (character counts only)": "", + "Content lengths (character counts only)": "Mida del contingut (només els caràcters)", "Continue Response": "Continuar la resposta", "Continue with {{provider}}": "Continuar amb {{provider}}", "Continue with Email": "Continuar amb el correu", @@ -367,7 +367,7 @@ "Copy link": "Copiar l'enllaç", "Copy Link": "Copiar l'enllaç", "Copy to clipboard": "Copiar al porta-retalls", - "Copy URL": "", + "Copy URL": "Copiar la URL", "Copying to clipboard was successful!": "La còpia al porta-retalls s'ha realitzat correctament", "CORS must be properly configured by the provider to allow requests from Open WebUI.": "CORS ha de ser configurat correctament pel proveïdor per permetre les sol·licituds d'Open WebUI", "Create": "Crear", @@ -384,14 +384,14 @@ "Create Model": "Crear model", "Create new key": "Crear una nova clau", "Create new secret key": "Crear una nova clau secreta", - "Create note": "", + "Create note": "Crear una nota", "Create Note": "Crea nota", "Create your first note by clicking on the plus button below.": "Crea la teva primera nota prement sobre el botó 'més' inferior", "Created at": "Creat el", "Created At": "Creat el", "Created by": "Creat per", "Created by you": "Creat per tu", - "Created on {{date}}": "", + "Created on {{date}}": "Creat el {{date}}", "CSV Import": "Importar CSV", "Ctrl+Enter to Send": "Ctrl+Enter per enviar", "Current Model": "Model actual", @@ -406,7 +406,7 @@ "Database": "Base de dades", "Datalab Marker API": "API de Datalab Marker", "DD/MM/YYYY": "DD/MM/YYYY", - "DDGS Backend": "", + "DDGS Backend": "Backend DDGS", "December": "Desembre", "Decrease UI Scale": "Disminuir la mida de la interfície gràfica", "Deepgram": "Deepgram", @@ -447,12 +447,12 @@ "delete this link": "Eliminar aquest enllaç", "Delete tool?": "Eliminar eina?", "Delete User": "Eliminar usuari", - "Deleted": "", + "Deleted": "Eliminat", "Deleted {{deleteModelTag}}": "S'ha eliminat {{deleteModelTag}}", "Deleted {{name}}": "S'ha eliminat {{name}}", "Deleted User": "Usuari eliminat", "Deployment names are required for Azure OpenAI": "Els noms de desplegament són requerits per Azure OpenAI", - "Desc": "", + "Desc": "Descendent", "Describe your knowledge base and objectives": "Descriu la teva base de coneixement i objectius", "Description": "Descripció", "Detect Artifacts Automatically": "Detectar automàticament els artefactes", @@ -489,7 +489,7 @@ "Dive into knowledge": "Aprofundir en el coneixement", "Do not install functions from sources you do not fully trust.": "No instal·lis funcions de fonts en què no confiïs plenament.", "Do not install tools from sources you do not fully trust.": "No instal·lis eines de fonts en què no confiïs plenament.", - "Do you want to sync your usage stats with Open WebUI Community?": "", + "Do you want to sync your usage stats with Open WebUI Community?": "Vols sincronitzar les estadístiques d'ús amb la Open WebUI Community?", "Docling": "Docling", "Docling Parameters": "Paràmetres de Docling", "Docling Server URL required.": "La URL del servidor Docling és necessària", @@ -498,7 +498,7 @@ "Document Intelligence endpoint required.": "Es necessita un punt de connexió de Document Intelligence", "Document Intelligence Model": "Model de Document Intelligence", "Documentation": "Documentació", - "Documents": "", + "Documents": "Documents", "does not make any external connections, and your data stays securely on your locally hosted server.": "no realitza connexions externes, i les teves dades romanen segures al teu servidor allotjat localment.", "Domain Filter List": "Llista de filtre de dominis", "don't fetch random pipelines from sources you don't trust.": "No obtinguis pipelines aleatòries de fonts no fiables.", @@ -509,20 +509,20 @@ "Done": "Fet", "Download": "Descarregar", "Download & Delete": "Descarregar i suprimir", - "Download as JSON": "", + "Download as JSON": "Descarregar com a JSON", "Download as SVG": "Descarrega com a SVG", "Download canceled": "Descàrrega cancel·lada", "Download Database": "Descarregar la base de dades", - "Downloading stats...": "", + "Downloading stats...": "Descarregant estadístiques...", "Draw": "Dibuixar", "Drop any files here to upload": "Arrossega aquí qualsevol fitxer per pujar-lo", - "DuckDuckGo": "", + "DuckDuckGo": "DuckDuckGo", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "p. ex. '30s','10m'. Les unitats de temps vàlides són 's', 'm', 'h'.", "e.g. \"json\" or a JSON schema": "p. ex. \"json\" o un esquema JSON", "e.g. 60": "p. ex. 60", "e.g. A filter to remove profanity from text": "p. ex. Un filtre per eliminar paraules malsonants del text", "e.g. about the Roman Empire": "p. ex. sobre l'imperi Romà", - "e.g. alloy, echo, shimmer": "", + "e.g. alloy, echo, shimmer": "p. ex. aliatge, eco, brillantor", "e.g. en": "p. ex. en", "e.g. My Filter": "p. ex. El meu filtre", "e.g. My Tools": "p. ex. Les meves eines", @@ -592,7 +592,7 @@ "Enter Bocha Search API Key": "Introdueix la clau API de Bocha Search", "Enter Brave Search API Key": "Introdueix la clau API de Brave Search", "Enter certificate path": "Introdueix el camí del certificat", - "Enter Chunk Min Size Target": "", + "Enter Chunk Min Size Target": "Introdueix la mida mínima del bloc objectiu", "Enter Chunk Overlap": "Introdueix la mida de solapament de blocs", "Enter Chunk Size": "Introdueix la mida del bloc", "Enter comma-separated \"token:bias_value\" pairs (example: 5432:100, 413:-100)": "Introdueix parelles de \"token:valor de biaix\" separats per comes (exemple: 5432:100, 413:-100)", @@ -616,7 +616,7 @@ "Enter External Web Search URL": "Introdueix la URL d'External Web Search", "Enter Firecrawl API Base URL": "Introdueix la URL base de Firecrawl API", "Enter Firecrawl API Key": "Introdueix la clau API de Firecrawl", - "Enter Firecrawl Timeout": "", + "Enter Firecrawl Timeout": "Introdueix el temps d'espera per a Firecrawl", "Enter folder name": "Introdueix el nom de la carpeta", "Enter function name filter list (e.g. func1, !func2)": "Introdueix la llista de filtres de noms de funció (per exemple, func1, !func2)", "Enter Github Raw URL": "Introdueix la URL en brut de Github", @@ -625,7 +625,7 @@ "Enter hex color (e.g. #FF0000)": "Introdueix el codi hexadecimal del color (p. ex. #FF0000)", "Enter ID": "Introdueix l'ID", "Enter Image Size (e.g. 512x512)": "Introdueix la mida de la imatge (p. ex. 512x512)", - "Enter Jina API Base URL": "", + "Enter Jina API Base URL": "Introdueix la URL base de Jina", "Enter Jina API Key": "Introdueix la clau API de Jina", "Enter JSON config (e.g., {\"disable_links\": true})": "Introdueix la configuració JSON (per exemple, {\"disable_links\": true})", "Enter Jupyter Password": "Introdueix la contrasenya de Jupyter", @@ -634,7 +634,7 @@ "Enter Kagi Search API Key": "Introdueix la clau API de Kagi Search", "Enter Key Behavior": "Introdueix el comportament de clau", "Enter language codes": "Introdueix els codis de llenguatge", - "Enter MinerU API Key": "", + "Enter MinerU API Key": "Introdueix la clau API de MinerU", "Enter Mistral API Base URL": "Entra la URL Base de l'API de Mistral", "Enter Mistral API Key": "Entra la clau API de Mistral", "Enter Model ID": "Introdueix l'identificador del model", @@ -646,7 +646,7 @@ "Enter Ollama Cloud API Key": "Introdueix la clau API de Ollama Cloud", "Enter Perplexity API Key": "Introdueix la clau API de Perplexity", "Enter Perplexity Search API URL": "Introduïu l'URL de l'API de cerca de Perplexity", - "Enter Playwright Timeout": "Introdueix el timeout de Playwright", + "Enter Playwright Timeout": "Introdueix el temps d'espera de Playwright", "Enter Playwright WebSocket URL": "Introdueix la URL de Playwright WebSocket", "Enter proxy URL (e.g. https://user:password@host:port)": "Entra la URL (p. ex. https://user:password@host:port)", "Enter reasoning effort": "Introdueix l'esforç de raonament", @@ -654,7 +654,7 @@ "Enter SearchApi API Key": "Introdueix la clau API SearchApi", "Enter SearchApi Engine": "Introdueix el motor SearchApi", "Enter Searxng Query URL": "Introdueix la URL de consulta de Searxng", - "Enter Searxng search language": "", + "Enter Searxng search language": "Entra la llengua de cerca de Searxng", "Enter Seed": "Introdueix la llavor", "Enter SerpApi API Key": "Introdueix la clau API SerpApi", "Enter SerpApi Engine": "Introdueix el motor API SerpApi", @@ -675,7 +675,7 @@ "Enter the URL of the function to import": "Introdueix la URL de la funció a importar", "Enter the URL to import": "Introdueix la URL a importar", "Enter Tika Server URL": "Introdueix la URL del servidor Tika", - "Enter timeout in seconds": "Entra el temps màxim en segons", + "Enter timeout in seconds": "Entra el temps d'espera en segons", "Enter to Send": "Enter per enviar", "Enter Top K": "Introdueix Top K", "Enter Top K Reranker": "Introdueix el Top K Reranker", @@ -760,10 +760,10 @@ "Failed to generate title": "No s'ha pogut generar el títol", "Failed to import models": "No s'han pogut importar el models", "Failed to load chat preview": "No s'ha pogut carregar la previsualització del xat", - "Failed to load Excel/CSV file. Please try downloading it instead.": "", + "Failed to load Excel/CSV file. Please try downloading it instead.": "No s'ha pogut carregar el fitxer Excel/CSV. Si us plau, prova de descarregar-lo.", "Failed to load file content.": "No s'ha pogut carregar el contingut del fitxer", "Failed to move chat": "No s'ha pogut moure el xat", - "Failed to process URL: {{url}}": "", + "Failed to process URL: {{url}}": "No s'ha pogut processar la URL: {{url}}", "Failed to read clipboard contents": "No s'ha pogut llegir el contingut del porta-retalls", "Failed to remove member": "No s'ha pogut eliminar el membre", "Failed to render diagram": "No s'ha pogut renderitzar el diagrama", @@ -777,7 +777,7 @@ "Features": "Característiques", "Features Permissions": "Permisos de les característiques", "February": "Febrer", - "Feedback": "", + "Feedback": "Retorn", "Feedback deleted successfully": "Retorn eliminat correctament", "Feedback Details": "Detalls del retorn", "Feedback History": "Històric de comentaris", @@ -786,7 +786,7 @@ "File": "Arxiu", "File added successfully.": "L'arxiu s'ha afegit correctament.", "File content updated successfully.": "El contingut de l'arxiu s'ha actualitzat correctament.", - "File Context": "", + "File Context": "Contingut de l'arxiu", "File Mode": "Mode d'arxiu", "File not found.": "No s'ha trobat l'arxiu.", "File removed successfully.": "Arxiu eliminat correctament.", @@ -802,13 +802,13 @@ "Fingerprint spoofing detected: Unable to use initials as avatar. Defaulting to default profile image.": "S'ha detectat la suplantació d'identitat de l'empremta digital: no es poden utilitzar les inicials com a avatar. S'estableix la imatge de perfil predeterminada.", "Firecrawl API Base URL": "URL de l'API de base de Firecrawl", "Firecrawl API Key": "Clau API de Firecrawl", - "Firecrawl Timeout (s)": "", + "Firecrawl Timeout (s)": "Temps d'espera de Firecrawl (s)", "Floating Quick Actions": "Accions ràpides flotants", "Focus Chat Input": "Posa el focus en l'entrada del xat", "Folder": "Carpeta", "Folder Background Image": "Imatge del fons de la carpeta", "Folder deleted successfully": "Carpeta eliminada correctament", - "Folder Max File Count": "", + "Folder Max File Count": "Nombre màxim d'arxius per carpeta", "Folder Name": "Nom de la carpeta", "Folder name cannot be empty.": "El nom de la carpeta no pot ser buit.", "Folder name updated successfully": "Nom de la carpeta actualitzat correctament", @@ -863,13 +863,13 @@ "Get started with {{WEBUI_NAME}}": "Comença amb {{WEBUI_NAME}}", "Global": "Global", "Good Response": "Bona resposta", - "Google": "", + "Google": "Google", "Google Drive": "Google Drive", "Google PSE API Key": "Clau API PSE de Google", "Google PSE Engine Id": "Identificador del motor PSE de Google", "Gravatar": "Gravatar", - "Grid": "", - "Grokipedia": "", + "Grid": "Graella", + "Grokipedia": "Grokipedia", "Group": "Grup", "Group Channel": "Canal de grup", "Group created successfully": "El grup s'ha creat correctament", @@ -923,7 +923,7 @@ "Image Prompt Generation": "Generació d'indicacions d'imatge", "Image Prompt Generation Prompt": "Indicació per a la generació d'indicacions d'imatge", "Image Size": "Mida de la imatge", - "Images": "", + "Images": "Imatges", "Import": "Importar", "Import Chats": "Importar xats", "Import Config from JSON File": "Importar la configuració des d'un arxiu JSON", @@ -942,7 +942,7 @@ "Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive.": "Influeix amb la rapidesa amb què l'algoritme respon als comentaris del text generat. Una taxa d'aprenentatge més baixa donarà lloc a ajustos més lents, mentre que una taxa d'aprenentatge més alta farà que l'algorisme sigui més sensible.", "Info": "Informació", "Initials": "Inicials", - "Inject file content into conversation context": "", + "Inject file content into conversation context": "Injecta el contingut del fitxer en el context de la conversa", "Inject the entire content as context for comprehensive processing, this is recommended for complex queries.": "Injectar tot el contingut com a context per a un processament complet, això es recomana per a consultes complexes.", "Input": "Entrada", "Input Key (e.g. text, unet_name, steps)": "Entra la clau (p. ex. text, unet_name, steps)", @@ -956,7 +956,7 @@ "Integration": "Integració", "Integrations": "Integracions", "Interface": "Interfície", - "Interface Settings Access": "", + "Interface Settings Access": "Accés a la configuració de la interfície", "Invalid file content": "Continguts del fitxer no vàlids", "Invalid file format.": "Format d'arxiu no vàlid.", "Invalid JSON file": "Arxiu JSON no vàlid", @@ -970,7 +970,7 @@ "is typing...": "està escrivint...", "Italic": "Cursiva", "January": "Gener", - "Jina API Base URL": "", + "Jina API Base URL": "URL Base de l'API Jina", "Jina API Key": "Clau API de Jina", "join our Discord for help.": "uneix-te al nostre Discord per obtenir ajuda.", "JSON": "JSON", @@ -995,7 +995,7 @@ "Knowledge created successfully.": "Coneixement creat correctament.", "Knowledge deleted successfully.": "Coneixement eliminat correctament.", "Knowledge Description": "Descripció del coneixement", - "Knowledge exported successfully": "", + "Knowledge exported successfully": "El coneixement s'ha exportat correctament", "Knowledge Name": "Nom del coneixement", "Knowledge Public Sharing": "Compartir públicament el Coneixement", "Knowledge reset successfully.": "Coneixement restablert correctament.", @@ -1022,7 +1022,7 @@ "Leave empty to include all models from \"{{url}}/api/tags\" endpoint": "Deixar-ho buit per incloure tots els models del punt de connexió \"{{url}}/api/tags\"", "Leave empty to include all models from \"{{url}}/models\" endpoint": "Deixar-ho buit per incloure tots els models del punt de connexió \"{{url}}/models\"", "Leave empty to include all models or select specific models": "Deixa-ho en blanc per incloure tots els models o selecciona models específics", - "Leave empty to use first admin user": "", + "Leave empty to use first admin user": "Deixa-ho buit per utilitzar el primer usuari administrador", "Leave empty to use the default model (voxtral-mini-latest).": "Deixau-ho en blanc per utilitzar el model per defecte (voxtral-mini-latest).", "Leave empty to use the default prompt, or enter a custom prompt": "Deixa-ho en blanc per utilitzar la indicació predeterminada o introdueix una indicació personalitzada", "Leave model field empty to use the default model.": "Deixa el camp de model buit per utilitzar el model per defecte.", @@ -1031,8 +1031,8 @@ "License": "Llicència", "Lift List": "Aixecar la llista", "Light": "Clar", - "Limit concurrent search queries. 0 = unlimited (default). Set to 1 for sequential execution (recommended for APIs with strict rate limits like Brave free tier).": "", - "List": "", + "Limit concurrent search queries. 0 = unlimited (default). Set to 1 for sequential execution (recommended for APIs with strict rate limits like Brave free tier).": "Limita les consultes de cerca simultànies. 0 = il·limitada (per defecte). Estableix-ho a 1 per a l'execució seqüencial (recomanat per a API amb límits de velocitat estrictes com el nivell gratuït de Brave).", + "List": "Llista", "Listening...": "Escoltant...", "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "Els models de llenguatge poden cometre errors. Verifica la informació important.", @@ -1062,12 +1062,12 @@ "Manage your account information.": "Gestionar la informació del teu compte.", "March": "Març", "Markdown": "Markdown", - "Markdown Header Text Splitter": "", + "Markdown Header Text Splitter": "Divisor de text de capçalera de Markdown", "Max Speakers": "Nombre màxim d'altaveus", "Max Upload Count": "Nombre màxim de càrregues", "Max Upload Size": "Mida màxima de càrrega", - "Maximum number of files allowed per folder.": "", - "Maximum number of files per folder is {{max}}.": "", + "Maximum number of files allowed per folder.": "Nombre màxim de fitxers permès per carpeta.", + "Maximum number of files per folder is {{max}}.": "El nombre màxim de fitxers per carpeta és {{max}}.", "Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Es poden descarregar un màxim de 3 models simultàniament. Si us plau, prova-ho més tard.", "May": "Maig", "MBR": "MBR", @@ -1077,7 +1077,7 @@ "Member removed successfully": "El membre s'ha eliminat satisfactòriament", "Members": "Membres", "Members added successfully": "Els membres s'han afegit satisfactòriament", - "Memories": "", + "Memories": "Memòries", "Memories accessible by LLMs will be shown here.": "Les memòries accessibles pels models de llenguatge es mostraran aquí.", "Memory": "Memòria", "Memory added successfully": "Memòria afegida correctament", @@ -1087,7 +1087,7 @@ "Merge Responses": "Fusionar les respostes", "Merged Response": "Resposta combinada", "Message": "Missatge", - "Message counts and response timestamps": "", + "Message counts and response timestamps": "Recompte de missatges i marques de temps de resposta", "Message rating should be enabled to use this feature": "La classificació dels missatges s'hauria d'activar per utilitzar aquesta funció", "Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "Els missatges enviats després de crear el teu enllaç no es compartiran. Els usuaris amb la URL podran veure el xat compartit.", "Microsoft OneDrive": "Microsoft OneDrive", @@ -1120,11 +1120,11 @@ "Model Name": "Nom del model", "Model name already exists, please choose a different one": "Aquest nom de model ja existeix, si us plau, tria'n un altre", "Model Name is required.": "El nom del model és necessari", - "Model names and usage frequency": "", + "Model names and usage frequency": "Noms de models i freqüència d'ús", "Model not selected": "Model no seleccionat", "Model Params": "Paràmetres del model", "Model Permissions": "Permisos dels models", - "Model responses or outputs": "", + "Model responses or outputs": "Respostes o resultats del model", "Model unloaded successfully": "El model s'ha descarregat correctament", "Model updated successfully": "Model actualitzat correctament", "Model(s) do not support file upload": "El model no permet la pujada d'arxius", @@ -1135,7 +1135,7 @@ "Models imported successfully": "Els models s'han importat correctament", "Models Public Sharing": "Compartició pública de models", "Models Sharing": "Compartir els models", - "Mojeek": "", + "Mojeek": "Mojeek", "Mojeek Search API Key": "Clau API de Mojeek Search", "More": "Més", "More Concise": "Més precís", @@ -1145,22 +1145,22 @@ "Name and ID are required, please fill them out": "El nom i l'ID són necessaris, emplena'ls, si us plau", "Name your knowledge base": "Anomena la teva base de coneixement", "Native": "Natiu", - "New": "", + "New": "Nou", "New Button": "Botó nou", "New Chat": "Nou xat", "New Folder": "Nova carpeta", "New Function": "Nova funció", "New Knowledge": "Nou coneixement", "New Model": "Nou model", - "New Note": "", + "New Note": "Nova nota", "New Password": "Nova contrasenya", "New Prompt": "Nova indicació", "New Temporary Chat": "Nou xat temporal", "New Tool": "Nova eina", - "New Webhook": "", + "New Webhook": "Nou webhook", "new-channel": "nou-canal", "Next message": "Missatge següent", - "No activity data": "", + "No activity data": "No hi ha dades d'activitat", "No authentication": "Sense autenticació", "No chats found": "No s'han trobat xats", "No chats found for this user.": "No s'han trobat xats per a aquest usuari.", @@ -1171,14 +1171,14 @@ "No conversation to save": "No hi ha cap conversa a desar", "No distance available": "No hi ha distància disponible", "No expiration can pose security risks.": "No posar expiració pot suposar problemes de seguretat.", - "No feedback found": "", + "No feedback found": "No s'ha trobat cap retorn", "No file selected": "No s'ha escollit cap fitxer", - "No files in this knowledge base.": "", + "No files in this knowledge base.": "No hi ha arxius a la base de coneixement.", "No functions found": "No s'han trobat funcions", "No groups with access, add a group to grant access": "No hi ha cap grup amb accés, afegeix un grup per concedir accés", "No HTML, CSS, or JavaScript content found.": "No s'ha trobat contingut HTML, CSS o JavaScript.", "No inference engine with management support found": "No s'ha trobat un motor d'inferència amb suport de gestió", - "No knowledge bases found.": "", + "No knowledge bases found.": "No s'han trobat bases de coneixement.", "No knowledge found": "No s'ha trobat Coneixement", "No memories to clear": "No hi ha memòries per netejar", "No model IDs": "No hi ha IDs de model", @@ -1186,7 +1186,7 @@ "No models selected": "No s'ha seleccionat cap model", "No Notes": "No hi ha notes", "No notes found": "No s'han trobat notes", - "No one": "", + "No one": "Ningú", "No pinned messages": "No hi ha missatges fixats", "No prompts found": "No s'han trobat indicacions", "No results": "No s'han trobat resultats", @@ -1199,7 +1199,7 @@ "No users were found.": "No s'han trobat usuaris", "No valves": "No hi ha valves", "No valves to update": "No hi ha cap Valve per actualitzar", - "No webhooks yet": "", + "No webhooks yet": "No hi ha webhooks encara", "Node Ids": "Id de nodes", "None": "Cap", "Not factually correct": "No és clarament correcte", @@ -1239,7 +1239,7 @@ "Only invited users can access": "Només hi poden accedir els usuaris convidats", "Only markdown files are allowed": "Només es permeten arxius markdown", "Only select users and groups with permission can access": "Només hi poden accedir usuaris i grups seleccionats amb permís", - "Only sync new/updated chats": "", + "Only sync new/updated chats": "Sincronitza només els xats nous/actualitzats", "Oops! Looks like the URL is invalid. Please double-check and try again.": "Ui! Sembla que la URL no és vàlida. Si us plau, revisa-la i torna-ho a provar.", "Oops! There are files still uploading. Please wait for the upload to complete.": "Ui! Encara hi ha fitxers pujant-se. Si us plau, espera que finalitzi la càrrega.", "Oops! There was an error in the previous response.": "Ui! Hi ha hagut un error a la resposta anterior.", @@ -1256,7 +1256,7 @@ "Open WebUI can use tools provided by any OpenAPI server.": "Open WebUI pot utilitzar eines de servidors OpenAPI.", "Open WebUI uses faster-whisper internally.": "Open WebUI utilitza faster-whisper internament.", "Open WebUI uses SpeechT5 and CMU Arctic speaker embeddings.": "Open WebUI utilitza incrustacions de SpeechT5 i CMU Arctic.", - "Open WebUI version": "", + "Open WebUI version": "Versió d'Open WebUI", "Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "La versió d'Open WebUI (v{{OPEN_WEBUI_VERSION}}) és inferior a la versió requerida (v{{REQUIRED_VERSION}})", "OpenAI": "OpenAI", "OpenAI API": "API d'OpenAI", @@ -1281,8 +1281,8 @@ "page": "pàgina", "Paginate": "Paginar", "Parameters": "Paràmetres", - "Parent message not found": "", - "Participate in community leaderboards and evaluations! Syncing aggregated usage stats helps drive research and improvements to Open WebUI. Your privacy is paramount: no message content is ever shared.": "", + "Parent message not found": "No s'ha trobat el missatge pare", + "Participate in community leaderboards and evaluations! Syncing aggregated usage stats helps drive research and improvements to Open WebUI. Your privacy is paramount: no message content is ever shared.": "Participa en les taules de classificació i les avaluacions de la comunitat! La sincronització de les estadístiques d'ús agregades ajuda a impulsar la recerca i les millores a Open WebUI. La teva privadesa és primordial: no es comparteix mai cap contingut de missatge.", "Password": "Contrasenya", "Passwords do not match.": "Les contrasenyes no coincideixen", "Paste Large Text as File": "Enganxa un text llarg com a fitxer", @@ -1308,7 +1308,7 @@ "Pipe": "Canonada", "Pipeline deleted successfully": "Pipeline eliminada correctament", "Pipeline downloaded successfully": "Pipeline descarregada correctament", - "Pipelines": "", + "Pipelines": "Pipelines", "Pipelines are a plugin system with arbitrary code execution —": "Pipelines és un sistema de connectors amb execució arbitrària de codi —", "Pipelines Not Detected": "No s'ha detectat Pipelines", "Pipelines Valves": "Vàlvules de les Pipelines", @@ -1371,8 +1371,8 @@ "Read": "Llegit", "Read Aloud": "Llegir en veu alta", "Read more →": "Llegeix més →", - "Read Only": "", - "Read-Only Access": "", + "Read Only": "Només lectura", + "Read-Only Access": "Accés de només lectura", "Reason": "Raó", "Reasoning Effort": "Esforç de raonament", "Reasoning Tags": "Etiqueta de raonament", @@ -1481,7 +1481,7 @@ "Searching Knowledge for \"{{searchQuery}}\"": "Cercant \"{{searchQuery}}\" al coneixement", "Searching the web": "Cercant la web...", "Searxng Query URL": "URL de consulta de Searxng", - "Searxng search language (all, en, es, de, fr, etc.)": "", + "Searxng search language (all, en, es, de, fr, etc.)": "Idioma de cerca de cerca (all, en, es, de, fr, etc.)", "See readme.md for instructions": "Consulta l'arxiu readme.md per obtenir instruccions", "See what's new": "Veure què hi ha de nou", "Seed": "Llavor", @@ -1546,7 +1546,7 @@ "Sets the stop sequences to use. When this pattern is encountered, the LLM will stop generating text and return. Multiple stop patterns may be set by specifying multiple separate stop parameters in a modelfile.": "Establir les seqüències d'aturada a utilitzar. Quan es trobi aquest patró, el LLM deixarà de generar text. Es poden establir diversos patrons de parada especificant diversos paràmetres de parada separats en un fitxer model.", "Setting": "Preferència", "Settings": "Preferències", - "Settings Permissions": "", + "Settings Permissions": "Preferències de permisos", "Settings saved successfully!": "Les preferències s'han desat correctament", "Share": "Compartir", "Share Chat": "Compartir el xat", @@ -1557,7 +1557,7 @@ "Show": "Mostrar", "Show \"What's New\" modal on login": "Veure 'Què hi ha de nou' a l'entrada", "Show Admin Details in Account Pending Overlay": "Mostrar els detalls de l'administrador a la superposició del compte pendent", - "Show Files": "", + "Show Files": "Mostra els arxius", "Show Formatting Toolbar": "Mostrar la barra de format", "Show image preview": "Mostrar la previsualització de la imatge", "Show Model": "Mostrar el model", @@ -1582,7 +1582,7 @@ "Sonar Pro": "Sonar Pro", "Sonar Reasoning": "Sonar Reasoning", "Sonar Reasoning Pro": "Sonar Reasoning Pro", - "Sort": "", + "Sort": "Ordenar", "Sougou Search API sID": "sID de l'API de Sougou Search", "Sougou Search API SK": "SK de l'API de Sougou Search", "Source": "Font", @@ -1590,7 +1590,7 @@ "Speech recognition error: {{error}}": "Error de reconeixement de veu: {{error}}", "Speech-to-Text": "Àudio-a-Text", "Speech-to-Text Engine": "Motor de veu a text", - "Split documents by markdown headers before applying character/token splitting.": "", + "Split documents by markdown headers before applying character/token splitting.": "Divideix els documents per capçaleres de markdown abans d'aplicar la divisió de caràcters/tokens.", "Start a new conversation": "Iniciar una nova conversa", "Start of the channel": "Inici del canal", "Start Tag": "Etiqueta d'inici", @@ -1601,7 +1601,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Passos", "Stop": "Atura", - "Stop Download": "", + "Stop Download": "Aturar la descàrrega", "Stop Generating": "Aturar la generació", "Stop Sequence": "Atura la seqüència", "Stream Chat Response": "Fer streaming de la resposta del xat", @@ -1622,14 +1622,14 @@ "Support": "Dona suport", "Support this plugin:": "Dona suport a aquest complement:", "Supported MIME Types": "Tipus MIME admesos", - "Sync": "", - "Sync Complete!": "", + "Sync": "Sincronitzar", + "Sync Complete!": "Sincronia completada", "Sync directory": "Sincronitzar directori", - "Sync Failed": "", - "Sync Usage Stats": "", - "Syncing stats...": "", - "Syncing...": "", - "Syncs only chats with updates after your last sync timestamp. Disable to re-sync all chats.": "", + "Sync Failed": "La sincronia ha fallat", + "Sync Usage Stats": "Mostra la estadístiques d'ús", + "Syncing stats...": "Sincronitzant les estadístiques...", + "Syncing...": "Sincronitzant", + "Syncs only chats with updates after your last sync timestamp. Disable to re-sync all chats.": "Sincronitza només els xats amb actualitzacions posteriors a la data i hora de l'última sincronització. Desactiva-ho per tornar a sincronitzar tots els xats.", "System": "Sistema", "System Instructions": "Instruccions de sistema", "System Prompt": "Indicació del Sistema", @@ -1674,7 +1674,7 @@ "The Weight of BM25 Hybrid Search. 0 more semantic, 1 more lexical. Default 0.5": "El pes de la cerca híbrida BM25. 0 més semàntic, 1 més lèxic. Per defecte 0,5", "The width in pixels to compress images to. Leave empty for no compression.": "L'amplada en píxels per comprimir imatges. Deixar-ho buit per a cap compressió.", "Theme": "Tema", - "There was an error syncing your stats. Please try again.": "", + "There was an error syncing your stats. Please try again.": "S'ha produït un error en sincronitzar les estadístiques. Torna-ho a provar.", "Thinking...": "Pensant...", "This action cannot be undone. Do you wish to continue?": "Aquesta acció no es pot desfer. Vols continuar?", "This channel was created on {{createdAt}}. This is the very beginning of the {{channelName}} channel.": "Aquest canal es va crear el dia {{createdAt}}. Aquest és el començament del canal {{channelName}}.", @@ -1703,7 +1703,7 @@ "Tika": "Tika", "Tika Server URL required.": "La URL del servidor Tika és obligatòria.", "Tiktoken": "Tiktoken", - "Timeout": "", + "Timeout": "Temps d'espera", "Title": "Títol", "Title Auto-Generation": "Generació automàtica de títol", "Title cannot be an empty string.": "El títol no pot ser una cadena buida.", @@ -1739,7 +1739,7 @@ "Tools have a function calling system that allows arbitrary code execution.": "Les eines disposen d'un sistema de crida a funcions que permet execució de codi arbitrari.", "Tools Public Sharing": "Compartició pública d'eines", "Tools Sharing": "Compartir les eines", - "Top": "", + "Top": "A dalt", "Top K": "Top K", "Top K Reranker": "Top K Reranker", "Transformers": "Transformadors", @@ -1788,7 +1788,7 @@ "Upload Pipeline": "Pujar una Pipeline", "Upload Progress": "Progrés de càrrega", "Upload Progress: {{uploadedFiles}}/{{totalFiles}} ({{percentage}}%)": "Progrés de la pujada: {{uploadedFiles}}/{{totalFiles}} ({{percentage}}%)", - "Uploaded files or images": "", + "Uploaded files or images": "Arxius o imatges pujats", "Uploading file...": "Pujant l'arxiu...", "URL": "URL", "URL is required": "La URL és necessaria", @@ -1806,8 +1806,8 @@ "User Groups": "Grups d'usuari", "User location successfully retrieved.": "Ubicació de l'usuari obtinguda correctament", "User menu": "Menú d'usuari", - "User ratings (thumbs up/down)": "", - "User Status": "", + "User ratings (thumbs up/down)": "Valoracions dels usuaris (polze amunt/avall)", + "User Status": "Estats d'usuari", "User Webhooks": "Webhooks d'usuari", "Username": "Nom d'usuari", "users": "usuaris", @@ -1848,10 +1848,10 @@ "Web Search Engine": "Motor de cerca de la web", "Web Search in Chat": "Cerca a internet al xat", "Web Search Query Generation": "Generació de consultes per a la cerca de la web", - "Webhook Name": "", + "Webhook Name": "Nom del webhook", "Webhook URL": "URL del webhook", - "Webhooks": "", - "Webpage URLs": "", + "Webhooks": "Webhooks", + "Webpage URLs": "URLs de la pàgina", "WebUI Settings": "Preferències de WebUI", "WebUI URL": "URL de WebUI", "WebUI will make requests to \"{{url}}\"": "WebUI farà peticions a \"{{url}}\"", @@ -1859,19 +1859,19 @@ "WebUI will make requests to \"{{url}}/chat/completions\"": "WebUI farà peticions a \"{{url}}/chat/completions\"", "What are you trying to achieve?": "Què intentes aconseguir?", "What are you working on?": "En què estàs treballant?", - "What is NOT shared:": "", - "What is shared:": "", + "What is NOT shared:": "Què no es comparteix", + "What is shared:": "Què es comparteix", "What's New in": "Què hi ha de nou a", "What's on your mind?": "Què tens en ment?", "When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "Quan està activat, el model respondrà a cada missatge de xat en temps real, generant una resposta tan bon punt l'usuari envia un missatge. Aquest mode és útil per a aplicacions de xat en directe, però pot afectar el rendiment en maquinari més lent.", "wherever you are": "allà on estiguis", "Whether to paginate the output. Each page will be separated by a horizontal rule and page number. Defaults to False.": "Si es pagina la sortida. Cada pàgina estarà separada per una regla horitzontal i un número de pàgina. Per defecte és Fals.", "Whisper (Local)": "Whisper (local)", - "Who can share to this group": "", + "Who can share to this group": "Qui pot compartir amb aquest grup", "Why?": "Per què?", "Widescreen Mode": "Mode de pantalla ampla", "Width": "amplada", - "Wikipedia": "", + "Wikipedia": "Wikipedia", "Won": "Ha guanyat", "Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text.": "Funciona juntament amb top-k. Un valor més alt (p. ex., 0,95) donarà lloc a un text més divers, mentre que un valor més baix (p. ex., 0,5) generarà un text més concentrat i conservador.", "Workspace": "Espai de treball", @@ -1883,8 +1883,8 @@ "Yacy Instance URL": "URL de la instància de Yacy", "Yacy Password": "Contrasenya de Yacy", "Yacy Username": "Nom d'usuari de Yacy", - "Yahoo": "", - "Yandex": "", + "Yahoo": "Yahoo", + "Yandex": "Yandex", "Yesterday": "Ahir", "Yesterday at {{LOCALIZED_TIME}}": "Ahir a les {{LOCALIZED_TIME}}", "You": "Tu", @@ -1892,12 +1892,12 @@ "You can only chat with a maximum of {{maxCount}} file(s) at a time.": "Només pots xatejar amb un màxim de {{maxCount}} fitxers alhora.", "You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "Pots personalitzar les teves interaccions amb els models de llenguatge afegint memòries mitjançant el botó 'Gestiona' que hi ha a continuació, fent-les més útils i adaptades a tu.", "You cannot upload an empty file.": "No es pot pujar un arxiu buit.", - "You do not have permission to edit this model": "", - "You do not have permission to edit this prompt.": "", - "You do not have permission to save this prompt.": "", + "You do not have permission to edit this model": "No tens permís per editar aquest model", + "You do not have permission to edit this prompt.": "No tens permís per editar aquesta indicació", + "You do not have permission to save this prompt.": "No tens permís per desar aquesta indicació", "You do not have permission to send messages in this channel.": "No tens permís per enviar missatges en aquest canal.", "You do not have permission to send messages in this thread.": "No tens permís per enviar missatges en aquest fil.", - "You do not have permission to upload files to this knowledge base.": "", + "You do not have permission to upload files to this knowledge base.": "No tens permís per carregar fitxers a aquesta base de coneixements.", "You do not have permission to upload files.": "No tens permisos per pujar arxius.", "You have no archived conversations.": "No tens converses arxivades.", "You have shared this chat": "Has compartit aquest xat", @@ -1906,8 +1906,8 @@ "Your Account": "El teu compte", "Your account status is currently pending activation.": "El compte està actualment pendent d'activació", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Tota la teva contribució anirà directament al desenvolupador del complement; Open WebUI no se'n queda cap percentatge. Tanmateix, la plataforma de finançament escollida pot tenir les seves pròpies comissions.", - "Your message text or inputs": "", - "Your usage stats have been successfully synced.": "", + "Your message text or inputs": "El text o les entrades del teu missatge", + "Your usage stats have been successfully synced.": "Les teves estadístiques d'ús s'han sincronitzat correctament.", "YouTube": "Youtube", "Youtube Language": "Idioma de YouTube", "Youtube Proxy URL": "URL de Proxy de Youtube" From 24044b42ea97f8fd855472b2c0abc497a813843b Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 11 Jan 2026 20:35:38 +0100 Subject: [PATCH 0010/1854] fix(db): release connection before LLM call in Ollama /v1/chat/completions (#20569) Remove Depends(get_session) from the /v1/chat/completions endpoint to prevent database connections from being held during the entire duration of LLM calls. Previously, the database session was acquired at request start and held until the streaming response completed. Under concurrent load, this exhausted the connection pool, causing QueuePool timeout errors. The fix allows Models.get_model_by_id() and has_access() to manage their own short-lived sessions internally, releasing the connection immediately after authorization checks complete. --- backend/open_webui/routers/ollama.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/backend/open_webui/routers/ollama.py b/backend/open_webui/routers/ollama.py index b269aa329a..9cfff0c9de 100644 --- a/backend/open_webui/routers/ollama.py +++ b/backend/open_webui/routers/ollama.py @@ -1464,8 +1464,11 @@ async def generate_openai_chat_completion( form_data: dict, url_idx: Optional[int] = None, user=Depends(get_verified_user), - db: Session = Depends(get_session), ): + # NOTE: We intentionally do NOT use Depends(get_session) here. + # Database operations (get_model_by_id, has_access) manage their own short-lived sessions. + # This prevents holding a connection during the entire LLM call (30-60+ seconds), + # which would exhaust the connection pool under concurrent load. metadata = form_data.pop("metadata", None) try: @@ -1485,7 +1488,7 @@ async def generate_openai_chat_completion( if ":" not in model_id: model_id = f"{model_id}:latest" - model_info = Models.get_model_by_id(model_id, db=db) + model_info = Models.get_model_by_id(model_id) if model_info: if model_info.base_model_id: payload["model"] = model_info.base_model_id @@ -1506,7 +1509,6 @@ async def generate_openai_chat_completion( user.id, type="read", access_control=model_info.access_control, - db=db, ) ): raise HTTPException( From 9e596f861651766a1b7d043bb4a989d0dba61bc5 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 11 Jan 2026 20:35:46 +0100 Subject: [PATCH 0011/1854] fix(db): release connection before LLM call in Ollama /v1/completions (#20570) Remove Depends(get_session) from the /v1/completions endpoint to prevent database connections from being held during the entire duration of LLM calls. Previously, the database session was acquired at request start and held until the response completed. Under concurrent load, this exhausted the connection pool, causing QueuePool timeout errors. The fix allows Models.get_model_by_id() and has_access() to manage their own short-lived sessions internally, releasing the connection immediately after authorization checks complete. --- backend/open_webui/routers/ollama.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/backend/open_webui/routers/ollama.py b/backend/open_webui/routers/ollama.py index 9cfff0c9de..cfbdbcac08 100644 --- a/backend/open_webui/routers/ollama.py +++ b/backend/open_webui/routers/ollama.py @@ -1381,8 +1381,11 @@ async def generate_openai_completion( form_data: dict, url_idx: Optional[int] = None, user=Depends(get_verified_user), - db: Session = Depends(get_session), ): + # NOTE: We intentionally do NOT use Depends(get_session) here. + # Database operations (get_model_by_id, has_access) manage their own short-lived sessions. + # This prevents holding a connection during the entire LLM call (30-60+ seconds), + # which would exhaust the connection pool under concurrent load. metadata = form_data.pop("metadata", None) try: @@ -1402,7 +1405,7 @@ async def generate_openai_completion( if ":" not in model_id: model_id = f"{model_id}:latest" - model_info = Models.get_model_by_id(model_id, db=db) + model_info = Models.get_model_by_id(model_id) if model_info: if model_info.base_model_id: payload["model"] = model_info.base_model_id @@ -1419,7 +1422,6 @@ async def generate_openai_completion( user.id, type="read", access_control=model_info.access_control, - db=db, ) ): raise HTTPException( From 1cb751d18463cb41dec3769f43b8819c135b07d9 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 11 Jan 2026 20:36:36 +0100 Subject: [PATCH 0012/1854] fix(db): release connection before embedding in knowledge /{id}/update (#20574) Remove Depends(get_session) from POST /{id}/update endpoint to prevent database connections from being held during embedding API calls (1-5+ seconds). All database operations (get_knowledge_by_id, has_access, has_permission, update_knowledge_by_id, get_file_metadatas_by_id) manage their own short-lived sessions internally, releasing connections before and after the slow embed_knowledge_base_metadata() call. --- backend/open_webui/routers/knowledge.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/backend/open_webui/routers/knowledge.py b/backend/open_webui/routers/knowledge.py index c38c5e0bdf..65836a8d16 100644 --- a/backend/open_webui/routers/knowledge.py +++ b/backend/open_webui/routers/knowledge.py @@ -419,9 +419,12 @@ async def update_knowledge_by_id( id: str, form_data: KnowledgeForm, user=Depends(get_verified_user), - db: Session = Depends(get_session), ): - knowledge = Knowledges.get_knowledge_by_id(id=id, db=db) + # NOTE: We intentionally do NOT use Depends(get_session) here. + # Database operations manage their own short-lived sessions internally. + # This prevents holding a connection during embed_knowledge_base_metadata() + # which makes external embedding API calls (1-5+ seconds). + knowledge = Knowledges.get_knowledge_by_id(id=id) if not knowledge: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, @@ -430,7 +433,7 @@ async def update_knowledge_by_id( # Is the user the original creator, in a group with write access, or an admin if ( knowledge.user_id != user.id - and not has_access(user.id, "write", knowledge.access_control, db=db) + and not has_access(user.id, "write", knowledge.access_control) and user.role != "admin" ): raise HTTPException( @@ -446,12 +449,11 @@ async def update_knowledge_by_id( user.id, "sharing.public_knowledge", request.app.state.config.USER_PERMISSIONS, - db=db, ) ): form_data.access_control = {} - knowledge = Knowledges.update_knowledge_by_id(id=id, form_data=form_data, db=db) + knowledge = Knowledges.update_knowledge_by_id(id=id, form_data=form_data) if knowledge: # Re-embed knowledge base for semantic search await embed_knowledge_base_metadata( @@ -462,7 +464,7 @@ async def update_knowledge_by_id( ) return KnowledgeFilesResponse( **knowledge.model_dump(), - files=Knowledges.get_file_metadatas_by_id(knowledge.id, db=db), + files=Knowledges.get_file_metadatas_by_id(knowledge.id), ) else: raise HTTPException( From 33e8a098809860c9f663d7729155686b1788ddaf Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 11 Jan 2026 20:37:05 +0100 Subject: [PATCH 0013/1854] fix(db): release connection before embedding in knowledge /create (#20575) Remove Depends(get_session) from POST /create endpoint to prevent database connections from being held during embedding API calls (1-5+ seconds). The has_permission() and Knowledges.insert_new_knowledge() functions manage their own short-lived sessions internally, releasing connections before the slow embed_knowledge_base_metadata() call begins. --- backend/open_webui/routers/knowledge.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/backend/open_webui/routers/knowledge.py b/backend/open_webui/routers/knowledge.py index 65836a8d16..96136d6898 100644 --- a/backend/open_webui/routers/knowledge.py +++ b/backend/open_webui/routers/knowledge.py @@ -227,10 +227,13 @@ async def create_new_knowledge( request: Request, form_data: KnowledgeForm, user=Depends(get_verified_user), - db: Session = Depends(get_session), ): + # NOTE: We intentionally do NOT use Depends(get_session) here. + # Database operations (has_permission, insert_new_knowledge) manage their own sessions. + # This prevents holding a connection during embed_knowledge_base_metadata() + # which makes external embedding API calls (1-5+ seconds). if user.role != "admin" and not has_permission( - user.id, "workspace.knowledge", request.app.state.config.USER_PERMISSIONS, db=db + user.id, "workspace.knowledge", request.app.state.config.USER_PERMISSIONS ): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, @@ -245,12 +248,11 @@ async def create_new_knowledge( user.id, "sharing.public_knowledge", request.app.state.config.USER_PERMISSIONS, - db=db, ) ): form_data.access_control = {} - knowledge = Knowledges.insert_new_knowledge(user.id, form_data, db=db) + knowledge = Knowledges.insert_new_knowledge(user.id, form_data) if knowledge: # Embed knowledge base for semantic search From 1dc353433a9f9a0ce945f1cc0e4db708da6f208e Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 11 Jan 2026 20:37:47 +0100 Subject: [PATCH 0014/1854] fix(db): release connection before embedding in memory /query (#20579) Remove Depends(get_session) from POST /query endpoint to prevent database connections from being held during embedding API calls (1-5+ seconds). The Memories.get_memories_by_user_id() function manages its own short-lived session internally, releasing the connection before the slow EMBEDDING_FUNCTION() call begins. --- backend/open_webui/routers/memories.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/routers/memories.py b/backend/open_webui/routers/memories.py index 96b4716987..e8546b9efd 100644 --- a/backend/open_webui/routers/memories.py +++ b/backend/open_webui/routers/memories.py @@ -122,8 +122,11 @@ async def query_memory( request: Request, form_data: QueryMemoryForm, user=Depends(get_verified_user), - db: Session = Depends(get_session), ): + # NOTE: We intentionally do NOT use Depends(get_session) here. + # Database operations (get_memories_by_user_id) manage their own short-lived sessions. + # This prevents holding a connection during EMBEDDING_FUNCTION() + # which makes external embedding API calls (1-5+ seconds). if not request.app.state.config.ENABLE_MEMORIES: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, @@ -138,7 +141,7 @@ async def query_memory( detail=ERROR_MESSAGES.ACCESS_PROHIBITED, ) - memories = Memories.get_memories_by_user_id(user.id, db=db) + memories = Memories.get_memories_by_user_id(user.id) if not memories: raise HTTPException(status_code=404, detail="No memories found for user") From 0fb4cceec1a3d3525f284ebf92fc157e26874dcf Mon Sep 17 00:00:00 2001 From: _00_ <131402327+rgaricano@users.noreply.github.com> Date: Sun, 11 Jan 2026 20:39:52 +0100 Subject: [PATCH 0015/1854] UPD: i18n: Spanish es-ES Translation v0.7.0 (#20564) ### UPD: i18n: Spanish es-ES Translation v0.7.0 - Added new strings --- src/lib/i18n/locales/es-ES/translation.json | 174 ++++++++++---------- 1 file changed, 87 insertions(+), 87 deletions(-) diff --git a/src/lib/i18n/locales/es-ES/translation.json b/src/lib/i18n/locales/es-ES/translation.json index afa86a5680..6715d681e9 100644 --- a/src/lib/i18n/locales/es-ES/translation.json +++ b/src/lib/i18n/locales/es-ES/translation.json @@ -47,7 +47,7 @@ "Activate this command by typing \"/{{COMMAND}}\" to chat input.": "Activar este comando escribiendo \"/{{COMMAND}}\" en el chat", "Active": "Activo", "Active Users": "Usuarios activos", - "Activity": "", + "Activity": "Actividad", "Add": "Añadir", "Add a model ID": "Añadir un ID de modelo", "Add a short description about what this model does": "Añadir una breve descripción sobre lo que hace este modelo", @@ -78,7 +78,7 @@ "Adjusting these settings will apply changes universally to all users.": "El ajuste de estas opciones se aplicará globalmente a todos los usuarios.", "admin": "admin", "Admin": "Admin", - "Admin Contact Email": "", + "Admin Contact Email": "Email de Contacto del Admin", "Admin Panel": "Administración", "Admin Settings": "Ajustes de Admin", "Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "Los administradores tienen acceso a todas las herramientas en todo momento; los usuarios necesitan que los modelos tengan asignadas las herramientas en el area de trabajo.", @@ -131,7 +131,7 @@ "and {{COUNT}} more": "y {{COUNT}} más", "and create a new shared link.": "y crear un nuevo enlace compartido.", "Android": "Android", - "Anyone": "", + "Anyone": "Cualquiera", "API Base URL": "URL Base API", "API Base URL for Datalab Marker service. Defaults to: https://www.datalab.to/api/v1/marker": "URL Base API para Datalab Marker service. La Predeterminada es: https://www.datalab.to/api/v1/marker", "API Key": "Clave API ", @@ -177,7 +177,7 @@ "Authenticate": "Autentificar", "Authentication": "Autenticación", "Auto": "Auto", - "Auto (Random)": "", + "Auto (Random)": "Auto (Aleatorio)", "Auto-Copy Response to Clipboard": "AutoCopiado de respuesta al Portapapeles", "Auto-playback response": "Reproducir Respuesta automáticamente", "Autocomplete Generation": "Generación de Autocompletado", @@ -186,7 +186,7 @@ "AUTOMATIC1111 Api Auth String": "Auth API para AUTOMATIC1111", "AUTOMATIC1111 Base URL": "URL Base de AUTOMATIC1111", "AUTOMATIC1111 Base URL is required.": "la URL Base de AUTOMATIC1111 es necesaria.", - "Automatically inject system tools in native function calling mode (e.g., timestamps, memory, chat history, notes, etc.)": "", + "Automatically inject system tools in native function calling mode (e.g., timestamps, memory, chat history, notes, etc.)": "Inyectar automáticamente herramientas del sistema en el modo de llamada de función nativa (ej.: marcas de tiempo, memoria, historial de chat, notas, etc.)", "Available list": "Lista disponible", "Available Tools": "Herramientas Disponibles", "available users": "usuarios disponibles", @@ -205,7 +205,7 @@ "before": "antes", "Being lazy": "Ser perezoso", "Beta": "Beta", - "Bing": "", + "Bing": "Bing", "Bing Search V7 Endpoint": "Endpoint de Bing Search V7", "Bing Search V7 Subscription Key": "Clave de Suscripción de Bing Search V7", "Bio": "Bio", @@ -214,14 +214,14 @@ "Bocha Search API Key": "Clave API de Bocha Search", "Bold": "Negrita", "Boosting or penalizing specific tokens for constrained responses. Bias values will be clamped between -100 and 100 (inclusive). (Default: none)": "Impulsando o penalizando tokens específicos para respuestas restringidas. Los valores de sesgo se limitarán entre -100 y 100 (inclusive). (Por defecto: ninguno)", - "Brave": "", + "Brave": "Brave", "Brave Search API Key": "Clave API de Brave Search", - "Builtin Tools": "", + "Builtin Tools": "Herramientas Integradas", "Bullet List": "Lista de Viñetas", "Button ID": "ID del Botón", "Button Label": "Etiqueta del Botón", "Button Prompt": "Indicador del Botón", - "by {{name}}": "", + "by {{name}}": "por {{name}}", "By {{name}}": "Por {{name}}", "Bypass Embedding and Retrieval": "Desactivar Incrustración y Recuperación", "Bypass Web Loader": "Desactivar Cargar de Web", @@ -264,10 +264,10 @@ "Check for updates": "Buscar actualizaciones", "Checking for updates...": "Buscando actualizaciones...", "Choose a model before saving...": "Escoge un modelo antes de guardar...", - "Chunk Min Size Target": "", + "Chunk Min Size Target": "Tamaño Mínimo del Fragmento", "Chunk Overlap": "Superposición de Fragmentos", "Chunk Size": "Tamaño de los Fragmentos", - "Chunks smaller than this threshold will be merged with neighboring chunks when possible. Set to 0 to disable merging.": "", + "Chunks smaller than this threshold will be merged with neighboring chunks when possible. Set to 0 to disable merging.": "Los fragmentos menores a este umbral se fusionarán con los fragmentos vecinos cuando sea posible. Establézcalo en 0 para deshabilitar la fusión.", "Ciphers": "Cifrado", "Citation": "Cita", "Citations": "Citas", @@ -302,8 +302,8 @@ "CMU ARCTIC speaker embedding name": "Nombre de incrustación CMU ARCTIC del interlocutor", "Code Block": "Bloque de Código", "Code Editor": "Editor de Código", - "Code execution": "Ejecución de Código", - "Code Execution": "", + "Code execution": "Ejecución de código", + "Code Execution": "Ejecución de Código", "Code Execution Engine": "Motor de Ejecución de Código", "Code Execution Timeout": "Tiempo límite de espera para Ejecución de Código", "Code formatted successfully": "El codigo se ha formateado correctamente.", @@ -346,7 +346,7 @@ "Contact Admin for WebUI Access": "Contacta con Admin para obtener acceso a WebUI", "Content": "Contenido", "Content Extraction Engine": "Motor para la Extracción de Contenido", - "Content lengths (character counts only)": "", + "Content lengths (character counts only)": "Longitud del contenido (solo recuento de caracteres)", "Continue Response": "Continuar Respuesta", "Continue with {{provider}}": "Continuar con {{provider}}", "Continue with Email": "Continuar con Email", @@ -367,7 +367,7 @@ "Copy link": "Copiar Enlace", "Copy Link": "Copiar enlace", "Copy to clipboard": "Copia a portapapeles", - "Copy URL": "", + "Copy URL": "Copiar URL", "Copying to clipboard was successful!": "¡La copia al portapapeles se ha realizado correctamente!", "CORS must be properly configured by the provider to allow requests from Open WebUI.": "El protocolo CORS debe estar configurado correctamente por el proveedor para permitir solicitudes desde Open WebUI.", "Create": "Crear", @@ -391,7 +391,7 @@ "Created At": "Creado En", "Created by": "Creado por", "Created by you": "Creado por tí", - "Created on {{date}}": "", + "Created on {{date}}": "Creado el {{date}}", "CSV Import": "Importar CSV", "Ctrl+Enter to Send": "'Ctrl+Enter' para Enviar", "Current Model": "Modelo Actual", @@ -406,7 +406,7 @@ "Database": "Base de datos", "Datalab Marker API": "API de Datalab Marker", "DD/MM/YYYY": "DD/MM/YYYY", - "DDGS Backend": "", + "DDGS Backend": "DDGS Backend", "December": "Diciembre", "Decrease UI Scale": "Reducir la Escala de la IU", "Deepgram": "Deepgram", @@ -447,7 +447,7 @@ "delete this link": "Borrar este enlace", "Delete tool?": "¿Borrar la herramienta?", "Delete User": "Borrar Usuario", - "Deleted": "", + "Deleted": "Borrado", "Deleted {{deleteModelTag}}": "{{deleteModelTag}} Borrado", "Deleted {{name}}": "{{nombre}} Borrado", "Deleted User": "Usuario Borrado", @@ -489,7 +489,7 @@ "Dive into knowledge": "Sumérgete en el conocimiento", "Do not install functions from sources you do not fully trust.": "¡No instalar funciones de fuentes en las que que no se confíe totalmente!", "Do not install tools from sources you do not fully trust.": "¡No instalar herramientas de fuentes en las que no se confíe totalmente!", - "Do you want to sync your usage stats with Open WebUI Community?": "", + "Do you want to sync your usage stats with Open WebUI Community?": "¿Quieres sincronizar tus estadísticas de uso con Open WebUI Community?", "Docling": "Docling", "Docling Parameters": "Parámetros de Docling", "Docling Server URL required.": "Docling URL del servidor necesaria.", @@ -498,7 +498,7 @@ "Document Intelligence endpoint required.": "Endpoint Azure Doc Intelligence requerido", "Document Intelligence Model": "Modelo para Doc Intelligence", "Documentation": "Documentación", - "Documents": "", + "Documents": "Documentos", "does not make any external connections, and your data stays securely on your locally hosted server.": "no se realiza ninguna conexión externa y tus datos permanecen seguros alojados localmente en tu servidor.", "Domain Filter List": "Lista de Filtrado de Dominio", "don't fetch random pipelines from sources you don't trust.": "No obtengas pipelines aleatorias de fuentes no confiables.", @@ -509,20 +509,20 @@ "Done": "Hecho", "Download": "Descargar", "Download & Delete": "Descargar y eliminar", - "Download as JSON": "", + "Download as JSON": "Descargar como JSON", "Download as SVG": "Descargar como SVG", "Download canceled": "Descarga cancelada", "Download Database": "Descargar Base de Datos", - "Downloading stats...": "", + "Downloading stats...": "Descargando estadísticas...", "Draw": "Dibujar", "Drop any files here to upload": "Arrastra aquí los archivos a subir.", - "DuckDuckGo": "", + "DuckDuckGo": "DuckDuckGo", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "p.ej. '30s','10m'. Unidades de tiempo válidas son 's', 'm', 'h'.", "e.g. \"json\" or a JSON schema": "p.ej. \"json\" o un esquema JSON", "e.g. 60": "p.ej. 60", "e.g. A filter to remove profanity from text": "p.ej. Un filtro para eliminar malas palabras del texto", "e.g. about the Roman Empire": "p.ej. sobre el imperio romano", - "e.g. alloy, echo, shimmer": "", + "e.g. alloy, echo, shimmer": "p.ej. aleación, eco, brillo", "e.g. en": "p.ej. es", "e.g. My Filter": "p.ej. Mi Filtro", "e.g. My Tools": "p.ej. Mis Herramientas", @@ -592,7 +592,7 @@ "Enter Bocha Search API Key": "Ingresar la Clave API de Bocha Search", "Enter Brave Search API Key": "Ingresar la Clave API de Brave Search", "Enter certificate path": "Ingresar la ruta del certificado", - "Enter Chunk Min Size Target": "", + "Enter Chunk Min Size Target": "Introduce el Tamaño Mínimo de Fragmento", "Enter Chunk Overlap": "Ingresar Superposición de los Fragmentos", "Enter Chunk Size": "Ingresar el Tamaño del Fragmento", "Enter comma-separated \"token:bias_value\" pairs (example: 5432:100, 413:-100)": "Ingresar pares \"token:valor_sesgo\" separados por comas (ejemplo: 5432:100, 413:-100)", @@ -616,7 +616,7 @@ "Enter External Web Search URL": "Ingresar URL del Buscador Web Externo", "Enter Firecrawl API Base URL": "Ingresar URL Base del API de Firecrawl", "Enter Firecrawl API Key": "Ingresar Clave del API de Firecrawl", - "Enter Firecrawl Timeout": "", + "Enter Firecrawl Timeout": "Ingresar Timeout para Firecrawl", "Enter folder name": "Ingresar nombre de la carpeta", "Enter function name filter list (e.g. func1, !func2)": "Ingresar lista para el filtro de nombres de función (p.ej.: func1, !func2)", "Enter Github Raw URL": "Ingresar URL Github en Bruto(raw)", @@ -625,7 +625,7 @@ "Enter hex color (e.g. #FF0000)": "Ingresa color hex (ej. #FF0000)", "Enter ID": "Ingresar ID", "Enter Image Size (e.g. 512x512)": "Ingresar Tamaño de Imagen (p.ej. 512x512)", - "Enter Jina API Base URL": "", + "Enter Jina API Base URL": "Ingresar URL Base de la API de Jina", "Enter Jina API Key": "Ingresar Clave API de Jina", "Enter JSON config (e.g., {\"disable_links\": true})": "Ingresar config JSON (ej., {\"disable_links\": true})", "Enter Jupyter Password": "Ingresar Contraseña de Jupyter", @@ -634,7 +634,7 @@ "Enter Kagi Search API Key": "Ingresar Clave API de Kagi Search", "Enter Key Behavior": "Comportamiento de la Tecla de Envío", "Enter language codes": "Ingresar Códigos de Idioma", - "Enter MinerU API Key": "", + "Enter MinerU API Key": "Ingresar Clave API de MinerU", "Enter Mistral API Base URL": "Ingresar la URL Base de la API de Mistral", "Enter Mistral API Key": "Ingresar Clave API de Mistral", "Enter Model ID": "Ingresar ID del Modelo", @@ -760,7 +760,7 @@ "Failed to generate title": "Fallo al generar el título", "Failed to import models": "Fallo al importar modelos", "Failed to load chat preview": "Fallo al cargar la previsualización del chat", - "Failed to load Excel/CSV file. Please try downloading it instead.": "", + "Failed to load Excel/CSV file. Please try downloading it instead.": "Fallo al cargar el archivo Excel/CSV. Por favor, en su lugar intente descargarlo.", "Failed to load file content.": "Fallo al cargar el contenido del archivo", "Failed to move chat": "Fallo al mover el chat", "Failed to process URL: {{url}}": "Fallo al procesar la URL", @@ -777,7 +777,7 @@ "Features": "Características", "Features Permissions": "Permisos de las Características", "February": "Febrero", - "Feedback": "", + "Feedback": "Opinión", "Feedback deleted successfully": "Opinión eliminada correctamente", "Feedback Details": "Detalle de la Opinión", "Feedback History": "Historia de la Opiniones", @@ -786,7 +786,7 @@ "File": "Archivo", "File added successfully.": "Archivo añadido correctamente.", "File content updated successfully.": "Contenido del archivo actualizado correctamente.", - "File Context": "", + "File Context": "Contexto del Archivo", "File Mode": "Modo de Archivo", "File not found.": "Archivo no encontrado.", "File removed successfully.": "Archivo eliminado correctamente.", @@ -802,13 +802,13 @@ "Fingerprint spoofing detected: Unable to use initials as avatar. Defaulting to default profile image.": "Se detectó suplantación de huellas: No se pueden usar las iniciales como avatar. Se establece la imagen de perfil predeterminada.", "Firecrawl API Base URL": "URL Base de API de Firecrawl", "Firecrawl API Key": "Clave de API de Firecrawl", - "Firecrawl Timeout (s)": "", + "Firecrawl Timeout (s)": "Timeout (s) para Firecrawl", "Floating Quick Actions": "Acciones Rápidas Flotantes", "Focus Chat Input": "Enfocar a la Entrada del Chat", "Folder": "Carpeta", "Folder Background Image": "Imagen de Fondo de la Carpeta", "Folder deleted successfully": "Carpeta eliminada correctamente", - "Folder Max File Count": "", + "Folder Max File Count": "Máximo Número de Ficheros en Carpeta", "Folder Name": "Nombre de la Carpeta", "Folder name cannot be empty.": "El nombre de la carpeta no puede estar vacío", "Folder name updated successfully": "Nombre de la carpeta actualizado correctamente", @@ -863,13 +863,13 @@ "Get started with {{WEBUI_NAME}}": "Empezar con {{WEBUI_NAME}}", "Global": "Global", "Good Response": "Buena Respuesta", - "Google": "", + "Google": "Google", "Google Drive": "Google Drive", "Google PSE API Key": "Clave API de Google PSE", "Google PSE Engine Id": "ID del Motor PSE de Google", "Gravatar": "Gravatar", "Grid": "Cuadrícula", - "Grokipedia": "", + "Grokipedia": "Grokipedia", "Group": "Grupo", "Group Channel": "Canal de Grupo", "Group created successfully": "Grupo creado correctamente", @@ -923,7 +923,7 @@ "Image Prompt Generation": "Indicador para Generación de Imagen", "Image Prompt Generation Prompt": "Indicador para la Generación del Indicador de Imagen", "Image Size": "Tamaño de la Imagen", - "Images": "", + "Images": "Imágenes", "Import": "Importar", "Import Chats": "Importar Chats", "Import Config from JSON File": "Importar Config desde Archivo JSON", @@ -942,7 +942,7 @@ "Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive.": "Influye en la rápidez de respuesta a la realimentación desde el texto generado. Una tasa de aprendizaje más baja resulta en un ajustado más lento, mientras que una tasa de aprendizaje más alta hará que el algoritmo sea más reactivo.", "Info": "Información", "Initials": "Iniciales", - "Inject file content into conversation context": "", + "Inject file content into conversation context": "Inyectar el contenido del archivo en el contexto de la conversación", "Inject the entire content as context for comprehensive processing, this is recommended for complex queries.": "Inyecta el contenido completo como contexto para un procesado comprensivo, recomendado para consultas complejas.", "Input": "Entrada", "Input Key (e.g. text, unet_name, steps)": "Ingresa Clave (ej. text, unet_name. steps)", @@ -956,7 +956,7 @@ "Integration": "Integración", "Integrations": "Integraciones", "Interface": "Interfaz", - "Interface Settings Access": "", + "Interface Settings Access": "Configuración de Acceso al Interfaz", "Invalid file content": "Contenido de archivo inválido", "Invalid file format.": "Formato de archivo inválido.", "Invalid JSON file": "Archivo JSON inválido", @@ -970,7 +970,7 @@ "is typing...": "está escribiendo...", "Italic": "Cursiva", "January": "Enero", - "Jina API Base URL": "", + "Jina API Base URL": "URL Base de la API de Jina", "Jina API Key": "Clave API de Jina", "join our Discord for help.": "unete a nuestro Discord para ayuda.", "JSON": "JSON", @@ -995,7 +995,7 @@ "Knowledge created successfully.": "Conocimiento creado correctamente.", "Knowledge deleted successfully.": "Conocimiento eliminado correctamente.", "Knowledge Description": "Descripción del Conocimiento", - "Knowledge exported successfully": "", + "Knowledge exported successfully": "Conocimiento exportado correctamente", "Knowledge Name": "Nombre del Conocimiento", "Knowledge Public Sharing": "Compartir Conocimiento Públicamente", "Knowledge reset successfully.": "Conocimiento restablecido correctamente.", @@ -1022,7 +1022,7 @@ "Leave empty to include all models from \"{{url}}/api/tags\" endpoint": "Dejar vacío para incluir todos los modelos desde el endpoint \"{{url}}/api/tags\"", "Leave empty to include all models from \"{{url}}/models\" endpoint": "Dejar vacío para incluir todos los modelos desde el endpoint \"{{url}}/models\"", "Leave empty to include all models or select specific models": "Dejar vacío para incluir todos los modelos o Seleccionar modelos específicos", - "Leave empty to use first admin user": "", + "Leave empty to use first admin user": "Dejar vacío para utilizar el primer usuario administrador", "Leave empty to use the default model (voxtral-mini-latest).": "Dejar vacío para usar el modo predeterminado (voxtral-mini-latest).", "Leave empty to use the default prompt, or enter a custom prompt": "Dejar vacío para usar el indicador predeterminado, o Ingresar un indicador personalizado", "Leave model field empty to use the default model.": "Dejar vacío el campo modelo para usar el modelo predeterminado.", @@ -1062,12 +1062,12 @@ "Manage your account information.": "Gestionar la información de tu cuenta", "March": "Marzo", "Markdown": "Markdown", - "Markdown Header Text Splitter": "", + "Markdown Header Text Splitter": "Divisor de Texto Encabezado de Markdown", "Max Speakers": "Max Interlocutores", "Max Upload Count": "Número Max de Subidas", "Max Upload Size": "Tamaño Max de Subidas", - "Maximum number of files allowed per folder.": "", - "Maximum number of files per folder is {{max}}.": "", + "Maximum number of files allowed per folder.": "Número máximo de archivos permitidos por carpeta", + "Maximum number of files per folder is {{max}}.": "El número máximo de archivos permitidos por carpeta es {{max}}.", "Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Se puede descargar un máximo de 3 modelos simultáneamente. Por favor, reinténtelo más tarde.", "May": "Mayo", "MBR": "MBR", @@ -1077,7 +1077,7 @@ "Member removed successfully": "Miembro removido correctamente", "Members": "Miembros", "Members added successfully": "Miembros añadidos correctamente", - "Memories": "", + "Memories": "Memorias", "Memories accessible by LLMs will be shown here.": "Las memorias accesibles por los LLMs se mostrarán aquí.", "Memory": "Memoria", "Memory added successfully": "Memoria añadida correctamente", @@ -1087,7 +1087,7 @@ "Merge Responses": "Fusionar Respuestas", "Merged Response": "Respuesta combinada", "Message": "Mensaje", - "Message counts and response timestamps": "", + "Message counts and response timestamps": "Recuento de mensajes y marcas de tiempo de la respuesta", "Message rating should be enabled to use this feature": "Para usar esta función debe estar habilitada la calificación de mensajes", "Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "Los mensajes que envíe después de la creación del enlace no se compartirán. Los usuarios con la URL del enlace podrán ver el chat compartido.", "Microsoft OneDrive": "Microsoft OneDrive", @@ -1120,11 +1120,11 @@ "Model Name": "Nombre Modelo", "Model name already exists, please choose a different one": "Ese nombre de modelo ya existe, por favor elige otro diferente", "Model Name is required.": "El Nombre de Modelo es requerido", - "Model names and usage frequency": "", + "Model names and usage frequency": "Nombres de modelos y frecuencia de uso", "Model not selected": "Modelo no seleccionado", "Model Params": "Paráms Modelo", "Model Permissions": "Permisos Modelo", - "Model responses or outputs": "", + "Model responses or outputs": "Respuestas del modelo o salidas", "Model unloaded successfully": "Modelo descargado correctamente", "Model updated successfully": "Modelo actualizado correctamente", "Model(s) do not support file upload": "Modelo/s no soportan subida de archivos", @@ -1135,7 +1135,7 @@ "Models imported successfully": "Modelos importados correctamente", "Models Public Sharing": "Compartir Modelos Públicamente", "Models Sharing": "Compartir Modelos", - "Mojeek": "", + "Mojeek": "Mojeek", "Mojeek Search API Key": "Clave API de Mojeek Search", "More": "Más", "More Concise": "Más Conciso", @@ -1157,10 +1157,10 @@ "New Prompt": "Nuevo Indicador", "New Temporary Chat": "Nuevo Chat Temporal", "New Tool": "Nueva Herramienta", - "New Webhook": "", + "New Webhook": "Nuevo Webhook", "new-channel": "nuevo-canal", "Next message": "Siguiente mensaje", - "No activity data": "", + "No activity data": "Sin datos de actividad", "No authentication": "Sin Autentificación", "No chats found": "No se encontró ningún chat", "No chats found for this user.": "No se encontró ningún chat de este usuario", @@ -1171,7 +1171,7 @@ "No conversation to save": "No hay conversación para guardar", "No distance available": "No hay distancia disponible", "No expiration can pose security risks.": "No expiración puede poner la seguridad en riesgo.", - "No feedback found": "", + "No feedback found": "No se encontró ninguna opinión", "No file selected": "No se seleccionó archivo", "No files in this knowledge base.": "Ningún archivo en esta base de conocimiento.", "No functions found": "No se encontraron funciones", @@ -1186,7 +1186,7 @@ "No models selected": "No se seleccionaron modelos", "No Notes": "Sin Notas", "No notes found": "No se encontraron notas", - "No one": "", + "No one": "Ni uno", "No pinned messages": "No hay mensajes fijados", "No prompts found": "No se encontraron indicadores", "No results": "No se encontraron resultados", @@ -1199,7 +1199,7 @@ "No users were found.": "No se encontraron usuarios.", "No valves": "No hay válvulas", "No valves to update": "No hay válvulas para actualizar", - "No webhooks yet": "", + "No webhooks yet": "Todavía no hay webhooks", "Node Ids": "IDs de Nodo", "None": "Ninguno", "Not factually correct": "No es correcto en todos los aspectos", @@ -1239,7 +1239,7 @@ "Only invited users can access": "Solo pueden acceder usuarios invitados", "Only markdown files are allowed": "Solo están permitidos archivos markdown", "Only select users and groups with permission can access": "Solo pueden acceder los usuarios y grupos con permiso", - "Only sync new/updated chats": "", + "Only sync new/updated chats": "Sincronizar solo chats nuevos o actualizados", "Oops! Looks like the URL is invalid. Please double-check and try again.": "¡vaya! Parece que la URL es inválida. Por favor, revisala y reintenta de nuevo.", "Oops! There are files still uploading. Please wait for the upload to complete.": "¡vaya! Todavía hay archivos subiendose. Por favor, espera a que se complete la subida.", "Oops! There was an error in the previous response.": "¡vaya! Hubo un error en la respuesta previa.", @@ -1256,7 +1256,7 @@ "Open WebUI can use tools provided by any OpenAPI server.": "Open-WebUI puede usar herramientas proporcionadas por cualquier servidor OpenAPI", "Open WebUI uses faster-whisper internally.": "Open-WebUI usa faster-whisper internamente.", "Open WebUI uses SpeechT5 and CMU Arctic speaker embeddings.": "Open-WebUI usa SpeechT5 y la incrustración de locutores de CMU Arctic.", - "Open WebUI version": "", + "Open WebUI version": "versión de Open-WebUI", "Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "La versión de Open-WebUI (v{{OPEN_WEBUI_VERSION}}) es inferior a la versión (v{{REQUIRED_VERSION}}) requerida", "OpenAI": "OpenAI", "OpenAI API": "API OpenAI", @@ -1281,8 +1281,8 @@ "page": "página", "Paginate": "Paginar", "Parameters": "Parámetros", - "Parent message not found": "", - "Participate in community leaderboards and evaluations! Syncing aggregated usage stats helps drive research and improvements to Open WebUI. Your privacy is paramount: no message content is ever shared.": "", + "Parent message not found": "Mensaje padre no encontrado", + "Participate in community leaderboards and evaluations! Syncing aggregated usage stats helps drive research and improvements to Open WebUI. Your privacy is paramount: no message content is ever shared.": "¡Participa en las clasificaciones y evaluaciones de la comunidad! La sincronización agregada de estadísticas de uso ayuda a impulsar la investigación y las mejoras de Open-WebUI. Tu privacidad es primordial: nunca se comparte el contenido de los mensajes.", "Password": "Contraseña", "Passwords do not match.": "Las contraseñas no coinciden", "Paste Large Text as File": "Pegar el Texto Largo como Archivo", @@ -1308,8 +1308,8 @@ "Pipe": "Tubo", "Pipeline deleted successfully": "Tubería borrada correctamente", "Pipeline downloaded successfully": "Tubería descargada correctamente", - "Pipelines": "", - "Pipelines are a plugin system with arbitrary code execution —": "Pipelines es un sistema de complementos con ejecución arbitraria de código —", + "Pipelines": "Tuberías", + "Pipelines are a plugin system with arbitrary code execution —": "Tuberías (Pipelines) es un sistema de complementos con ejecución arbitraria de código —", "Pipelines Not Detected": "Servicio de Tuberías (Pipelines) No Detectado", "Pipelines Valves": "Válvulas de Tuberías", "Plain text (.md)": "Texto plano (.md)", @@ -1546,7 +1546,7 @@ "Sets the stop sequences to use. When this pattern is encountered, the LLM will stop generating text and return. Multiple stop patterns may be set by specifying multiple separate stop parameters in a modelfile.": "Establece las secuencias de parada a usar. Cuando se encuentre este patrón, el LLM dejará de generar texto y retornará. Se pueden establecer varios patrones de parada especificando separadamente múltiples parámetros de parada en un archivo de modelo.", "Setting": "Ajuste", "Settings": "Ajustes", - "Settings Permissions": "", + "Settings Permissions": "Ajustes de Permisos", "Settings saved successfully!": "¡Ajustes guardados correctamente!", "Share": "Compartir", "Share Chat": "Compartir Chat", @@ -1590,7 +1590,7 @@ "Speech recognition error: {{error}}": "Error en reconocimiento de voz: {{error}}", "Speech-to-Text": "Voz a Texto", "Speech-to-Text Engine": "Motor Voz a Texto(STT)", - "Split documents by markdown headers before applying character/token splitting.": "", + "Split documents by markdown headers before applying character/token splitting.": "Dividir los documentos por encabezados markdown antes de aplicar la división de caracteres/tokens.", "Start a new conversation": "Comenzar una conversación nueva", "Start of the channel": "Inicio del canal", "Start Tag": "Etiqueta de Inicio", @@ -1601,7 +1601,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Pasos", "Stop": "Detener", - "Stop Download": "", + "Stop Download": "Detener la Descarga", "Stop Generating": "Parar la Generación", "Stop Sequence": "Secuencia de Parada", "Stream Chat Response": "Transmisión Directa de la Respuesta del Chat", @@ -1622,14 +1622,14 @@ "Support": "Soportar", "Support this plugin:": "Apoya este plugin:", "Supported MIME Types": "Tipos MIME Soportados", - "Sync": "", - "Sync Complete!": "", + "Sync": "Sincronizar", + "Sync Complete!": "Sincronización Completa", "Sync directory": "Sincroniza Directorio", - "Sync Failed": "", - "Sync Usage Stats": "", - "Syncing stats...": "", - "Syncing...": "", - "Syncs only chats with updates after your last sync timestamp. Disable to re-sync all chats.": "", + "Sync Failed": "Fallo al Sincronizar", + "Sync Usage Stats": "Sincronizar Estadísticas de Uso", + "Syncing stats...": "Sincronizando estadísticas...", + "Syncing...": "Sincronizando...", + "Syncs only chats with updates after your last sync timestamp. Disable to re-sync all chats.": "Sincroniza solo los chats con actualizaciones posteriores a la última sincronización. Desactiva esta opción para volver a sincronizar todos los chats.", "System": "Sistema", "System Instructions": "Instrucciones del sistema", "System Prompt": "Indicador del sistema", @@ -1674,7 +1674,7 @@ "The Weight of BM25 Hybrid Search. 0 more semantic, 1 more lexical. Default 0.5": "La Ponderación de BM25 en la Búsqueda Híbrida. 0 más semántica, 1 más léxica. Por defecto, 0.5", "The width in pixels to compress images to. Leave empty for no compression.": "El ancho en pixeles al comprimir imágenes. Dejar vacío para no compresión", "Theme": "Tema", - "There was an error syncing your stats. Please try again.": "", + "There was an error syncing your stats. Please try again.": "Se produjo un error al sincronizar tus estadísticas. Por favor, inténtalo de nuevo.", "Thinking...": "Pensando...", "This action cannot be undone. Do you wish to continue?": "Esta acción no se puede deshacer. ¿Desea continuar?", "This channel was created on {{createdAt}}. This is the very beginning of the {{channelName}} channel.": "Este canal fue creado el {{createdAt}}. Este es el comienzo del canal {{channelName}}.", @@ -1788,7 +1788,7 @@ "Upload Pipeline": "Subir Tubería", "Upload Progress": "Progreso de la Subida", "Upload Progress: {{uploadedFiles}}/{{totalFiles}} ({{percentage}}%)": "Progreso de la Subida: {{uploadedFiles}}/{{totalFiles}} ({{percentage}}%)", - "Uploaded files or images": "", + "Uploaded files or images": "Archivos o imágenes cargados", "Uploading file...": "Subiendo archivo...", "URL": "URL", "URL is required": "La URL es requerida", @@ -1806,8 +1806,8 @@ "User Groups": "Grupos de Usuarios", "User location successfully retrieved.": "Ubicación de usuario obtenida correctamente.", "User menu": "Menu de Usuario", - "User ratings (thumbs up/down)": "", - "User Status": "", + "User ratings (thumbs up/down)": "Calificaciones de los usuarios (pulgares arriba/abajo)", + "User Status": "Estado del Usuario", "User Webhooks": "Usuario Webhooks", "Username": "Nombre de Usuario", "users": "usuarios", @@ -1848,9 +1848,9 @@ "Web Search Engine": "Motor Búsqueda Web", "Web Search in Chat": "Búsqueda Web en Chat", "Web Search Query Generation": "Generación de Consulta Búsqueda Web", - "Webhook Name": "", + "Webhook Name": "Nombre del Webhook", "Webhook URL": "URL EnganchesWeb(Webhook)", - "Webhooks": "", + "Webhooks": "Webhooks", "Webpage URLs": "URLS de PáginasWeb", "WebUI Settings": "WebUI Ajustes", "WebUI URL": "WebUI URL", @@ -1859,19 +1859,19 @@ "WebUI will make requests to \"{{url}}/chat/completions\"": "WebUI hará solicitudes a \"{{url}}/chat/completions\"", "What are you trying to achieve?": "¿Qué estás tratando de conseguir?", "What are you working on?": "¿En qué estás trabajando?", - "What is NOT shared:": "", - "What is shared:": "", + "What is NOT shared:": "Que NO es compartido:", + "What is shared:": "Que es compartido:", "What's New in": "Que hay de Nuevo en", "What's on your mind?": "¿En que estás pensando?", "When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "Cuando está habilitado, el modelo responderá a cada mensaje de chat en tiempo real, generando una respuesta tan pronto como se envíe un mensaje. Este modo es útil para aplicaciones de chat en vivo, pero puede afectar al rendimiento en equipos más lentos.", "wherever you are": "dondequiera que estés", "Whether to paginate the output. Each page will be separated by a horizontal rule and page number. Defaults to False.": "Al paginar la salida. Cada página será separada por una línea horizontal y número de página. Por defecto: Falso", "Whisper (Local)": "Whisper (Local)", - "Who can share to this group": "", + "Who can share to this group": "Quién puede compartir en este grupo", "Why?": "¿Por qué?", "Widescreen Mode": "Modo Pantalla Ancha", "Width": "Ancho", - "Wikipedia": "", + "Wikipedia": "Wikipedia", "Won": "Ganó", "Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text.": "Trabaja conjuntamente con top-k. Un valor más alto (p.ej. 0.95) dará lugar a un texto más diverso, mientras que un valor más bajo (p.ej. 0.5) generará un texto más centrado y conservador.", "Workspace": "Espacio de Trabajo", @@ -1883,8 +1883,8 @@ "Yacy Instance URL": "URL de la instancia Yacy", "Yacy Password": "Contraseña de Yacy", "Yacy Username": "Usuario de Yacy", - "Yahoo": "", - "Yandex": "", + "Yahoo": "Yahoo", + "Yandex": "Yandex", "Yesterday": "Ayer", "Yesterday at {{LOCALIZED_TIME}}": "Ayer a las {{LOCALIZED_TIME}}", "You": "Tu", @@ -1892,9 +1892,9 @@ "You can only chat with a maximum of {{maxCount}} file(s) at a time.": "Solo puedes chatear con un máximo de {{maxCount}} archivo(s) a la vez.", "You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "Puedes personalizar tus interacciones con los LLMs añadiendo memorias a través del botón 'Gestionar' debajo, haciendo que te sean más útiles y personalizados.", "You cannot upload an empty file.": "No puedes subir un archivo vacío.", - "You do not have permission to edit this model": "", - "You do not have permission to edit this prompt.": "", - "You do not have permission to save this prompt.": "", + "You do not have permission to edit this model": "No tienes permiso para editar este modelo", + "You do not have permission to edit this prompt.": "No tienes permiso para editar este indicador", + "You do not have permission to save this prompt.": "No tienes permiso para guardar este indicador", "You do not have permission to send messages in this channel.": "No tienes permiso para enviar mensajes en este canal", "You do not have permission to send messages in this thread.": "No tienes permiso para enviar mensajes en este hilo", "You do not have permission to upload files to this knowledge base.": "No tienes permiso para subir archivos a esta base de conocimiento.", @@ -1906,8 +1906,8 @@ "Your Account": "Tu Cuenta", "Your account status is currently pending activation.": "Tu cuenta está pendiente de activación.", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Tu entera contribución irá directamente al desarrollador del complemento; Open-WebUI no recibe ningún porcentaje. Sin embargo, la plataforma de financiación elegida podría tener sus propias tarifas.", - "Your message text or inputs": "", - "Your usage stats have been successfully synced.": "", + "Your message text or inputs": "Tu mensaje de texto o entrada", + "Your usage stats have been successfully synced.": "Tu estadistica de uso ha sido sincronizada", "YouTube": "Youtube", "Youtube Language": "Youtube Idioma", "Youtube Proxy URL": "Youtube URL Proxy" From af584b46f4c09f8d41b26d2cca959eb1825d50d1 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 11 Jan 2026 21:18:41 +0100 Subject: [PATCH 0016/1854] feat: code-interpreter native (#20592) * code-interpreter native * Update tools.py * Update builtin.py * Update builtin.py * Update tools.py * Update builtin.py * Update builtin.py * Update builtin.py * Update builtin.py * Update builtin.py * Update builtin.py * Update builtin.py * Update builtin.py * Update builtin.py * Update builtin.py --- backend/open_webui/tools/builtin.py | 160 ++++++++++++++++++++++++++++ backend/open_webui/utils/tools.py | 11 ++ 2 files changed, 171 insertions(+) diff --git a/backend/open_webui/tools/builtin.py b/backend/open_webui/tools/builtin.py index eb3b7cfc9f..d26e032727 100644 --- a/backend/open_webui/tools/builtin.py +++ b/backend/open_webui/tools/builtin.py @@ -341,6 +341,166 @@ async def edit_image( return json.dumps({"error": str(e)}) +# ============================================================================= +# CODE INTERPRETER TOOLS +# ============================================================================= + + +async def execute_code( + code: str, + __request__: Request = None, + __user__: dict = None, + __event_emitter__: callable = None, + __event_call__: callable = None, + __chat_id__: str = None, + __message_id__: str = None, + __metadata__: dict = None, +) -> str: + """ + Execute Python code in a sandboxed environment and return the output. + Use this to perform calculations, data analysis, generate visualizations, + or run any Python code that would help answer the user's question. + + :param code: The Python code to execute + :return: JSON with stdout, stderr, and result from execution + """ + from uuid import uuid4 + + if __request__ is None: + return json.dumps({"error": "Request context not available"}) + + try: + # Import blocked modules from config (same as middleware) + from open_webui.config import CODE_INTERPRETER_BLOCKED_MODULES + + # Add import blocking code if there are blocked modules + if CODE_INTERPRETER_BLOCKED_MODULES: + import textwrap + blocking_code = textwrap.dedent( + f""" + import builtins + + BLOCKED_MODULES = {CODE_INTERPRETER_BLOCKED_MODULES} + + _real_import = builtins.__import__ + def restricted_import(name, globals=None, locals=None, fromlist=(), level=0): + if name.split('.')[0] in BLOCKED_MODULES: + importer_name = globals.get('__name__') if globals else None + if importer_name == '__main__': + raise ImportError( + f"Direct import of module {{name}} is restricted." + ) + return _real_import(name, globals, locals, fromlist, level) + + builtins.__import__ = restricted_import + """ + ) + code = blocking_code + "\n" + code + + engine = getattr(__request__.app.state.config, "CODE_INTERPRETER_ENGINE", "pyodide") + if engine == "pyodide": + # Execute via frontend pyodide using bidirectional event call + if __event_call__ is None: + return json.dumps({"error": "Event call not available. WebSocket connection required for pyodide execution."}) + + output = await __event_call__( + { + "type": "execute:python", + "data": { + "id": str(uuid4()), + "code": code, + "session_id": __metadata__.get("session_id") if __metadata__ else None, + }, + } + ) + + # Parse the output - pyodide returns dict with stdout, stderr, result + if isinstance(output, dict): + stdout = output.get("stdout", "") + stderr = output.get("stderr", "") + result = output.get("result", "") + else: + stdout = "" + stderr = "" + result = str(output) if output else "" + + elif engine == "jupyter": + from open_webui.utils.code_interpreter import execute_code_jupyter + + output = await execute_code_jupyter( + __request__.app.state.config.CODE_INTERPRETER_JUPYTER_URL, + code, + ( + __request__.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN + if __request__.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH == "token" + else None + ), + ( + __request__.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD + if __request__.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH == "password" + else None + ), + __request__.app.state.config.CODE_INTERPRETER_JUPYTER_TIMEOUT, + ) + + stdout = output.get("stdout", "") + stderr = output.get("stderr", "") + result = output.get("result", "") + + else: + return json.dumps({"error": f"Unknown code interpreter engine: {engine}"}) + + # Handle image outputs (base64 encoded) - replace with uploaded URLs + # Get actual user object for image upload (upload_image requires user.id attribute) + if __user__ and __user__.get("id"): + from open_webui.models.users import Users + from open_webui.utils.files import get_image_url_from_base64 + + user = Users.get_user_by_id(__user__["id"]) + + # Extract and upload images from stdout + if stdout and isinstance(stdout, str): + stdout_lines = stdout.split("\n") + for idx, line in enumerate(stdout_lines): + if "data:image/png;base64" in line: + image_url = get_image_url_from_base64( + __request__, + line, + __metadata__ or {}, + user, + ) + if image_url: + stdout_lines[idx] = f"![Output Image]({image_url})" + stdout = "\n".join(stdout_lines) + + # Extract and upload images from result + if result and isinstance(result, str): + result_lines = result.split("\n") + for idx, line in enumerate(result_lines): + if "data:image/png;base64" in line: + image_url = get_image_url_from_base64( + __request__, + line, + __metadata__ or {}, + user, + ) + if image_url: + result_lines[idx] = f"![Output Image]({image_url})" + result = "\n".join(result_lines) + + response = { + "status": "success", + "stdout": stdout, + "stderr": stderr, + "result": result, + } + + return json.dumps(response, ensure_ascii=False) + except Exception as e: + log.exception(f"execute_code error: {e}") + return json.dumps({"error": str(e)}) + + # ============================================================================= # MEMORY TOOLS # ============================================================================= diff --git a/backend/open_webui/utils/tools.py b/backend/open_webui/utils/tools.py index 6cb6c4b856..77f985ebbc 100644 --- a/backend/open_webui/utils/tools.py +++ b/backend/open_webui/utils/tools.py @@ -51,6 +51,7 @@ from open_webui.tools.builtin import ( fetch_url, generate_image, edit_image, + execute_code, search_memories, add_memory, replace_memory_content, @@ -449,6 +450,14 @@ def get_builtin_tools( ) and get_model_capability("image_generation"): builtin_functions.append(edit_image) + # Add code interpreter tool if enabled globally AND model has code_interpreter capability + # Supports both pyodide (via frontend event call) and jupyter engines + if ( + getattr(request.app.state.config, "ENABLE_CODE_INTERPRETER", True) + and get_model_capability("code_interpreter") + ): + builtin_functions.append(execute_code) + # Notes tools - search, view, create, and update user's notes (if notes enabled globally) if getattr(request.app.state.config, "ENABLE_NOTES", False): builtin_functions.extend( @@ -473,6 +482,8 @@ def get_builtin_tools( "__request__": request, "__user__": extra_params.get("__user__", {}), "__event_emitter__": extra_params.get("__event_emitter__"), + "__event_call__": extra_params.get("__event_call__"), + "__metadata__": extra_params.get("__metadata__"), "__chat_id__": extra_params.get("__chat_id__"), "__message_id__": extra_params.get("__message_id__"), "__model_knowledge__": model_knowledge, From 84d76cccde5717f379255b1d1272f3e2f0427758 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 11 Jan 2026 21:41:28 +0100 Subject: [PATCH 0017/1854] Update translation.json (#20593) --- src/lib/i18n/locales/de-DE/translation.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lib/i18n/locales/de-DE/translation.json b/src/lib/i18n/locales/de-DE/translation.json index 34d668b5ca..b1ca731f7e 100644 --- a/src/lib/i18n/locales/de-DE/translation.json +++ b/src/lib/i18n/locales/de-DE/translation.json @@ -47,7 +47,7 @@ "Activate this command by typing \"/{{COMMAND}}\" to chat input.": "Aktivieren Sie diesen Befehl, indem Sie \"/{{COMMAND}}\" in die Chat-Eingabe tippen.", "Active": "Aktiv", "Active Users": "Aktive Benutzer", - "Activity": "", + "Activity": "Aktivität", "Add": "Hinzufügen", "Add a model ID": "Modell-ID hinzufügen", "Add a short description about what this model does": "Fügen Sie eine kurze Beschreibung der Funktion dieses Modells hinzu", @@ -303,7 +303,7 @@ "Code Block": "Code-Block", "Code Editor": "Code-Editor", "Code execution": "Codeausführung", - "Code Execution": "", + "Code Execution": "Codeausführung", "Code Execution Engine": "Engine zur Codeausführung", "Code Execution Timeout": "Zeitlimit für Codeausführung", "Code formatted successfully": "Code erfolgreich formatiert", @@ -498,7 +498,7 @@ "Document Intelligence endpoint required.": "Dokumentenintelligenz-Endpunkt erforderlich.", "Document Intelligence Model": "Dokumentenintelligenz-Modell", "Documentation": "Dokumentation", - "Documents": "", + "Documents": "Dokumente", "does not make any external connections, and your data stays securely on your locally hosted server.": "stellt keine externen Verbindungen her; Ihre Daten bleiben sicher auf Ihrem lokalen Server.", "Domain Filter List": "Domain-Filterliste", "don't fetch random pipelines from sources you don't trust.": "Laden Sie keine Pipelines aus Quellen, denen Sie nicht vertrauen.", @@ -522,7 +522,7 @@ "e.g. 60": "z. B. 60", "e.g. A filter to remove profanity from text": "z. B. Ein Filter zum Entfernen von Schimpfwörtern", "e.g. about the Roman Empire": "z. B. über das Römische Reich", - "e.g. alloy, echo, shimmer": "", + "e.g. alloy, echo, shimmer": "z. B. alloy, echo, shimmer", "e.g. en": "z. B. de", "e.g. My Filter": "z. B. Mein Filter", "e.g. My Tools": "z. B. Meine Werkzeuge", @@ -786,7 +786,7 @@ "File": "Datei", "File added successfully.": "Datei erfolgreich hinzugefügt.", "File content updated successfully.": "Dateiinhalt erfolgreich aktualisiert.", - "File Context": "", + "File Context": "Datei-Kontext", "File Mode": "Datei-Modus", "File not found.": "Datei nicht gefunden.", "File removed successfully.": "Datei erfolgreich entfernt.", @@ -923,7 +923,7 @@ "Image Prompt Generation": "Bild-Prompt-Generierung", "Image Prompt Generation Prompt": "Prompt für Bild-Prompt-Generierung", "Image Size": "Bildgröße", - "Images": "", + "Images": "Bilder", "Import": "Importieren", "Import Chats": "Chats importieren", "Import Config from JSON File": "Konfiguration aus JSON importieren", @@ -942,7 +942,7 @@ "Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive.": "Beeinflusst, wie schnell der Algorithmus auf Feedback aus dem generierten Text reagiert. Eine niedrigere Lernrate führt zu langsameren Anpassungen, während eine höhere Lernrate den Algorithmus reaktionsschneller macht.", "Info": "Info", "Initials": "Initialen", - "Inject file content into conversation context": "", + "Inject file content into conversation context": "Injiziere den Datei-Kontext in den Konversations-Kontext", "Inject the entire content as context for comprehensive processing, this is recommended for complex queries.": "Gesamten Inhalt als Kontext für umfassende Verarbeitung einfügen; dies wird für komplexe Abfragen empfohlen.", "Input": "Eingabe", "Input Key (e.g. text, unet_name, steps)": "Eingabeschlüssel (z. B. text, unet_name, steps)", @@ -1160,7 +1160,7 @@ "New Webhook": "Neuer Webhook", "new-channel": "neuer-kanal", "Next message": "Nächste Nachricht", - "No activity data": "", + "No activity data": "Keine Aktivitätsdaten", "No authentication": "Keine Authentifizierung", "No chats found": "Keine Chats gefunden", "No chats found for this user.": "Keine Chats für diesen Benutzer gefunden.", @@ -1308,7 +1308,7 @@ "Pipe": "Pipe", "Pipeline deleted successfully": "Pipeline erfolgreich gelöscht", "Pipeline downloaded successfully": "Pipeline erfolgreich heruntergeladen", - "Pipelines": "", + "Pipelines": "Pipelines", "Pipelines are a plugin system with arbitrary code execution —": "Pipelines sind ein Plugin-System mit beliebiger Codeausführung —", "Pipelines Not Detected": "Keine Pipelines erkannt", "Pipelines Valves": "Pipeline-Valves", From 01d5f42755187ddb0b6508c4dfa768d441d31170 Mon Sep 17 00:00:00 2001 From: joaoback <156559121+joaoback@users.noreply.github.com> Date: Mon, 12 Jan 2026 07:04:09 -0300 Subject: [PATCH 0018/1854] Update translation.json (pt-BR) (#20599) translation of the new items recently added --- src/lib/i18n/locales/pt-BR/translation.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/i18n/locales/pt-BR/translation.json b/src/lib/i18n/locales/pt-BR/translation.json index b6d2966bbc..f35e12323d 100644 --- a/src/lib/i18n/locales/pt-BR/translation.json +++ b/src/lib/i18n/locales/pt-BR/translation.json @@ -303,7 +303,7 @@ "Code Block": "Bloco de código", "Code Editor": "Editor de código", "Code execution": "Execução de código", - "Code Execution": "", + "Code Execution": "Execução de Código", "Code Execution Engine": "Mecanismo de execução de código", "Code Execution Timeout": "Tempo limite de execução do código", "Code formatted successfully": "Código formatado com sucesso", @@ -498,7 +498,7 @@ "Document Intelligence endpoint required.": "É necessário o endpoint do Document Intelligence.", "Document Intelligence Model": "Modelo de Inteligência de Documentos", "Documentation": "Documentação", - "Documents": "", + "Documents": "Documentos", "does not make any external connections, and your data stays securely on your locally hosted server.": "não faz nenhuma conexão externa, e seus dados permanecem seguros no seu servidor local.", "Domain Filter List": "Lista de filtros de domínio", "don't fetch random pipelines from sources you don't trust.": "Não busque pipelines aleatórios de fontes não confiáveis.", @@ -923,7 +923,7 @@ "Image Prompt Generation": "Geração de prompt de imagem", "Image Prompt Generation Prompt": "Prompt de geração de prompt de imagem", "Image Size": "Tamanho da imagem", - "Images": "", + "Images": "Imagens", "Import": "Importar", "Import Chats": "Importar Chats", "Import Config from JSON File": "Importar Configurações de JSON", @@ -1308,7 +1308,7 @@ "Pipe": "", "Pipeline deleted successfully": "Pipeline excluído com sucesso", "Pipeline downloaded successfully": "Pipeline baixado com sucesso", - "Pipelines": "", + "Pipelines": "Pipelines", "Pipelines are a plugin system with arbitrary code execution —": "Pipelines é um sistema de plugins com execução arbitrária de código —", "Pipelines Not Detected": "Pipelines Não Detectados", "Pipelines Valves": "Configurações de Pipelines", From 9617df04ae15cdb3c19b6926dea539198f76450e Mon Sep 17 00:00:00 2001 From: Shirasawa <764798966@qq.com> Date: Tue, 13 Jan 2026 00:34:13 +0800 Subject: [PATCH 0019/1854] I18n: improve Chinese translation (#20613) * i18n: improve zh-CN translation * i18n: improve zh-TW translation --- src/lib/i18n/locales/zh-CN/translation.json | 38 ++++++++++----------- src/lib/i18n/locales/zh-TW/translation.json | 36 +++++++++---------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/lib/i18n/locales/zh-CN/translation.json b/src/lib/i18n/locales/zh-CN/translation.json index f185bc8b12..dacae40c77 100644 --- a/src/lib/i18n/locales/zh-CN/translation.json +++ b/src/lib/i18n/locales/zh-CN/translation.json @@ -47,7 +47,7 @@ "Activate this command by typing \"/{{COMMAND}}\" to chat input.": "在对话框中输入 \"/{{COMMAND}}\" 激活此命令", "Active": "在线", "Active Users": "当前在线用户", - "Activity": "", + "Activity": "活动", "Add": "添加", "Add a model ID": "添加模型 ID", "Add a short description about what this model does": "添加有关该模型能力的简短描述", @@ -221,7 +221,7 @@ "Button ID": "按钮 ID", "Button Label": "按钮文本", "Button Prompt": "点击按钮后执行的提示词", - "by {{name}}": "", + "by {{name}}": "由 {{name}} 提供", "By {{name}}": "由 {{name}} 提供", "Bypass Embedding and Retrieval": "绕过嵌入和检索", "Bypass Web Loader": "绕过网页加载器", @@ -303,7 +303,7 @@ "Code Block": "代码块", "Code Editor": "代码编辑器", "Code execution": "代码执行", - "Code Execution": "", + "Code Execution": "代码执行", "Code Execution Engine": "代码执行引擎", "Code Execution Timeout": "代码执行超时", "Code formatted successfully": "代码格式化成功", @@ -367,7 +367,7 @@ "Copy link": "复制链接", "Copy Link": "复制链接", "Copy to clipboard": "复制到剪贴板", - "Copy URL": "", + "Copy URL": "复制 URL", "Copying to clipboard was successful!": "成功复制到剪贴板!", "CORS must be properly configured by the provider to allow requests from Open WebUI.": "为允许 Open WebUI 发出的请求,提供商必须正确配置 CORS", "Create": "创建", @@ -391,7 +391,7 @@ "Created At": "创建于", "Created by": "作者", "Created by you": "由您创建", - "Created on {{date}}": "", + "Created on {{date}}": "创建于 {{date}}", "CSV Import": "通过 CSV 文件导入", "Ctrl+Enter to Send": "Ctrl+Enter 发送", "Current Model": "当前模型", @@ -447,7 +447,7 @@ "delete this link": "此处删除这个链接", "Delete tool?": "要删除此工具吗?", "Delete User": "删除用户", - "Deleted": "", + "Deleted": "删除成功", "Deleted {{deleteModelTag}}": "已删除 {{deleteModelTag}}", "Deleted {{name}}": "已删除 {{name}}", "Deleted User": "已删除用户", @@ -498,7 +498,7 @@ "Document Intelligence endpoint required.": "Document Intelligence 接口地址是必填项。", "Document Intelligence Model": "Document Intelligence 模型", "Documentation": "帮助文档", - "Documents": "", + "Documents": "文档", "does not make any external connections, and your data stays securely on your locally hosted server.": "不会与外部建立任何连接,您的数据会安全地存储在本地托管的服务器上。", "Domain Filter List": "域名过滤列表", "don't fetch random pipelines from sources you don't trust.": "请勿从未经验证或不可信的来源获取 Pipelines。", @@ -522,7 +522,7 @@ "e.g. 60": "例如:60", "e.g. A filter to remove profanity from text": "例如:一个用于剔除文本中不当内容的过滤器", "e.g. about the Roman Empire": "例如:关于罗马帝国的趣闻", - "e.g. alloy, echo, shimmer": "", + "e.g. alloy, echo, shimmer": "例如:alloy, echo, shimmer", "e.g. en": "例如:en", "e.g. My Filter": "例如:我的过滤器", "e.g. My Tools": "例如:我的工具", @@ -786,7 +786,7 @@ "File": "文件", "File added successfully.": "文件成功添加", "File content updated successfully.": "文件内容成功更新", - "File Context": "", + "File Context": "文件上下文", "File Mode": "文件模式", "File not found.": "文件未找到。", "File removed successfully.": "文件成功删除", @@ -923,7 +923,7 @@ "Image Prompt Generation": "图像提示词生成", "Image Prompt Generation Prompt": "用于生成图像提示词的提示词", "Image Size": "图片尺寸", - "Images": "", + "Images": "图片", "Import": "导入", "Import Chats": "导入对话记录", "Import Config from JSON File": "从 JSON 文件中导入配置信息", @@ -942,7 +942,7 @@ "Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive.": "影响算法对生成文本反馈的响应速度。较低的学习率会导致调整过程较慢,而较高的学习率将使算法反应更灵敏。", "Info": "信息", "Initials": "姓名缩写", - "Inject file content into conversation context": "", + "Inject file content into conversation context": "将文件内容注入为对话上下文", "Inject the entire content as context for comprehensive processing, this is recommended for complex queries.": "注入整个内容作为上下文进行综合处理,适用于复杂查询", "Input": "输入", "Input Key (e.g. text, unet_name, steps)": "输入键名(例如:text, unet_name, steps)", @@ -1156,11 +1156,11 @@ "New Password": "新密码", "New Prompt": "创建提示词", "New Temporary Chat": "创建临时对话", - "New Tool": "新工具", - "New Webhook": "", + "New Tool": "新建工具", + "New Webhook": "新建 Webhook", "new-channel": "新频道", "Next message": "下一条消息", - "No activity data": "", + "No activity data": "没有活动数据", "No authentication": "无身份验证", "No chats found": "未找到对话记录", "No chats found for this user.": "未找到此用户的对话记录", @@ -1199,7 +1199,7 @@ "No users were found.": "未找到用户", "No valves": "没有配置项", "No valves to update": "没有需要更新的配置项", - "No webhooks yet": "", + "No webhooks yet": "没有 Webhook", "Node Ids": "节点 ID", "None": "无", "Not factually correct": "与事实不符", @@ -1308,7 +1308,7 @@ "Pipe": "Pipe", "Pipeline deleted successfully": "Pipeline 删除成功", "Pipeline downloaded successfully": "Pipeline 下载成功", - "Pipelines": "", + "Pipelines": "Pipelines", "Pipelines are a plugin system with arbitrary code execution —": "Pipelines 是具有任意代码执行风险的插件系统 —", "Pipelines Not Detected": "未检测到 Pipeline", "Pipelines Valves": "Pipeline 配置项", @@ -1805,7 +1805,7 @@ "User location successfully retrieved.": "成功检索到用户位置", "User menu": "用户菜单", "User ratings (thumbs up/down)": "用户评分(赞/踩)", - "User Status": "", + "User Status": "用户状态", "User Webhooks": "用户 Webhook", "Username": "用户名", "users": "用户", @@ -1846,9 +1846,9 @@ "Web Search Engine": "联网搜索引擎", "Web Search in Chat": "在对话时进行联网搜索", "Web Search Query Generation": "联网搜索关键词生成", - "Webhook Name": "", + "Webhook Name": "Webhook 名称", "Webhook URL": "Webhook URL", - "Webhooks": "", + "Webhooks": "Webhook", "Webpage URLs": "网页链接", "WebUI Settings": "WebUI 设置", "WebUI URL": "WebUI URL", diff --git a/src/lib/i18n/locales/zh-TW/translation.json b/src/lib/i18n/locales/zh-TW/translation.json index 41ce6f5813..eea7b2162b 100644 --- a/src/lib/i18n/locales/zh-TW/translation.json +++ b/src/lib/i18n/locales/zh-TW/translation.json @@ -47,7 +47,7 @@ "Activate this command by typing \"/{{COMMAND}}\" to chat input.": "在對話輸入框中輸入 \"/{{COMMAND}}\" 來啟用此命令。", "Active": "線上", "Active Users": "活躍使用者", - "Activity": "", + "Activity": "活動", "Add": "新增", "Add a model ID": "新增模型 ID", "Add a short description about what this model does": "新增這個模型的簡短描述", @@ -221,7 +221,7 @@ "Button ID": "按鈕 ID", "Button Label": "按鈕文字", "Button Prompt": "點擊按鈕後執行的提示詞", - "by {{name}}": "", + "by {{name}}": "由 {{name}} 提供", "By {{name}}": "由 {{name}} 製作", "Bypass Embedding and Retrieval": "繞過嵌入與檢索", "Bypass Web Loader": "繞過網頁載入器", @@ -303,7 +303,7 @@ "Code Block": "程式碼區塊", "Code Editor": "程式碼編輯器", "Code execution": "程式碼執行", - "Code Execution": "", + "Code Execution": "程式碼執行", "Code Execution Engine": "程式碼執行引擎", "Code Execution Timeout": "程式執行超時", "Code formatted successfully": "成功格式化程式碼", @@ -367,7 +367,7 @@ "Copy link": "複製連結", "Copy Link": "複製連結", "Copy to clipboard": "複製到剪貼簿", - "Copy URL": "", + "Copy URL": "複製 URL", "Copying to clipboard was successful!": "成功複製到剪貼簿!", "CORS must be properly configured by the provider to allow requests from Open WebUI.": "CORS 必須由供應商正確設定,以允許來自 Open WebUI 的請求。", "Create": "建立", @@ -391,7 +391,7 @@ "Created At": "建立於", "Created by": "建立者", "Created by you": "由您建立", - "Created on {{date}}": "", + "Created on {{date}}": "建立於 {{date}}", "CSV Import": "CSV 匯入", "Ctrl+Enter to Send": "使用 Ctrl+Enter 傳送", "Current Model": "目前模型", @@ -447,7 +447,7 @@ "delete this link": "刪除此連結", "Delete tool?": "刪除工具?", "Delete User": "刪除使用者", - "Deleted": "", + "Deleted": "刪除成功", "Deleted {{deleteModelTag}}": "已刪除 {{deleteModelTag}}", "Deleted {{name}}": "已刪除 {{name}}", "Deleted User": "刪除使用者?", @@ -498,7 +498,7 @@ "Document Intelligence endpoint required.": "需要提供 Document Intelligence 端點。", "Document Intelligence Model": "Document Intelligence 模型", "Documentation": "說明檔案", - "Documents": "", + "Documents": "文件", "does not make any external connections, and your data stays securely on your locally hosted server.": "不會建立任何外部連線,而且您的資料會安全地儲存在您本機伺服器上。", "Domain Filter List": "網域篩選列表", "don't fetch random pipelines from sources you don't trust.": "請勿從您無法信任的來源擷取任意管線。", @@ -522,7 +522,7 @@ "e.g. 60": "例如:60", "e.g. A filter to remove profanity from text": "例如:用來移除不雅詞彙的過濾器", "e.g. about the Roman Empire": "例如:關於羅馬帝國的事蹟", - "e.g. alloy, echo, shimmer": "", + "e.g. alloy, echo, shimmer": "例如:alloy, echo, shimmer", "e.g. en": "例如:en", "e.g. My Filter": "例如:我的篩選器", "e.g. My Tools": "例如:我的工具", @@ -786,7 +786,7 @@ "File": "檔案", "File added successfully.": "成功新增檔案。", "File content updated successfully.": "成功更新檔案內容。", - "File Context": "", + "File Context": "檔案上下文", "File Mode": "檔案模式", "File not found.": "未找到檔案。", "File removed successfully.": "成功移除檔案。", @@ -923,7 +923,7 @@ "Image Prompt Generation": "圖片提示詞生成", "Image Prompt Generation Prompt": "生成圖片提示詞的提示詞", "Image Size": "圖片尺寸", - "Images": "", + "Images": "圖片", "Import": "匯入", "Import Chats": "匯入對話紀錄", "Import Config from JSON File": "從 JSON 檔案匯入設定", @@ -942,7 +942,7 @@ "Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive.": "影響演算法對生成文字回饋的反應速度。較低的學習率會導致調整速度較慢,而較高的學習率會使演算法反應更靈敏。", "Info": "資訊", "Initials": "姓名縮寫", - "Inject file content into conversation context": "", + "Inject file content into conversation context": "將文件內容注入為對話上下文", "Inject the entire content as context for comprehensive processing, this is recommended for complex queries.": "將完整內容注入為上下文以進行全面處理,建議用於複雜查詢。", "Input": "輸入", "Input Key (e.g. text, unet_name, steps)": "輸入鍵名(例如:text, unet_name, steps)", @@ -1157,10 +1157,10 @@ "New Prompt": "新增提示詞", "New Temporary Chat": "新增臨時對話", "New Tool": "新增工具", - "New Webhook": "", + "New Webhook": "新增 Webhook", "new-channel": "新頻道", "Next message": "下一條訊息", - "No activity data": "", + "No activity data": "沒有活動數據", "No authentication": "無身份驗證", "No chats found": "未找到對話記錄", "No chats found for this user.": "未找到此使用者的對話記錄。", @@ -1199,7 +1199,7 @@ "No users were found.": "未找到任何使用者", "No valves": "沒有設定項目", "No valves to update": "設定項目可更新", - "No webhooks yet": "", + "No webhooks yet": "尚無 Webhook", "Node Ids": "節點 ID", "None": "無", "Not factually correct": "與事實不符", @@ -1308,7 +1308,7 @@ "Pipe": "Pipe", "Pipeline deleted successfully": "成功刪除管線", "Pipeline downloaded successfully": "成功下載管線", - "Pipelines": "", + "Pipelines": "管線", "Pipelines are a plugin system with arbitrary code execution —": "管線是具任意程式碼執行風險的外掛系統 —", "Pipelines Not Detected": "未偵測到管線", "Pipelines Valves": "管線設定項目", @@ -1805,7 +1805,7 @@ "User location successfully retrieved.": "成功取得使用者位置。", "User menu": "使用者選單", "User ratings (thumbs up/down)": "使用者評分(讚/踩)", - "User Status": "", + "User Status": "使用者狀態", "User Webhooks": "使用者 Webhooks", "Username": "使用者名稱", "users": "使用者", @@ -1846,9 +1846,9 @@ "Web Search Engine": "網頁搜尋引擎", "Web Search in Chat": "在對話中進行網頁搜尋", "Web Search Query Generation": "網頁搜尋查詢生成", - "Webhook Name": "", + "Webhook Name": "Webhook 名稱", "Webhook URL": "Webhook URL", - "Webhooks": "", + "Webhooks": "Webhook", "Webpage URLs": "網頁連結", "WebUI Settings": "WebUI 設定", "WebUI URL": "WebUI URL", From 6f80cb6b65f9774d29b4613895bff5eecf61397b Mon Sep 17 00:00:00 2001 From: Toru Suzuki <35589743+zolgear@users.noreply.github.com> Date: Tue, 13 Jan 2026 01:34:32 +0900 Subject: [PATCH 0020/1854] i18n: Update Japanese translation (#20605) Co-authored-by: Tim Baek Co-authored-by: joaoback <156559121+joaoback@users.noreply.github.com> --- src/lib/i18n/locales/ja-JP/translation.json | 50 ++++++++++----------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/lib/i18n/locales/ja-JP/translation.json b/src/lib/i18n/locales/ja-JP/translation.json index 11ea56f1b1..641c92f282 100644 --- a/src/lib/i18n/locales/ja-JP/translation.json +++ b/src/lib/i18n/locales/ja-JP/translation.json @@ -165,9 +165,9 @@ "Assistant": "アシスタント", "Async Embedding Processing": "", "Attach File From Knowledge": "", - "Attach Knowledge": "", - "Attach Notes": "", - "Attach Webpage": "", + "Attach Knowledge": "ナレッジを追加", + "Attach Notes": "ノートを追加", + "Attach Webpage": "ウェブページを追加", "Attention to detail": "細部への注意", "Attribute for Mail": "メールの属性", "Attribute for Username": "ユーザー名の属性", @@ -373,7 +373,7 @@ "Create": "作成", "Create a knowledge base": "ナレッジベースを作成する", "Create a model": "モデルを作成する", - "Create a new note": "", + "Create a new note": "新しいノートを作成する", "Create Account": "アカウントを作成", "Create Admin Account": "管理者アカウントを作成", "Create Channel": "チャンネルを作成", @@ -390,7 +390,7 @@ "Created at": "作成日時", "Created At": "作成日時", "Created by": "作成者", - "Created by you": "", + "Created by you": "自分が作成", "Created on {{date}}": "", "CSV Import": "CSVインポート", "Ctrl+Enter to Send": "Ctrl+Enterで送信", @@ -805,15 +805,15 @@ "Firecrawl Timeout (s)": "", "Floating Quick Actions": "フローティング クイックアクション", "Focus Chat Input": "", - "Folder": "", - "Folder Background Image": "", + "Folder": "フォルダー", + "Folder Background Image": "フォルダーの背景画像", "Folder deleted successfully": "フォルダー削除が成功しました。", "Folder Max File Count": "", "Folder Name": "フォルダ名", "Folder name cannot be empty.": "フォルダー名を入力してください。", "Folder name updated successfully": "フォルダー名の変更に成功しました。", "Folder updated successfully": "フォルダの更新に成功しました。", - "Folders": "", + "Folders": "フォルダー", "Follow up": "関連質問", "Follow Up Generation": "関連質問の生成", "Follow Up Generation Prompt": "関連質問の生成プロンプト", @@ -868,7 +868,7 @@ "Google PSE API Key": "Google PSE APIキー", "Google PSE Engine Id": "Google PSE エンジン ID", "Gravatar": "", - "Grid": "", + "Grid": "グリッド", "Grokipedia": "", "Group": "グループ", "Group Channel": "", @@ -1032,7 +1032,7 @@ "Lift List": "リストを字下げ", "Light": "ライト", "Limit concurrent search queries. 0 = unlimited (default). Set to 1 for sequential execution (recommended for APIs with strict rate limits like Brave free tier).": "", - "List": "", + "List": "リスト", "Listening...": "聞いています...", "Llama.cpp": "", "LLMs can make mistakes. Verify important information.": "LLM は間違いを犯す可能性があります。重要な情報を検証してください。", @@ -1150,11 +1150,11 @@ "New Chat": "新しいチャット", "New Folder": "新しいフォルダ", "New Function": "新しいFunction", - "New Knowledge": "", - "New Model": "", - "New Note": "", + "New Knowledge": "新しいナレッジベース", + "New Model": "新しいモデル", + "New Note": "新しいノート", "New Password": "新しいパスワード", - "New Prompt": "", + "New Prompt": "新しいプロンプト", "New Temporary Chat": "", "New Tool": "新しいツール", "New Webhook": "", @@ -1174,18 +1174,18 @@ "No feedback found": "", "No file selected": "ファイルが選択されていません", "No files in this knowledge base.": "", - "No functions found": "", + "No functions found": "functionsが見つかりません", "No groups with access, add a group to grant access": "アクセス権限があるグループがありません。グループを追加してアクセス権限を付与してください。", "No HTML, CSS, or JavaScript content found.": "HTML、CSS、またはJavaScriptの内容が見つかりません。", "No inference engine with management support found": "管理サポートのある推論エンジンが見つかりません。", - "No knowledge bases found.": "", + "No knowledge bases found.": "ナレッジベースが見つかりません", "No knowledge found": "ナレッジベースが見つかりません", "No memories to clear": "クリアするメモリがありません", "No model IDs": "モデルIDがありません", "No models found": "モデルが見つかりません", "No models selected": "モデルが選択されていません", "No Notes": "ノートがありません", - "No notes found": "", + "No notes found": "ノートが見つかりません", "No one": "", "No pinned messages": "", "No prompts found": "", @@ -1371,7 +1371,7 @@ "Read": "読み込む", "Read Aloud": "読み上げ", "Read more →": "", - "Read Only": "", + "Read Only": "読み取り専用", "Read-Only Access": "", "Reason": "理由", "Reasoning Effort": "推理の努力", @@ -1535,7 +1535,7 @@ "Set the number of worker threads used for computation. This option controls how many threads are used to process incoming requests concurrently. Increasing this value can improve performance under high concurrency workloads but may also consume more CPU resources.": "計算に使用するワーカースレッドの数を設定します。このオプションは、同時に処理可能なリクエスト数(スレッド数)を制御します。値を増やすことで、高い同時実行負荷下でのパフォーマンスが向上する可能性がありますが、その分CPUリソースの消費も増加します。", "Set Voice": "音声を設定", "Set whisper model": "whisperモデルを設定", - "Set your status": "", + "Set your status": "ステータスを設定", "Sets a flat bias against tokens that have appeared at least once. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 0.9) will be more lenient. At 0, it is disabled.": "一度でも出現したトークンに対して一定のペナルティを設定します。値が高い(例:1.5)ほど繰り返しを強く抑制し、低い値(例:0.9)では寛容になります。0の場合は無効です。", "Sets a scaling bias against tokens to penalize repetitions, based on how many times they have appeared. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 0.9) will be more lenient. At 0, it is disabled.": "出現回数に応じてトークンにスケーリングされたペナルティを設定します。値が高い(例:1.5)ほど繰り返しを強く抑制し、低い値(例:0.9)では寛容になります。0の場合は無効です。", "Sets how far back for the model to look back to prevent repetition.": "モデルが繰り返しを防止するために遡る履歴の長さを設定します。", @@ -1550,7 +1550,7 @@ "Share Chat": "チャットを共有", "Share to Open WebUI Community": "OpenWebUI コミュニティに共有", "Share your background and interests": "あなたの背景情報と興味を教えてください", - "Shared with you": "", + "Shared with you": "自分に共有", "Sharing Permissions": "共有に関する権限", "Show": "表示", "Show \"What's New\" modal on login": "ログイン時に更新内容モーダルを表示", @@ -1589,10 +1589,10 @@ "Speech-to-Text": "音声テキスト変換", "Speech-to-Text Engine": "音声テキスト変換エンジン", "Split documents by markdown headers before applying character/token splitting.": "", - "Start a new conversation": "", + "Start a new conversation": "新しい会話を開始", "Start of the channel": "チャンネルの開始", "Start Tag": "", - "Status": "", + "Status": "ステータス", "Status cleared successfully": "", "Status updated successfully": "", "Status Updates": "", @@ -1743,7 +1743,7 @@ "Transformers": "", "Trouble accessing Ollama?": "Ollama へのアクセスに問題がありますか?", "Trust Proxy Environment": "プロキシ環境を信頼する", - "Try adjusting your search or filter to find what you are looking for.": "", + "Try adjusting your search or filter to find what you are looking for.": "検索条件やフィルターを調整して、もう一度お試しください。", "Try Again": "再試行", "TTS Model": "TTSモデル", "TTS Settings": "TTS 設定", @@ -1849,7 +1849,7 @@ "Webhook Name": "", "Webhook URL": "Webhook URL", "Webhooks": "", - "Webpage URLs": "", + "Webpage URLs": "ウェブページのURL", "WebUI Settings": "WebUI 設定", "WebUI URL": "", "WebUI will make requests to \"{{url}}\"": "WebUIは\"{{url}}\"にリクエストを行います", @@ -1860,7 +1860,7 @@ "What is NOT shared:": "", "What is shared:": "", "What's New in": "新機能", - "What's on your mind?": "", + "What's on your mind?": "今の状況を入力してください", "When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "有効にすると、ユーザのメッセージ送信と同時にリアルタイムで応答を生成します。ライブチャット用途に適しますが、性能の低い環境では動作が重くなる可能性があります。", "wherever you are": "どこにいても", "Whether to paginate the output. Each page will be separated by a horizontal rule and page number. Defaults to False.": "出力をページ分けするかどうか。各ページは水平線とページ番号で分割されます。デフォルトでは無効", From 7da37b4f66b9b2e821796b06b75e03cb0237e0a9 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Mon, 12 Jan 2026 21:41:23 +0400 Subject: [PATCH 0021/1854] refac --- backend/open_webui/routers/channels.py | 8 ++------ backend/open_webui/routers/models.py | 6 ++---- backend/open_webui/routers/users.py | 6 ++---- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/backend/open_webui/routers/channels.py b/backend/open_webui/routers/channels.py index 4e697142bf..7f4b347bef 100644 --- a/backend/open_webui/routers/channels.py +++ b/backend/open_webui/routers/channels.py @@ -1874,13 +1874,9 @@ async def delete_message_by_id( @router.get("/webhooks/{webhook_id}/profile/image") -async def get_webhook_profile_image( - webhook_id: str, - user=Depends(get_verified_user), - db: Session = Depends(get_session), -): +def get_webhook_profile_image(webhook_id: str, user=Depends(get_verified_user)): """Get webhook profile image by webhook ID.""" - webhook = Channels.get_webhook_by_id(webhook_id, db=db) + webhook = Channels.get_webhook_by_id(webhook_id) if not webhook: # Return default favicon if webhook not found return FileResponse(f"{STATIC_DIR}/favicon.png") diff --git a/backend/open_webui/routers/models.py b/backend/open_webui/routers/models.py index a1f642bbce..85f0fb4f64 100644 --- a/backend/open_webui/routers/models.py +++ b/backend/open_webui/routers/models.py @@ -343,10 +343,8 @@ async def get_model_by_id( @router.get("/model/profile/image") -def get_model_profile_image( - id: str, user=Depends(get_verified_user), db: Session = Depends(get_session) -): - model = Models.get_model_by_id(id, db=db) +def get_model_profile_image(id: str, user=Depends(get_verified_user)): + model = Models.get_model_by_id(id) if model: etag = f'"{model.updated_at}"' if model.updated_at else None diff --git a/backend/open_webui/routers/users.py b/backend/open_webui/routers/users.py index 8eb4b5d199..20b69bcdf7 100644 --- a/backend/open_webui/routers/users.py +++ b/backend/open_webui/routers/users.py @@ -498,10 +498,8 @@ async def get_user_oauth_sessions_by_id( @router.get("/{user_id}/profile/image") -async def get_user_profile_image_by_id( - user_id: str, user=Depends(get_verified_user), db: Session = Depends(get_session) -): - user = Users.get_user_by_id(user_id, db=db) +def get_user_profile_image_by_id(user_id: str, user=Depends(get_verified_user)): + user = Users.get_user_by_id(user_id) if user: if user.profile_image_url: # check if it's url or base64 From 5a075a2c836e46b83f8710285f09aff1f6125072 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Mon, 12 Jan 2026 21:53:41 +0400 Subject: [PATCH 0022/1854] fix: members only groups --- backend/open_webui/models/groups.py | 14 +++++++------- .../workspace/common/AccessControl.svelte | 5 ++++- .../workspace/common/MemberSelector.svelte | 6 +++++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/backend/open_webui/models/groups.py b/backend/open_webui/models/groups.py index ae557f4daf..f1ece68aaf 100644 --- a/backend/open_webui/models/groups.py +++ b/backend/open_webui/models/groups.py @@ -165,15 +165,15 @@ class GroupTable: share_value = filter["share"] member_id = filter.get("member_id") json_share = Group.data["config"]["share"] - json_share_bool = json_share.as_boolean() - json_share_str = json_share.as_string() + json_share_lower = func.lower(json_share.as_string()) if share_value: - # Groups open to anyone: data is null, share is null, or share is true + # Groups open to anyone: data is null, config.share is null, or share is true + # Use case-insensitive string comparison to handle variations like "True", "TRUE" anyone_can_share = or_( Group.data.is_(None), - json_share_bool.is_(None), - json_share_bool == True, + json_share_lower.is_(None), + json_share_lower == "true", ) if member_id: @@ -184,7 +184,7 @@ class GroupTable: .subquery() ) members_only_and_is_member = and_( - json_share_str == "members", + json_share_lower == "members", Group.id.in_(member_groups_subq), ) query = query.filter( @@ -194,7 +194,7 @@ class GroupTable: query = query.filter(anyone_can_share) else: query = query.filter( - and_(Group.data.isnot(None), json_share_bool == False) + and_(Group.data.isnot(None), json_share_lower == "false") ) else: diff --git a/src/lib/components/workspace/common/AccessControl.svelte b/src/lib/components/workspace/common/AccessControl.svelte index 4355a6587f..1bf4bbc1f8 100644 --- a/src/lib/components/workspace/common/AccessControl.svelte +++ b/src/lib/components/workspace/common/AccessControl.svelte @@ -42,7 +42,10 @@ }; onMount(async () => { - groups = await getGroups(localStorage.token, true); + groups = await getGroups(localStorage.token, true).catch((error) => { + console.error(error); + return []; + }); if (accessControl === null) { initPublicAccess(); diff --git a/src/lib/components/workspace/common/MemberSelector.svelte b/src/lib/components/workspace/common/MemberSelector.svelte index 6627ae4459..a9bbb7149f 100644 --- a/src/lib/components/workspace/common/MemberSelector.svelte +++ b/src/lib/components/workspace/common/MemberSelector.svelte @@ -65,7 +65,11 @@ } onMount(async () => { - groups = await getGroups(localStorage.token, true); + groups = await getGroups(localStorage.token, true).catch((error) => { + console.error(error); + return []; + }); + if (userIds.length > 0) { userIds.forEach(async (id) => { const res = await getUserById(localStorage.token, id).catch((error) => { From de0cbb9073298f579e0d4b9e5340b266f474acec Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Mon, 12 Jan 2026 21:56:02 +0400 Subject: [PATCH 0023/1854] refac --- backend/open_webui/models/groups.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/models/groups.py b/backend/open_webui/models/groups.py index f1ece68aaf..31b34c45c8 100644 --- a/backend/open_webui/models/groups.py +++ b/backend/open_webui/models/groups.py @@ -165,14 +165,15 @@ class GroupTable: share_value = filter["share"] member_id = filter.get("member_id") json_share = Group.data["config"]["share"] - json_share_lower = func.lower(json_share.as_string()) + json_share_str = json_share.as_string() + json_share_lower = func.lower(json_share_str) if share_value: # Groups open to anyone: data is null, config.share is null, or share is true # Use case-insensitive string comparison to handle variations like "True", "TRUE" anyone_can_share = or_( Group.data.is_(None), - json_share_lower.is_(None), + json_share_str.is_(None), json_share_lower == "true", ) From 1555252c4a60cbf0be96d4725ea25b42e101cdf9 Mon Sep 17 00:00:00 2001 From: G30 <50341825+silentoplayz@users.noreply.github.com> Date: Thu, 15 Jan 2026 01:43:25 -0500 Subject: [PATCH 0024/1854] fix: handle undefined model in createMessagePair function (#20663) - Add a null check when looking up model to prevent JavaScript error when trying to add a message pair in a chat with an invalid/corrupt model ID. --- src/lib/components/chat/Chat.svelte | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index ff41dfe472..d7341257f2 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -1282,6 +1282,11 @@ const modelId = selectedModels[0]; const model = $models.filter((m) => m.id === modelId).at(0); + if (!model) { + toast.error($i18n.t('Model not found')); + return; + } + const messages = createMessagesList(history, history.currentId); const parentMessage = messages.length !== 0 ? messages.at(-1) : null; From e26f6acc3b67831dd3d80d4eae59b96adca858b4 Mon Sep 17 00:00:00 2001 From: Kailey Wong <61530252+kaileywong@users.noreply.github.com> Date: Wed, 14 Jan 2026 22:44:35 -0800 Subject: [PATCH 0025/1854] fix: use proper X-Api-Key header format when docling api key provided (#20652) --- backend/open_webui/retrieval/loaders/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/open_webui/retrieval/loaders/main.py b/backend/open_webui/retrieval/loaders/main.py index 2b83e44283..bf7c7286b5 100644 --- a/backend/open_webui/retrieval/loaders/main.py +++ b/backend/open_webui/retrieval/loaders/main.py @@ -143,7 +143,7 @@ class DoclingLoader: with open(self.file_path, "rb") as f: headers = {} if self.api_key: - headers["X-Api-Key"] = f"Bearer {self.api_key}" + headers["X-Api-Key"] = f"{self.api_key}" r = requests.post( f"{self.url}/v1/convert/file", From 1d343aeae41dff8f4ebd1e08720db80780f62159 Mon Sep 17 00:00:00 2001 From: EntropyYue <164553692+EntropyYue@users.noreply.github.com> Date: Thu, 15 Jan 2026 14:46:00 +0800 Subject: [PATCH 0026/1854] enh: Make builtin search web tools asynchronous (#20630) Co-authored-by: Tim Baek Co-authored-by: joaoback <156559121+joaoback@users.noreply.github.com> --- backend/open_webui/tools/builtin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/open_webui/tools/builtin.py b/backend/open_webui/tools/builtin.py index d26e032727..144d18d284 100644 --- a/backend/open_webui/tools/builtin.py +++ b/backend/open_webui/tools/builtin.py @@ -166,7 +166,7 @@ async def search_web( engine = __request__.app.state.config.WEB_SEARCH_ENGINE user = UserModel(**__user__) if __user__ else None - results = _search_web(__request__, engine, query, user) + results = await asyncio.to_thread(_search_web, __request__, engine, query, user) # Limit results results = results[:count] if results else [] From 1c1f72f05c526dbf7be2740f0e16c79289589f3e Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Thu, 15 Jan 2026 21:15:02 +0100 Subject: [PATCH 0027/1854] Update builtin.py (#20705) --- backend/open_webui/tools/builtin.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/backend/open_webui/tools/builtin.py b/backend/open_webui/tools/builtin.py index 144d18d284..fcd1d4d233 100644 --- a/backend/open_webui/tools/builtin.py +++ b/backend/open_webui/tools/builtin.py @@ -1599,6 +1599,25 @@ async def query_knowledge_files( if not __user__: return json.dumps({"error": "User context not available"}) + # Coerce parameters from LLM tool calls (may come as strings) + if isinstance(count, str): + try: + count = int(count) + except ValueError: + count = 5 # Default fallback + + # Handle knowledge_ids being string "None", "null", or empty + if isinstance(knowledge_ids, str): + if knowledge_ids.lower() in ("none", "null", ""): + knowledge_ids = None + else: + # Try to parse as JSON array if it looks like one + try: + knowledge_ids = json.loads(knowledge_ids) + except json.JSONDecodeError: + # Treat as single ID + knowledge_ids = [knowledge_ids] + try: from open_webui.models.knowledge import Knowledges from open_webui.models.files import Files From 711a2cd7385ea755b789083dfbecdf7916cf740d Mon Sep 17 00:00:00 2001 From: Kylapaallikko Date: Sat, 17 Jan 2026 19:37:14 +0200 Subject: [PATCH 0028/1854] Update translation.json (#20741) Added missing translations and minor changes to wording of the translations. --- src/lib/i18n/locales/fi-FI/translation.json | 208 ++++++++++---------- 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/src/lib/i18n/locales/fi-FI/translation.json b/src/lib/i18n/locales/fi-FI/translation.json index 2e092f59a3..ff34a7b91d 100644 --- a/src/lib/i18n/locales/fi-FI/translation.json +++ b/src/lib/i18n/locales/fi-FI/translation.json @@ -12,10 +12,10 @@ "{{COUNT}} Available Tools": "{{COUNT}} työkalua saatavilla", "{{COUNT}} characters": "{{COUNT}} kirjainta", "{{COUNT}} extracted lines": "{{COUNT}} poimittua riviä", - "{{COUNT}} files": "", + "{{COUNT}} files": "{{COUNT}} tiedostoa", "{{COUNT}} hidden lines": "{{COUNT}} piilotettua riviä", "{{COUNT}} Replies": "{{COUNT}} vastausta", - "{{COUNT}} Rows": "", + "{{COUNT}} Rows": "{{COUNT}} riviä", "{{COUNT}} Sources": "{{COUNT}} lähdettä", "{{COUNT}} words": "{{COUNT}} sanaa", "{{LOCALIZED_DATE}} at {{LOCALIZED_TIME}}": "{{LOCALIZED_DATE}} {{LOCALIZED_TIME}}", @@ -47,7 +47,7 @@ "Activate this command by typing \"/{{COMMAND}}\" to chat input.": "Aktivoi tämä komento kirjoittamalla \"/{{COMMAND}}\" chat-syötteeseen.", "Active": "Aktiivinen", "Active Users": "Aktiiviset käyttäjät", - "Activity": "", + "Activity": "Toiminta", "Add": "Lisää", "Add a model ID": "Lisää mallitunnus", "Add a short description about what this model does": "Lisää lyhyt kuvaus siitä, mitä tämä malli tekee", @@ -70,15 +70,15 @@ "Add text content": "Lisää tekstisisältöä", "Add User": "Lisää käyttäjä", "Add User Group": "Lisää käyttäjäryhmä", - "Add webpage": "", + "Add webpage": "Lisää verkkosivu", "Additional Config": "Lisäasetukset", "Additional configuration options for marker. This should be a JSON string with key-value pairs. For example, '{\"key\": \"value\"}'. Supported keys include: disable_links, keep_pageheader_in_output, keep_pagefooter_in_output, filter_blank_pages, drop_repeated_text, layout_coverage_threshold, merge_threshold, height_tolerance, gap_threshold, image_threshold, min_line_length, level_count, default_level": "", "Additional Parameters": "Lisäparametrit", "Adds filenames, titles, sections, and snippets into the BM25 text to improve lexical recall.": "", - "Adjusting these settings will apply changes universally to all users.": "Näiden asetusten säätäminen vaikuttaa kaikkiin käyttäjiin.", + "Adjusting these settings will apply changes universally to all users.": "Näiden asetusten muokkaaminen vaikuttaa kaikkiin käyttäjiin.", "admin": "hallinta", "Admin": "Ylläpito", - "Admin Contact Email": "", + "Admin Contact Email": "Ylläpidon sähköposti", "Admin Panel": "Ylläpitopaneeli", "Admin Settings": "Ylläpitoasetukset", "Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "Ylläpitäjillä on pääsy kaikkiin työkaluihin koko ajan; käyttäjät tarvitsevat työkaluja mallille määritettynä työtilassa.", @@ -131,7 +131,7 @@ "and {{COUNT}} more": "ja {{COUNT}} muuta", "and create a new shared link.": "ja luo uusi jaettu linkki.", "Android": "Android", - "Anyone": "", + "Anyone": "Kukatahansa", "API Base URL": "API:n verkko-osoite", "API Base URL for Datalab Marker service. Defaults to: https://www.datalab.to/api/v1/marker": "API verkko-osoite Datalabb Marker palveluun. Oletuksena: https://www.datalab.to/api/v1/marker", "API Key": "API-avain", @@ -140,7 +140,7 @@ "API keys": "API-avaimet", "API Keys": "API-avaimet", "API Mode": "API-moodi", - "API Timeout": "", + "API Timeout": "API aikakatkaisu", "API Version": "API-versio", "API Version is required": "API-versio vaaditaan", "Application DN": "Sovelluksen DN", @@ -159,7 +159,7 @@ "Are you sure?": "Oletko varma?", "Arena Models": "Arena-mallit", "Artifacts": "Artefaktit", - "Asc": "", + "Asc": "Nouseva", "Ask": "Kysy", "Ask a question": "Kysy kysymys", "Assistant": "Avustaja", @@ -177,7 +177,7 @@ "Authenticate": "Todentaa", "Authentication": "Todennus", "Auto": "Automaattinen", - "Auto (Random)": "", + "Auto (Random)": "Automaattinen (satunnainen)", "Auto-Copy Response to Clipboard": "Kopioi vastaus automaattisesti leikepöydälle", "Auto-playback response": "Toista vastaus automaattisesti", "Autocomplete Generation": "Automaattisen täydennyksen luonti", @@ -216,12 +216,12 @@ "Boosting or penalizing specific tokens for constrained responses. Bias values will be clamped between -100 and 100 (inclusive). (Default: none)": "Tiettyjen tokeneiden tehostaminen tai rankaiseminen rajoitetuista vastauksista. Poikkeaman arvot rajoitetaan välille -100 ja 100 (mukaan lukien). (Oletus: ei mitään)", "Brave": "", "Brave Search API Key": "Brave Search API -avain", - "Builtin Tools": "", + "Builtin Tools": "Sisäänrakennetut työkalut", "Bullet List": "Luettelo", "Button ID": "Painikkeen ID", "Button Label": "Painikkeen nimi", "Button Prompt": "Painikkeen kehoite", - "by {{name}}": "", + "by {{name}}": "tekijä {{name}}", "By {{name}}": "Tekijä {{name}}", "Bypass Embedding and Retrieval": "Ohita upotus ja haku", "Bypass Web Loader": "Ohita verkkolataaja", @@ -231,8 +231,8 @@ "Call feature is not supported when using Web STT engine": "Puhelutoimintoa ei tueta käytettäessä web-puheentunnistusmoottoria", "Camera": "Kamera", "Cancel": "Peruuta", - "Cannot create an empty note.": "", - "Capabilities": "Ominaisuuksia", + "Cannot create an empty note.": "Tyhjää muistiinpanoa ei voi luoda.", + "Capabilities": "Ominaisuudet", "Capture": "Näyttökuva", "Capture Audio": "Kaappaa ääntä", "Certificate Path": "Varmennepolku", @@ -241,7 +241,7 @@ "Channel deleted successfully": "Kanavan poisto onnistui", "Channel Name": "Kanavan nimi", "Channel name cannot be empty.": "Kanavan nimi ei voi olla tyhjä", - "Channel name must be less than 128 characters": "", + "Channel name must be less than 128 characters": "Kanavan nimi oltava alle 128 merkkiä pitkä", "Channel Type": "Kanavatyyppi", "Channel updated successfully": "Kanavan päivitys onnistui", "Channels": "Kanavat", @@ -264,10 +264,10 @@ "Check for updates": "Tarkista päivitykset", "Checking for updates...": "Tarkistetaan päivityksiä...", "Choose a model before saving...": "Valitse malli ennen tallentamista...", - "Chunk Min Size Target": "", + "Chunk Min Size Target": "Osien vähimmäiskoko", "Chunk Overlap": "Päällekkäisten osien määrä", "Chunk Size": "Osien koko", - "Chunks smaller than this threshold will be merged with neighboring chunks when possible. Set to 0 to disable merging.": "", + "Chunks smaller than this threshold will be merged with neighboring chunks when possible. Set to 0 to disable merging.": "Kynnysarvoa pienemmät osat yhdistetään viereisiin osiin mahdollisuuksien mukaan. Aseta arvoksi 0 poistaaksesi yhdistämisen käytöstä.", "Ciphers": "Salausalgoritmi", "Citation": "Lähdeviite", "Citations": "Lähdeviitteet", @@ -303,7 +303,7 @@ "Code Block": "Koodilohko", "Code Editor": "Koodieditori", "Code execution": "Koodin suoritus", - "Code Execution": "", + "Code Execution": "Koodin suoritus", "Code Execution Engine": "Koodin suoritusmoottori", "Code Execution Timeout": "Koodin suorittamisen aikakatkaisu", "Code formatted successfully": "Koodin muotoilu onnistui", @@ -313,7 +313,7 @@ "Collaboration channel where people join as members": "Yhteistyökanava, johon ihmiset liittyvät jäseninä", "Collapse": "Pienennä", "Collection": "Kokoelma", - "Collections": "", + "Collections": "Kokoelmat", "Color": "Väri", "ComfyUI": "ComfyUI", "ComfyUI API Key": "ComfyUI API -avain", @@ -346,12 +346,12 @@ "Contact Admin for WebUI Access": "Ota yhteyttä ylläpitäjään WebUI-käyttöä varten", "Content": "Sisältö", "Content Extraction Engine": "Sisällönpoimintamoottori", - "Content lengths (character counts only)": "", + "Content lengths (character counts only)": "Sisällön pituus (vain merkkimäärä)", "Continue Response": "Jatka vastausta", "Continue with {{provider}}": "Jatka palvelulla {{provider}}", "Continue with Email": "Jatka sähköpostilla", "Continue with LDAP": "Jatka LDAP:illa", - "Control how message text is split for TTS requests. 'Punctuation' splits into sentences, 'paragraphs' splits into paragraphs, and 'none' keeps the message as a single string.": "Säädä, miten viestin teksti jaetaan puhesynteesipyyntöjä varten. 'Välimerkit' jakaa lauseisiin, 'kappaleet' jakaa kappaleisiin ja 'ei mitään' pitää viestin yhtenä merkkijonona.", + "Control how message text is split for TTS requests. 'Punctuation' splits into sentences, 'paragraphs' splits into paragraphs, and 'none' keeps the message as a single string.": "Muokkaa, miten viestin teksti jaetaan puhesynteesipyyntöjä varten. 'Välimerkit' jakaa lauseisiin, 'kappaleet' jakaa kappaleisiin ja 'ei mitään' pitää viestin yhtenä merkkijonona.", "Control the repetition of token sequences in the generated text. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 1.1) will be more lenient. At 1, it is disabled.": "", "Controls": "Ohjaimet", "Controls the balance between coherence and diversity of the output. A lower value will result in more focused and coherent text.": "Kontrolloi yhtenäisyyden ja monimuotoisuuden tasapainoa tuloksessa. Pienempi arvo tuottaa kohdennetumman ja johdonmukaisemman tekstin.", @@ -367,7 +367,7 @@ "Copy link": "Kopioi linkki", "Copy Link": "Kopioi linkki", "Copy to clipboard": "Kopioi leikepöydälle", - "Copy URL": "", + "Copy URL": "Kopioi linkki", "Copying to clipboard was successful!": "Kopioiminen leikepöydälle onnistui!", "CORS must be properly configured by the provider to allow requests from Open WebUI.": "CORS täytyy olla konfiguroitu palveluntarjoajan toimesta pyyntöjen hyväksymiseksi Open WebUI:sta.", "Create": "Luo", @@ -384,14 +384,14 @@ "Create Model": "Luo malli", "Create new key": "Luo uusi avain", "Create new secret key": "Luo uusi salainen avain", - "Create note": "", + "Create note": "Luo muistiinpano", "Create Note": "Luo muistiinpano", "Create your first note by clicking on the plus button below.": "Luo ensimmäinen muistiinpanosi painamalla alla olevaa plus painiketta.", "Created at": "Luotu", "Created At": "Luotu", "Created by": "Luonut", "Created by you": "Sinun luomasi", - "Created on {{date}}": "", + "Created on {{date}}": "Luotu {{date}}", "CSV Import": "CSV-tuonti", "Ctrl+Enter to Send": "Ctrl+Enter lähettääksesi", "Current Model": "Nykyinen malli", @@ -417,7 +417,7 @@ "Default description enabled": "Oletuskuvaus käytössä", "Default Features": "Oletus ominaisuudet", "Default Filters": "Oletus suodattimet", - "Default Group": "Oletus ryhmä", + "Default Group": "Oletusryhmä", "Default mode works with a wider range of models by calling tools once before execution. Native mode leverages the model's built-in tool-calling capabilities, but requires the model to inherently support this feature.": "Oletustila toimii laajemman mallivalikoiman kanssa kutsumalla työkaluja kerran ennen suorittamista. Natiivitila hyödyntää mallin sisäänrakennettuja työkalujen kutsumisominaisuuksia, mutta edellyttää, että malli tukee tätä ominaisuutta.", "Default Model": "Oletusmalli", "Default model updated": "Oletusmalli päivitetty", @@ -447,12 +447,12 @@ "delete this link": "poista tämä linkki", "Delete tool?": "Haluatko varmasti poistaa tämän työkalun?", "Delete User": "Poista käyttäjä", - "Deleted": "", + "Deleted": "Poistettu", "Deleted {{deleteModelTag}}": "Poistettu {{deleteModelTag}}", "Deleted {{name}}": "Poistettu {{nimi}}", "Deleted User": "Käyttäjä poistettu", "Deployment names are required for Azure OpenAI": "Azure OpenAI:lle vaaditaan käyttöönottojen nimet", - "Desc": "", + "Desc": "Laskeva", "Describe your knowledge base and objectives": "Kuvaa tietokantasi ja tavoitteesi", "Description": "Kuvaus", "Detect Artifacts Automatically": "Tunnista artefaktit automaattisesti", @@ -489,7 +489,7 @@ "Dive into knowledge": "Uppoudu tietoon", "Do not install functions from sources you do not fully trust.": "Älä asenna toimintoja lähteistä, joihin et luota täysin.", "Do not install tools from sources you do not fully trust.": "Älä asenna työkaluja lähteistä, joihin et luota täysin.", - "Do you want to sync your usage stats with Open WebUI Community?": "", + "Do you want to sync your usage stats with Open WebUI Community?": "Haluatko jakaa käyttötilastosi Open WebUI yhteisön kanssa?", "Docling": "Docling", "Docling Parameters": "Docling parametrit", "Docling Server URL required.": "Docling palvelimen verkko-osoite vaaditaan.", @@ -498,7 +498,7 @@ "Document Intelligence endpoint required.": "Document Intelligence pääte vaaditaan", "Document Intelligence Model": "Document Intelligence malli", "Documentation": "Dokumentaatio", - "Documents": "", + "Documents": "Dokumentit", "does not make any external connections, and your data stays securely on your locally hosted server.": "ei tee ulkoisia yhteyksiä, ja tietosi pysyvät turvallisesti paikallisesti isännöidyllä palvelimellasi.", "Domain Filter List": "Verkko-osoitteiden suodatuslista", "don't fetch random pipelines from sources you don't trust.": "Älä hae satunnaisia pipelineja epäluotettavista lähteistä.", @@ -509,11 +509,11 @@ "Done": "Valmis", "Download": "Lataa", "Download & Delete": "Lataa ja poista", - "Download as JSON": "", + "Download as JSON": "Lataa JSON:na", "Download as SVG": "Lataa SVG:nä", "Download canceled": "Lataus peruutettu", "Download Database": "Lataa tietokanta", - "Downloading stats...": "", + "Downloading stats...": "Ladataa tilastoja...", "Draw": "Piirros", "Drop any files here to upload": "Pudota tähän ladattavat tiedostot", "DuckDuckGo": "", @@ -522,7 +522,7 @@ "e.g. 60": "esim. 60", "e.g. A filter to remove profanity from text": "esim. suodatin, joka poistaa kirosanoja tekstistä", "e.g. about the Roman Empire": "esim. Rooman valtakunta", - "e.g. alloy, echo, shimmer": "", + "e.g. alloy, echo, shimmer": "esim. alloy, echo, shimmer", "e.g. en": "esim. en", "e.g. My Filter": "esim. Oma suodatin", "e.g. My Tools": "esim. Omat työkalut", @@ -575,7 +575,7 @@ "Endpoint URL": "Päätepiste verkko-osoite", "Enforce Temporary Chat": "Pakota väliaikaiset keskustelut", "Enhance": "Paranna", - "Enrich Hybrid Search Text": "", + "Enrich Hybrid Search Text": "Rikasta hybridihakutekstiä", "Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "Varmista, että CSV-tiedostossasi on 4 saraketta tässä järjestyksessä: Nimi, Sähköposti, Salasana, Rooli.", "Enter {{role}} message here": "Kirjoita {{role}}-viesti tähän", "Enter a detail about yourself for your LLMs to recall": "Kirjoita yksityiskohta itsestäsi, jonka LLM-ohjelmat voivat muistaa", @@ -592,7 +592,7 @@ "Enter Bocha Search API Key": "Kirjoita Bocha Search API -avain", "Enter Brave Search API Key": "Kirjoita Brave Search API -avain", "Enter certificate path": "Kirjoita varmennepolku", - "Enter Chunk Min Size Target": "", + "Enter Chunk Min Size Target": "Kirjoita osien vähimmäiskoko", "Enter Chunk Overlap": "Syötä osien päällekkäisyys", "Enter Chunk Size": "Syötä osien koko", "Enter comma-separated \"token:bias_value\" pairs (example: 5432:100, 413:-100)": "Syötä pilkulla erottaen \"token:bias_value\" parit (esim. 5432:100, 413:-100)", @@ -616,7 +616,7 @@ "Enter External Web Search URL": "Kirjoita ulkoisen Web Search verkko-osoite", "Enter Firecrawl API Base URL": "Kirjoita Firecrawl API -verkko-osoite", "Enter Firecrawl API Key": "Kirjoita Firecrawl API-avain", - "Enter Firecrawl Timeout": "", + "Enter Firecrawl Timeout": "Kirjoita Firecrawl aikakatkaisu", "Enter folder name": "Kirjoita kansion nimi", "Enter function name filter list (e.g. func1, !func2)": "Kirjoita funktion nimen suodatinluettelo (esim. func1, !func2)", "Enter Github Raw URL": "Kirjoita Github Raw -verkko-osoite", @@ -625,7 +625,7 @@ "Enter hex color (e.g. #FF0000)": "Kirjota hex väri (esim. #FF0000)", "Enter ID": "Kirjoita ID", "Enter Image Size (e.g. 512x512)": "Kirjoita kuvan koko (esim. 512x512)", - "Enter Jina API Base URL": "", + "Enter Jina API Base URL": "Kirjoita Jina API verkko-osoite", "Enter Jina API Key": "Kirjoita Jina API -avain", "Enter JSON config (e.g., {\"disable_links\": true})": "Kirjoita JSON asetus (esim. {\"disable_links\": true})", "Enter Jupyter Password": "Kirjoita Jupyter salasana", @@ -634,7 +634,7 @@ "Enter Kagi Search API Key": "Kirjoita Kagi Search API -avain", "Enter Key Behavior": "Enter näppäimen käyttäytyminen", "Enter language codes": "Kirjoita kielikoodit", - "Enter MinerU API Key": "", + "Enter MinerU API Key": "Kirjoita MinerU API-avain", "Enter Mistral API Base URL": "Kirjoita Mistral API verkko-osoite", "Enter Mistral API Key": "Kirjoita Mistral API-avain", "Enter Model ID": "Kirjoita mallitunnus", @@ -654,7 +654,7 @@ "Enter SearchApi API Key": "Kirjoita SearchApi API -avain", "Enter SearchApi Engine": "Kirjoita SearchApi-moottori", "Enter Searxng Query URL": "Kirjoita Searxng-kyselyn verkko-osoite", - "Enter Searxng search language": "", + "Enter Searxng search language": "Kirjoita Searxng hakukieli", "Enter Seed": "Kirjoita siemenluku", "Enter SerpApi API Key": "Kirjoita SerpApi API -avain", "Enter SerpApi Engine": "Valitse SerpApi Moottori", @@ -760,10 +760,10 @@ "Failed to generate title": "Otsikon luonti epäonnistui", "Failed to import models": "Mallien tuonti epäonnistui", "Failed to load chat preview": "Keskustelun esikatselun lataaminen epäonnistui", - "Failed to load Excel/CSV file. Please try downloading it instead.": "", + "Failed to load Excel/CSV file. Please try downloading it instead.": "Excel/CSV tiedoston lataaminen epäonnistui. Yritä ladata se sen sijaan.", "Failed to load file content.": "Tiedoston sisällön lataaminen epäonnistui.", "Failed to move chat": "Keskustelun siirto epäonnistui", - "Failed to process URL: {{url}}": "", + "Failed to process URL: {{url}}": "Verkko-osoitteen käsittely epäonnistui: {{url}}", "Failed to read clipboard contents": "Leikepöydän sisällön lukeminen epäonnistui", "Failed to remove member": "Jäsenen poistaminen epäonnistui", "Failed to render diagram": "Diagrammin renderöinti epäonnistui", @@ -777,7 +777,7 @@ "Features": "Ominaisuudet", "Features Permissions": "Ominaisuuksien käyttöoikeudet", "February": "helmikuu", - "Feedback": "", + "Feedback": "Palaute", "Feedback deleted successfully": "Palaute poistettu onnistuneesti", "Feedback Details": "Palautteen tiedot", "Feedback History": "Palautehistoria", @@ -786,7 +786,7 @@ "File": "Tiedosto", "File added successfully.": "Tiedosto lisätty onnistuneesti.", "File content updated successfully.": "Tiedoston sisältö päivitetty onnistuneesti.", - "File Context": "", + "File Context": "Tiedoston konteksti", "File Mode": "Tiedostotila", "File not found.": "Tiedostoa ei löytynyt.", "File removed successfully.": "Tiedosto poistettu onnistuneesti.", @@ -802,13 +802,13 @@ "Fingerprint spoofing detected: Unable to use initials as avatar. Defaulting to default profile image.": "Sormenjäljen väärentäminen havaittu: Alkukirjaimia ei voi käyttää avatarina. Käytetään oletusprofiilikuvaa.", "Firecrawl API Base URL": "Firecrawl API -verkko-osoite", "Firecrawl API Key": "Firecrawl API-avain", - "Firecrawl Timeout (s)": "", + "Firecrawl Timeout (s)": "Firecrawl aikakatkaisu (t)", "Floating Quick Actions": "Kelluvat pikakomennot", "Focus Chat Input": "Kohdista keskustelu tekstikenttään", "Folder": "Kansio", "Folder Background Image": "Kansion taustakuva", "Folder deleted successfully": "Kansio poistettu onnistuneesti", - "Folder Max File Count": "", + "Folder Max File Count": "Kansion tiedostojen enimmäismäärä", "Folder Name": "Kansion nimi", "Folder name cannot be empty.": "Kansion nimi ei voi olla tyhjä.", "Folder name updated successfully": "Kansion nimi päivitetty onnistuneesti", @@ -868,7 +868,7 @@ "Google PSE API Key": "Google PSE API -avain", "Google PSE Engine Id": "Google PSE -moottorin tunnus", "Gravatar": "Gravatar", - "Grid": "", + "Grid": "Ruudukko", "Grokipedia": "", "Group": "Ryhmä", "Group Channel": "Ryhmäkanava", @@ -923,7 +923,7 @@ "Image Prompt Generation": "Kuvan kehote generointi", "Image Prompt Generation Prompt": "Kuvan generoinnin kehote", "Image Size": "Kuvan koko", - "Images": "", + "Images": "Kuvat", "Import": "Tuo", "Import Chats": "Tuo keskustelut", "Import Config from JSON File": "Tuo asetukset JSON-tiedostosta", @@ -942,7 +942,7 @@ "Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive.": "Kuinka nopeasti algoritmi mukautuu generoidun tekstin palautteeseen. Alempi oppimisnopeus hidastaa mukautumista, kun taas nopeampi oppimisnopeus tekee algoritmistä reagoivamman.", "Info": "Tiedot", "Initials": "Nimikirjaimet", - "Inject file content into conversation context": "", + "Inject file content into conversation context": "Upota tiedostosisältö keskustelun kontekstiin", "Inject the entire content as context for comprehensive processing, this is recommended for complex queries.": "Upota koko sisältö kontekstiin kattavaa käsittelyä varten. Tätä suositellaan monimutkaisille kyselyille.", "Input": "Tekstikenttä", "Input Key (e.g. text, unet_name, steps)": "Syötteen arvo (esim. text, unet_namme, steps)", @@ -956,7 +956,7 @@ "Integration": "Integrointi", "Integrations": "Integraatiot", "Interface": "Käyttöliittymä", - "Interface Settings Access": "", + "Interface Settings Access": "Käyttöliittymän asetusten käyttöoikeus", "Invalid file content": "Virheellinen tiedostosisältö", "Invalid file format.": "Virheellinen tiedostomuoto.", "Invalid JSON file": "Virheellinen JSON tiedosto", @@ -970,7 +970,7 @@ "is typing...": "Kirjoittaa...", "Italic": "Kursiivi", "January": "tammikuu", - "Jina API Base URL": "", + "Jina API Base URL": "Jina API verkko-osoite", "Jina API Key": "Jina API -avain", "join our Discord for help.": "liity Discordiimme saadaksesi apua.", "JSON": "JSON", @@ -995,7 +995,7 @@ "Knowledge created successfully.": "Tietokanta luotu onnistuneesti.", "Knowledge deleted successfully.": "Tietokanta poistettu onnistuneesti.", "Knowledge Description": "Tietokannan kuvaus", - "Knowledge exported successfully": "", + "Knowledge exported successfully": "Tietokanta viety onnistuneesti", "Knowledge Name": "Tietokannan nimi", "Knowledge Public Sharing": "Tietokannan julkinen jakaminen", "Knowledge reset successfully.": "Tietokanta nollattu onnistuneesti.", @@ -1022,7 +1022,7 @@ "Leave empty to include all models from \"{{url}}/api/tags\" endpoint": "Jätä tyhjäksi sisällyttääksesi \"{{url}}/api/tags\" päätepisteen mallit", "Leave empty to include all models from \"{{url}}/models\" endpoint": "Jätä tyhjäksi sisällyttääksesi \"{{url}}/models\" päätepisteen mallit", "Leave empty to include all models or select specific models": "Jätä tyhjäksi, jos haluat sisällyttää kaikki mallit tai valitse tietyt mallit", - "Leave empty to use first admin user": "", + "Leave empty to use first admin user": "Jätä tyhjäksi käyttääksesi ensimmäistä ylläpitäjää", "Leave empty to use the default model (voxtral-mini-latest).": "Jätä tyhjäks käyttääksesi oletusmallia (voxtral-mini-latest)", "Leave empty to use the default prompt, or enter a custom prompt": "Jätä tyhjäksi käyttääksesi oletuskehotetta tai kirjoita mukautettu kehote", "Leave model field empty to use the default model.": "Jätä malli kenttä tyhjäksi käyttääksesi oletus mallia.", @@ -1031,8 +1031,8 @@ "License": "Lisenssi", "Lift List": "Nostolista", "Light": "Vaalea", - "Limit concurrent search queries. 0 = unlimited (default). Set to 1 for sequential execution (recommended for APIs with strict rate limits like Brave free tier).": "", - "List": "", + "Limit concurrent search queries. 0 = unlimited (default). Set to 1 for sequential execution (recommended for APIs with strict rate limits like Brave free tier).": "Rajoita samanaikaisia hakukyselyitä. 0 = rajoittamaton (oletus). Aseta arvoon 1 peräkkäistä suoritusta varten (suositellaan API-rajapinnoille, joilla on tiukat nopeusrajoitukset, kuten Brave-ilmaistaso).", + "List": "Lista", "Listening...": "Kuuntelee...", "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "Kielimallit voivat tehdä virheitä. Tarkista tärkeät tiedot.", @@ -1062,12 +1062,12 @@ "Manage your account information.": "Hallitse tilitietojasi", "March": "maaliskuu", "Markdown": "Markdown", - "Markdown Header Text Splitter": "", + "Markdown Header Text Splitter": "Markdown-otsikkotekstin jakaja", "Max Speakers": "Puhujien enimmäismäärä", "Max Upload Count": "Latausten enimmäismäärä", "Max Upload Size": "Latausten enimmäiskoko", - "Maximum number of files allowed per folder.": "", - "Maximum number of files per folder is {{max}}.": "", + "Maximum number of files allowed per folder.": "Kansiota kohden sallittujen tiedostojen enimmäismäärä.", + "Maximum number of files per folder is {{max}}.": "Tiedostojen enimmäismäärä kansiossa on {{max}}.", "Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Enintään 3 mallia voidaan ladata samanaikaisesti. Yritä myöhemmin uudelleen.", "May": "toukokuu", "MBR": "MBR", @@ -1077,7 +1077,7 @@ "Member removed successfully": "Jäsen poistettu onnistuneesti", "Members": "Jäsenet", "Members added successfully": "Jäsen lisätty onnistuneesti", - "Memories": "", + "Memories": "Muistot", "Memories accessible by LLMs will be shown here.": "Muistitiedostot, joita LLM-ohjelmat käyttävät, näkyvät tässä.", "Memory": "Muisti", "Memory added successfully": "Muisti lisätty onnistuneesti", @@ -1087,7 +1087,7 @@ "Merge Responses": "Yhdistä vastaukset", "Merged Response": "Yhdistetty vastaus", "Message": "Viesti", - "Message counts and response timestamps": "", + "Message counts and response timestamps": "Viestien määrä ja vastausten aikaleimat", "Message rating should be enabled to use this feature": "Tämän toiminnon käyttämiseksi viestiarviointi on otettava käyttöön", "Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "Linkin luomisen jälkeen lähettämäsi viestit eivät ole jaettuja. Käyttäjät, joilla on verkko-osoite, voivat tarkastella jaettua keskustelua.", "Microsoft OneDrive": "", @@ -1120,11 +1120,11 @@ "Model Name": "Mallin nimi", "Model name already exists, please choose a different one": "Mallin nimi on jo olemassa, valitse toinen nimi.", "Model Name is required.": "Mallin nimi on pakollinen", - "Model names and usage frequency": "", + "Model names and usage frequency": "Mallien nimet ja käyttötiheys", "Model not selected": "Mallia ei ole valittu", "Model Params": "Mallin parametrit", "Model Permissions": "Mallin käyttöoikeudet", - "Model responses or outputs": "", + "Model responses or outputs": "Mallin vastaukset tai tuotokset", "Model unloaded successfully": "Malli purettu onnistuneesti", "Model updated successfully": "Malli päivitetty onnistuneesti", "Model(s) do not support file upload": "Malli(t) ei tue tiedostojen lataamista", @@ -1145,22 +1145,22 @@ "Name and ID are required, please fill them out": "Nimi ja ID vaaditaan, täytä puuttuvat kentät", "Name your knowledge base": "Anna tietokannalle nimi", "Native": "Natiivi", - "New": "", + "New": "Uusi", "New Button": "Uusi painike", "New Chat": "Uusi keskustelu", "New Folder": "Uusi kansio", "New Function": "Uusi toiminto", "New Knowledge": "Uutta tietoa", "New Model": "Uusi malli", - "New Note": "", + "New Note": "Uusi muistiinpano", "New Password": "Uusi salasana", "New Prompt": "Uusi kehoite", "New Temporary Chat": "Uusi väliaikainen keskustelu", "New Tool": "Uusi työkalu", - "New Webhook": "", + "New Webhook": "Uusi Webhook", "new-channel": "uusi-kanava", "Next message": "Seuraava viesti", - "No activity data": "", + "No activity data": "Ei aktiivisuustietoja", "No authentication": "Ei todennusta", "No chats found": "Keskuteluja ei löytynyt", "No chats found for this user.": "Käyttäjän keskusteluja ei löytynyt.", @@ -1171,14 +1171,14 @@ "No conversation to save": "Ei tallennettavaa keskustelua", "No distance available": "Etäisyyttä ei saatavilla", "No expiration can pose security risks.": "Vanhenemisen laittamatta jättäminen voi altistaa tietoturvariskeille.", - "No feedback found": "", + "No feedback found": "Ei palautetta", "No file selected": "Tiedostoa ei ole valittu", - "No files in this knowledge base.": "", + "No files in this knowledge base.": "Tässä tietokannassa ei ole tiedostoja.", "No functions found": "Funktioita ei löytynyt", "No groups with access, add a group to grant access": "Ei ryhmiä, joilla on pääsy, lisää ryhmä antaaksesi pääsyn", "No HTML, CSS, or JavaScript content found.": "HTML-, CSS- tai JavaScript-sisältöä ei löytynyt.", "No inference engine with management support found": "", - "No knowledge bases found.": "", + "No knowledge bases found.": "Tietokantoja ei löytynyt.", "No knowledge found": "Tietoa ei löytynyt", "No memories to clear": "Ei muistia tyhjennettäväksi", "No model IDs": "Ei mallitunnuksia", @@ -1186,7 +1186,7 @@ "No models selected": "Malleja ei ole valittu", "No Notes": "Ei muistiinpanoja", "No notes found": "Muistiinpanoja ei löytynyt", - "No one": "", + "No one": "Kukaan", "No pinned messages": "Ei kiinnitettyjä viestejä", "No prompts found": "Kehoitteita ei löytynyt", "No results": "Ei tuloksia", @@ -1199,7 +1199,7 @@ "No users were found.": "Käyttäjiä ei löytynyt.", "No valves": "Ei venttiileitä", "No valves to update": "Ei venttiileitä päivitettäväksi", - "No webhooks yet": "", + "No webhooks yet": "Ei vielä webhookeja", "Node Ids": "Node id:t", "None": "Ei mikään", "Not factually correct": "Ei faktuaalisesti oikein", @@ -1239,7 +1239,7 @@ "Only invited users can access": "Vain kutsutut jäsenet voivat päästä", "Only markdown files are allowed": "Vain markdown tiedostot ovat sallittuja", "Only select users and groups with permission can access": "Vain valitut käyttäjät ja ryhmät, joilla on käyttöoikeus, pääsevät käyttämään", - "Only sync new/updated chats": "", + "Only sync new/updated chats": "Synkronoi vain uudet/päivitetyt keskustelut", "Oops! Looks like the URL is invalid. Please double-check and try again.": "Hups! Näyttää siltä, että verkko-osoite on virheellinen. Tarkista se ja yritä uudelleen.", "Oops! There are files still uploading. Please wait for the upload to complete.": "Hups! Tiedostoja on vielä ladattavana. Odota, että lataus on valmis.", "Oops! There was an error in the previous response.": "Hups! Edellisessä vastauksessa oli virhe.", @@ -1256,7 +1256,7 @@ "Open WebUI can use tools provided by any OpenAPI server.": "Open WebUI voi käyttää minkä tahansa OpenAPI-palvelimen tarjoamia työkaluja.", "Open WebUI uses faster-whisper internally.": "Open WebUI käyttää faster-whisperia sisäisesti.", "Open WebUI uses SpeechT5 and CMU Arctic speaker embeddings.": "Open WebUI käyttää SpeechT5:tä ja CMU Arctic -kaiuttimen upotuksia.", - "Open WebUI version": "", + "Open WebUI version": "Open WebUI versio", "Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "Open WebUI -versio (v{{OPEN_WEBUI_VERSION}}) on alempi kuin vaadittu versio (v{{REQUIRED_VERSION}})", "OpenAI": "OpenAI", "OpenAI API": "OpenAI API", @@ -1281,8 +1281,8 @@ "page": "sivu", "Paginate": "Sivutus", "Parameters": "Parametrit", - "Parent message not found": "", - "Participate in community leaderboards and evaluations! Syncing aggregated usage stats helps drive research and improvements to Open WebUI. Your privacy is paramount: no message content is ever shared.": "", + "Parent message not found": "Ylätason viestiä ei löytynyt", + "Participate in community leaderboards and evaluations! Syncing aggregated usage stats helps drive research and improvements to Open WebUI. Your privacy is paramount: no message content is ever shared.": "Osallistu yhteisön tulostaulukoihin ja arviointeihin! Koottujen käyttötilastojen synkronointi auttaa edistämään Open WebUI:n tutkimuksia ja parannuksia. Tietosuojasi on ensiarvoisen tärkeää: viestien sisältöä ei koskaan jaeta.", "Password": "Salasana", "Passwords do not match.": "Salasanat eivät täsmää", "Paste Large Text as File": "Liitä suuri teksti tiedostona", @@ -1308,7 +1308,7 @@ "Pipe": "Putki", "Pipeline deleted successfully": "Putki poistettu onnistuneesti", "Pipeline downloaded successfully": "Putki ladattu onnistuneesti", - "Pipelines": "", + "Pipelines": "Putkistot", "Pipelines are a plugin system with arbitrary code execution —": "Pipelines on liitännäisjärjestelmä, jossa voidaan suorittaa mielivaltaista koodia —", "Pipelines Not Detected": "Putkistoja ei havaittu", "Pipelines Valves": "Putkistojen venttiilit", @@ -1371,8 +1371,8 @@ "Read": "Lue", "Read Aloud": "Lue ääneen", "Read more →": "Lue lisää →", - "Read Only": "", - "Read-Only Access": "", + "Read Only": "Vain luku", + "Read-Only Access": "Vain lukuoikeus", "Reason": "Päättely", "Reasoning Effort": "Päättelyn määrä", "Reasoning Tags": "Päättely tagit", @@ -1545,7 +1545,7 @@ "Sets the stop sequences to use. When this pattern is encountered, the LLM will stop generating text and return. Multiple stop patterns may be set by specifying multiple separate stop parameters in a modelfile.": "Määrittää käytettävät lopetussekvenssit. Kun tämä kuvio havaitaan, LLM lopettaa tekstin tuottamisen ja palauttaa. Useita lopetuskuvioita voidaan asettaa määrittämällä useita erillisiä lopetusparametreja mallitiedostoon.", "Setting": "Asetus", "Settings": "Asetukset", - "Settings Permissions": "", + "Settings Permissions": "Asetuksien käyttöoikeudet", "Settings saved successfully!": "Asetukset tallennettu onnistuneesti!", "Share": "Jaa", "Share Chat": "Jaa keskustelu", @@ -1556,7 +1556,7 @@ "Show": "Näytä", "Show \"What's New\" modal on login": "Näytä \"Mitä uutta\" -modaali kirjautumisen yhteydessä", "Show Admin Details in Account Pending Overlay": "Näytä ylläpitäjän tiedot odottavan tilin päällä", - "Show Files": "", + "Show Files": "Näytä tiedostot", "Show Formatting Toolbar": "Näytä muotoilupalkki", "Show image preview": "Näytä kuvan esikatselu", "Show Model": "Näytä malli", @@ -1581,7 +1581,7 @@ "Sonar Pro": "Sonar Pro", "Sonar Reasoning": "Sonar Reasoning", "Sonar Reasoning Pro": "Sonar Reasoning Pro", - "Sort": "", + "Sort": "Järjestele", "Sougou Search API sID": "Sougou Search API sID", "Sougou Search API SK": "Sougou Search API SK", "Source": "Lähde", @@ -1600,7 +1600,7 @@ "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "Askeleet", "Stop": "Pysäytä", - "Stop Download": "", + "Stop Download": "Lopeta lataus", "Stop Generating": "Lopeta generointi", "Stop Sequence": "Lopetussekvenssi", "Stream Chat Response": "Streamaa keskusteluvastaus", @@ -1621,14 +1621,14 @@ "Support": "Tuki", "Support this plugin:": "Tue tätä lisäosaa:", "Supported MIME Types": "Tuetut MIME-tyypit", - "Sync": "", - "Sync Complete!": "", + "Sync": "Synkronoi", + "Sync Complete!": "Synkronointi valmis!", "Sync directory": "Synkronoitu hakemisto", - "Sync Failed": "", - "Sync Usage Stats": "", - "Syncing stats...": "", - "Syncing...": "", - "Syncs only chats with updates after your last sync timestamp. Disable to re-sync all chats.": "", + "Sync Failed": "Synkronointi epäonnistui", + "Sync Usage Stats": "Synkronoinnin käyttötilastot", + "Syncing stats...": "Synkronoidaan tilastoja...", + "Syncing...": "Synkronoidaan...", + "Syncs only chats with updates after your last sync timestamp. Disable to re-sync all chats.": "Synkronoi vain keskustelut, joihin on tehty päivityksiä viimeisen synkronoinnin aikaleiman jälkeen. Poista käytöstä synkronoidaksesi kaikki keskustelut uudelleen.", "System": "Järjestelmä", "System Instructions": "Järjestelmäohjeet", "System Prompt": "Järjestelmäkehote", @@ -1673,7 +1673,7 @@ "The Weight of BM25 Hybrid Search. 0 more semantic, 1 more lexical. Default 0.5": "", "The width in pixels to compress images to. Leave empty for no compression.": "Leveys pikseleinä, johon kuvat pakataan. Jätä tyhjäksi, jos et halua pakkausta.", "Theme": "Teema", - "There was an error syncing your stats. Please try again.": "", + "There was an error syncing your stats. Please try again.": "Tilastojen synkronoinnissa tapahtui virhe. Yritä uudelleen.", "Thinking...": "Ajattelee...", "This action cannot be undone. Do you wish to continue?": "Tätä toimintoa ei voi peruuttaa. Haluatko jatkaa?", "This channel was created on {{createdAt}}. This is the very beginning of the {{channelName}} channel.": "Tämä kanava on luotiin {{createdAt}}. Tämä on {{channelName}} kanavan alku.", @@ -1702,7 +1702,7 @@ "Tika": "Tika", "Tika Server URL required.": "Tika palvelimen verkko-osoite vaaditaan.", "Tiktoken": "Tiktoken", - "Timeout": "", + "Timeout": "Aikakatkaisu", "Title": "Otsikko", "Title Auto-Generation": "Otsikon automaattinen luonti", "Title cannot be an empty string.": "Otsikko ei voi olla tyhjä merkkijono.", @@ -1787,7 +1787,7 @@ "Upload Pipeline": "Lataa putki", "Upload Progress": "Latauksen edistyminen", "Upload Progress: {{uploadedFiles}}/{{totalFiles}} ({{percentage}}%)": "Latauksen edistyminen: {{uploadedFiles}}/{{totalFiles}} ({{percentage}}%)", - "Uploaded files or images": "", + "Uploaded files or images": "Ladatut tiedostot tai kuvat", "Uploading file...": "Ladataan tiedostoa...", "URL": "URL", "URL is required": "URL vaaditaan", @@ -1805,8 +1805,8 @@ "User Groups": "Käyttäjäryhmät", "User location successfully retrieved.": "Käyttäjän sijainti haettu onnistuneesti.", "User menu": "Käyttäjävalikko", - "User ratings (thumbs up/down)": "", - "User Status": "", + "User ratings (thumbs up/down)": "Käyttäjien arviot (peukku ylös/alas)", + "User Status": "Käyttäjän tila", "User Webhooks": "Käyttäjän Webhook:it", "Username": "Käyttäjätunnus", "users": "käyttäjät", @@ -1847,10 +1847,10 @@ "Web Search Engine": "Hakukoneet", "Web Search in Chat": "Verkkohaku keskustelussa", "Web Search Query Generation": "Verkkohakukyselyn luonti", - "Webhook Name": "", + "Webhook Name": "Webhook nimi", "Webhook URL": "Webhook verkko-osoite", - "Webhooks": "", - "Webpage URLs": "", + "Webhooks": "Webhookit", + "Webpage URLs": "Verkkosivujen verkko-osoitteet", "WebUI Settings": "WebUI-asetukset", "WebUI URL": "WebUI-osoite", "WebUI will make requests to \"{{url}}\"": "WebUI lähettää pyyntöjä osoitteeseen \"{{url}}\"", @@ -1858,15 +1858,15 @@ "WebUI will make requests to \"{{url}}/chat/completions\"": "WebUI lähettää pyyntöjä osoitteeseen \"{{url}}/chat/completions\"", "What are you trying to achieve?": "Mitä yrität saavuttaa?", "What are you working on?": "Mitä olet työskentelemässä?", - "What is NOT shared:": "", - "What is shared:": "", + "What is NOT shared:": "Mitä EI jaeta:", + "What is shared:": "Mitä jaetaan:", "What's New in": "Mitä uutta", "What's on your mind?": "Mitä ajattelet?", "When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "Kun käytössä, malli vastaa jokaiseen chatviestiin reaaliajassa, tuottaen vastauksen heti kun käyttäjä lähettää viestin. Tämä tila on hyödyllinen reaaliaikaisissa chat-sovelluksissa, mutta voi vaikuttaa suorituskykyyn hitaammilla laitteistoilla.", "wherever you are": "missä tahansa oletkin", "Whether to paginate the output. Each page will be separated by a horizontal rule and page number. Defaults to False.": "Sivutetaanko tuloste. Jokainen sivu erotetaan toisistaan vaakasuoralla viivalla ja sivunumerolla. Oletusarvo ei käytössä.", "Whisper (Local)": "Whisper (paikallinen)", - "Who can share to this group": "", + "Who can share to this group": "Ketkä voivat jakaa tähän ryhmään", "Why?": "Miksi?", "Widescreen Mode": "Laajakuvatila", "Width": "Leveys", @@ -1891,12 +1891,12 @@ "You can only chat with a maximum of {{maxCount}} file(s) at a time.": "Voit keskustella enintään {{maxCount}} tiedoston kanssa kerralla.", "You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "Voit personoida vuorovaikutustasi LLM-ohjelmien kanssa lisäämällä muistoja 'Hallitse'-painikkeen kautta, jolloin ne ovat hyödyllisempiä ja räätälöityjä sinua varten.", "You cannot upload an empty file.": "Et voi ladata tyhjää tiedostoa.", - "You do not have permission to edit this model": "", - "You do not have permission to edit this prompt.": "", - "You do not have permission to save this prompt.": "", + "You do not have permission to edit this model": "Sinulla ei ole oikeuksia muokata tätä mallinetta", + "You do not have permission to edit this prompt.": "Sinulla ei ole oikeuksia muokata tätä kehotetta.", + "You do not have permission to save this prompt.": "Sinulla ei ole oikeuksia tallentaa tätä kehotetta.", "You do not have permission to send messages in this channel.": "Sinulla ei ole oikeuksia lähettää viestejä tähän kanavaan.", "You do not have permission to send messages in this thread.": "Sinulla ei ole oikeuksia lähettää viestejä tähän ketjuun.", - "You do not have permission to upload files to this knowledge base.": "", + "You do not have permission to upload files to this knowledge base.": "Sinulla ei ole oikeuksia ladata tiedostoja tähän tietokantaan.", "You do not have permission to upload files.": "Sinulla ei ole lupaa ladata tiedostoja.", "You have no archived conversations.": "Sinulla ei ole arkistoituja keskusteluja.", "You have shared this chat": "Olet jakanut tämän keskustelun", @@ -1905,8 +1905,8 @@ "Your Account": "Tilisi", "Your account status is currently pending activation.": "Tilisi tila on tällä hetkellä odottaa aktivointia.", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Koko panoksesi menee suoraan lisäosan kehittäjälle; Open WebUI ei pidätä prosenttiosuutta. Valittu rahoitusalusta voi kuitenkin periä omia maksujaan.", - "Your message text or inputs": "", - "Your usage stats have been successfully synced.": "", + "Your message text or inputs": "Viestisi teksti tai syöteet", + "Your usage stats have been successfully synced.": "Käyttötilastosi on synkronoitu onnistuneesti.", "YouTube": "YouTube", "Youtube Language": "Youtube kieli", "Youtube Proxy URL": "Youtube-välityspalvelimen verkko-osoite" From 26e95f2a927f90793a99ad2371271beb364d019d Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sat, 17 Jan 2026 18:39:24 +0100 Subject: [PATCH 0029/1854] fix-csv-export (#20688) --- .../chat/Messages/Markdown/MarkdownTokens.svelte | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/components/chat/Messages/Markdown/MarkdownTokens.svelte b/src/lib/components/chat/Messages/Markdown/MarkdownTokens.svelte index bf8ad99931..d22cd2e7dc 100644 --- a/src/lib/components/chat/Messages/Markdown/MarkdownTokens.svelte +++ b/src/lib/components/chat/Messages/Markdown/MarkdownTokens.svelte @@ -53,16 +53,16 @@ const exportTableToCSVHandler = (token, tokenIdx = 0) => { console.log('Exporting table to CSV'); - // Extract header row text and escape for CSV. - const header = token.header.map((headerCell) => `"${headerCell.text.replace(/"/g, '""')}"`); + // Extract header row text, decode HTML entities, and escape for CSV. + const header = token.header.map((headerCell) => `"${decode(headerCell.text).replace(/"/g, '""')}"`); // Create an array for rows that will hold the mapped cell text. const rows = token.rows.map((row) => row.map((cell) => { // Map tokens into a single text const cellContent = cell.tokens.map((token) => token.text).join(''); - // Escape double quotes and wrap the content in double quotes - return `"${cellContent.replace(/"/g, '""')}"`; + // Decode HTML entities and escape double quotes, wrap in double quotes + return `"${decode(cellContent).replace(/"/g, '""')}"`; }) ); From 409f565f09bd554dd211f63c75aba3f2044e714d Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 17 Jan 2026 21:41:48 +0400 Subject: [PATCH 0030/1854] refac --- backend/open_webui/routers/files.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/open_webui/routers/files.py b/backend/open_webui/routers/files.py index e3dd63525a..130d0486bb 100644 --- a/backend/open_webui/routers/files.py +++ b/backend/open_webui/routers/files.py @@ -332,6 +332,8 @@ def upload_file_handler( detail=ERROR_MESSAGES.DEFAULT("Error uploading file"), ) + except HTTPException as e: + raise e except Exception as e: log.exception(e) raise HTTPException( From 716f2986b9da787103668af1c96a9a9303424a6a Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sat, 17 Jan 2026 18:44:32 +0100 Subject: [PATCH 0031/1854] dep bump (#20735) --- backend/requirements-min.txt | 6 +++--- backend/requirements.txt | 24 ++++++++++++------------ pyproject.toml | 24 ++++++++++++------------ 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/backend/requirements-min.txt b/backend/requirements-min.txt index 115d1bc92f..412dae1f3f 100644 --- a/backend/requirements-min.txt +++ b/backend/requirements-min.txt @@ -25,8 +25,8 @@ httpx[socks,http2,zstd,cli,brotli]==0.28.1 starsessions[redis]==2.2.1 sqlalchemy==2.0.45 -alembic==1.17.2 -peewee==3.18.3 +alembic==1.18.1 +peewee==3.19.0 peewee-migrate==1.14.3 pycrdt==0.12.44 @@ -41,7 +41,7 @@ asgiref==3.11.0 mcp==1.25.0 openai -langchain==1.2.0 +langchain==1.2.4 langchain-community==0.4.1 langchain-classic==1.0.1 langchain-text-splitters==1.1.0 diff --git a/backend/requirements.txt b/backend/requirements.txt index 51f0a8a1ae..7fa7d9ee14 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -23,8 +23,8 @@ starsessions[redis]==2.2.1 python-mimeparse==2.0.0 sqlalchemy==2.0.45 -alembic==1.17.2 -peewee==3.18.3 +alembic==1.18.1 +peewee==3.19.0 peewee-migrate==1.14.3 pycrdt==0.12.44 @@ -42,19 +42,19 @@ mcp==1.25.0 openai anthropic -google-genai==1.56.0 +google-genai==1.59.0 -langchain==1.2.0 +langchain==1.2.4 langchain-community==0.4.1 langchain-classic==1.0.1 langchain-text-splitters==1.1.0 fake-useragent==2.2.0 -chromadb==1.4.0 +chromadb==1.4.1 weaviate-client==4.19.2 opensearch-py==3.1.0 -transformers==4.57.3 +transformers==4.57.6 sentence-transformers==5.2.0 accelerate pyarrow==20.0.0 # fix: pin pyarrow version to 20 for rpi compatibility #15897 @@ -62,12 +62,12 @@ einops==0.8.1 ftfy==6.3.1 chardet==5.2.0 -pypdf==6.5.0 +pypdf==6.6.0 fpdf2==2.8.5 pymdown-extensions==10.20 docx2txt==0.9 python-pptx==1.0.2 -unstructured==0.18.24 +unstructured==0.18.27 msoffcrypto-tool==5.4.2 nltk==3.9.2 Markdown==3.10 @@ -98,7 +98,7 @@ ddgs==9.10.0 azure-ai-documentintelligence==1.0.2 azure-identity==1.25.1 -azure-storage-blob==12.27.1 +azure-storage-blob==12.28.0 azure-search-documents==11.6.0 ## Google Drive @@ -107,7 +107,7 @@ google-auth-httplib2 google-auth-oauthlib googleapis-common-protos==1.72.0 -google-cloud-storage==3.7.0 +google-cloud-storage==3.8.0 ## Databases pymongo @@ -115,7 +115,7 @@ psycopg2-binary==2.9.11 pgvector==0.4.2 PyMySQL==1.1.2 -boto3==1.42.21 +boto3==1.42.29 pymilvus==2.6.6 qdrant-client==1.16.2 @@ -138,7 +138,7 @@ pytest-docker~=3.2.5 ldap3==2.9.1 ## Firecrawl -firecrawl-py==4.12.0 +firecrawl-py==4.13.0 ## Trace opentelemetry-api==1.39.1 diff --git a/pyproject.toml b/pyproject.toml index 893e1d018a..b7df0dd78e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,8 +31,8 @@ dependencies = [ "python-mimeparse==2.0.0", "sqlalchemy==2.0.45", - "alembic==1.17.2", - "peewee==3.18.3", + "alembic==1.18.1", + "peewee==3.19.0", "peewee-migrate==1.14.3", "pycrdt==0.12.44", @@ -49,20 +49,20 @@ dependencies = [ "openai", "anthropic", - "google-genai==1.56.0", + "google-genai==1.59.0", - "langchain==1.2.0", + "langchain==1.2.4", "langchain-community==0.4.1", "langchain-classic==1.0.1", "langchain-text-splitters==1.1.0", "fake-useragent==2.2.0", - "chromadb==1.4.0", + "chromadb==1.4.1", "opensearch-py==3.1.0", "PyMySQL==1.1.2", - "boto3==1.42.21", + "boto3==1.42.29", - "transformers==4.57.3", + "transformers==4.57.6", "sentence-transformers==5.2.0", "accelerate", "pyarrow==20.0.0", # fix: pin pyarrow version to 20 for rpi compatibility #15897 @@ -70,12 +70,12 @@ dependencies = [ "ftfy==6.3.1", "chardet==5.2.0", - "pypdf==6.5.0", + "pypdf==6.6.0", "fpdf2==2.8.5", "pymdown-extensions==10.20", "docx2txt==0.9", "python-pptx==1.0.2", - "unstructured==0.18.24", + "unstructured==0.18.27", "msoffcrypto-tool==5.4.2", "nltk==3.9.2", "Markdown==3.10", @@ -110,10 +110,10 @@ dependencies = [ "google-auth-oauthlib", "googleapis-common-protos==1.72.0", - "google-cloud-storage==3.7.0", + "google-cloud-storage==3.8.0", "azure-identity==1.25.1", - "azure-storage-blob==12.27.1", + "azure-storage-blob==12.28.0", "ldap3==2.9.1", ] @@ -156,7 +156,7 @@ all = [ "oracledb==3.4.1", "colbert-ai==0.2.22", - "firecrawl-py==4.12.0", + "firecrawl-py==4.13.0", "azure-search-documents==11.6.0", ] From 9d642f63542cccae6fd7a4c888344dd2773f2f2f Mon Sep 17 00:00:00 2001 From: rohithshenoy <249723738+rohithshenoy@users.noreply.github.com> Date: Sat, 17 Jan 2026 23:18:52 +0530 Subject: [PATCH 0032/1854] Added support for connecting to self hosted weaviate deployments using connect_to_custom replacing connect_to_local, which is better suited for cases where HTTP and GRPC are hosted on different ingresses. (#20620) Co-authored-by: Tim Baek Co-authored-by: joaoback <156559121+joaoback@users.noreply.github.com> Co-authored-by: rohithshenoyg@gmail.com --- backend/open_webui/config.py | 4 ++++ .../open_webui/retrieval/vector/dbs/weaviate.py | 14 +++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index dab5b6cfe8..ed7df33ed2 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -2246,9 +2246,13 @@ ENABLE_QDRANT_MULTITENANCY_MODE = ( QDRANT_COLLECTION_PREFIX = os.environ.get("QDRANT_COLLECTION_PREFIX", "open-webui") WEAVIATE_HTTP_HOST = os.environ.get("WEAVIATE_HTTP_HOST", "") +WEAVIATE_GRPC_HOST = os.environ.get("WEAVIATE_GRPC_HOST", "") WEAVIATE_HTTP_PORT = int(os.environ.get("WEAVIATE_HTTP_PORT", "8080")) WEAVIATE_GRPC_PORT = int(os.environ.get("WEAVIATE_GRPC_PORT", "50051")) WEAVIATE_API_KEY = os.environ.get("WEAVIATE_API_KEY") +WEAVIATE_HTTP_SECURE = os.environ.get("WEAVIATE_HTTP_SECURE", "false").lower() == "true" +WEAVIATE_GRPC_SECURE = os.environ.get("WEAVIATE_GRPC_SECURE", "false").lower() == "true" +WEAVIATE_SKIP_INIT_CHECKS = os.environ.get("WEAVIATE_SKIP_INIT_CHECKS", "false").lower() == "true" # OpenSearch OPENSEARCH_URI = os.environ.get("OPENSEARCH_URI", "https://localhost:9200") diff --git a/backend/open_webui/retrieval/vector/dbs/weaviate.py b/backend/open_webui/retrieval/vector/dbs/weaviate.py index d204e8293a..dcc648c788 100644 --- a/backend/open_webui/retrieval/vector/dbs/weaviate.py +++ b/backend/open_webui/retrieval/vector/dbs/weaviate.py @@ -12,9 +12,13 @@ from open_webui.retrieval.vector.main import ( from open_webui.retrieval.vector.utils import process_metadata from open_webui.config import ( WEAVIATE_HTTP_HOST, + WEAVIATE_GRPC_HOST, WEAVIATE_HTTP_PORT, WEAVIATE_GRPC_PORT, WEAVIATE_API_KEY, + WEAVIATE_HTTP_SECURE, + WEAVIATE_GRPC_SECURE, + WEAVIATE_SKIP_INIT_CHECKS, ) @@ -52,9 +56,13 @@ class WeaviateClient(VectorDBBase): try: # Build connection parameters connection_params = { - "host": WEAVIATE_HTTP_HOST, - "port": WEAVIATE_HTTP_PORT, + "http_host": WEAVIATE_HTTP_HOST, + "http_port": WEAVIATE_HTTP_PORT, + "http_secure": WEAVIATE_HTTP_SECURE, + "grpc_host": WEAVIATE_GRPC_HOST, "grpc_port": WEAVIATE_GRPC_PORT, + "grpc_secure": WEAVIATE_GRPC_SECURE, + "skip_init_checks": WEAVIATE_SKIP_INIT_CHECKS, } # Only add auth_credentials if WEAVIATE_API_KEY exists and is not empty @@ -63,7 +71,7 @@ class WeaviateClient(VectorDBBase): weaviate.classes.init.Auth.api_key(WEAVIATE_API_KEY) ) - self.client = weaviate.connect_to_local(**connection_params) + self.client = weaviate.connect_to_custom(**connection_params) self.client.connect() except Exception as e: raise ConnectionError(f"Failed to connect to Weaviate: {e}") from e From 5cfb7a08cbde5d39aaf4097b849a80da87c30d66 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 17 Jan 2026 21:52:12 +0400 Subject: [PATCH 0033/1854] refac --- backend/open_webui/env.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backend/open_webui/env.py b/backend/open_webui/env.py index ff48a3abfe..aeba69b480 100644 --- a/backend/open_webui/env.py +++ b/backend/open_webui/env.py @@ -673,7 +673,11 @@ WEBSOCKET_SERVER_LOGGING = ( os.environ.get("WEBSOCKET_SERVER_LOGGING", "False").lower() == "true" ) WEBSOCKET_SERVER_ENGINEIO_LOGGING = ( - os.environ.get("WEBSOCKET_SERVER_LOGGING", "False").lower() == "true" + os.environ.get( + "WEBSOCKET_SERVER_ENGINEIO_LOGGING", + os.environ.get("WEBSOCKET_SERVER_LOGGING", "False"), + ).lower() + == "true" ) WEBSOCKET_SERVER_PING_TIMEOUT = os.environ.get("WEBSOCKET_SERVER_PING_TIMEOUT", "20") try: From e9926694c30cdccafe8a3e3c0cb49050af210651 Mon Sep 17 00:00:00 2001 From: G30 <50341825+silentoplayz@users.noreply.github.com> Date: Mon, 19 Jan 2026 04:42:33 -0500 Subject: [PATCH 0034/1854] fix: add username search support to workspace and admin pages (#20780) This fix restores and extends the username/email search functionality across workspace pages that was originally added in PR #14002. The issue was that: 1. The backend search functions for Models and Knowledge only searched `User.name` and `User.email`, but not `User.username` 2. The Functions admin page lacked user search entirely Changes made: Added User.username to backend search conditions for Models and Knowledge pages Added complete user search (name, email, username) to the Functions admin page client-side filter --- backend/open_webui/models/knowledge.py | 3 +++ backend/open_webui/models/models.py | 3 +++ src/lib/components/admin/Functions.svelte | 5 ++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/backend/open_webui/models/knowledge.py b/backend/open_webui/models/knowledge.py index 7f99f828c7..8612842015 100644 --- a/backend/open_webui/models/knowledge.py +++ b/backend/open_webui/models/knowledge.py @@ -229,6 +229,9 @@ class KnowledgeTable: or_( Knowledge.name.ilike(f"%{query_key}%"), Knowledge.description.ilike(f"%{query_key}%"), + User.name.ilike(f"%{query_key}%"), + User.email.ilike(f"%{query_key}%"), + User.username.ilike(f"%{query_key}%"), ) ) diff --git a/backend/open_webui/models/models.py b/backend/open_webui/models/models.py index 5457413f0d..42ae2e8ddc 100755 --- a/backend/open_webui/models/models.py +++ b/backend/open_webui/models/models.py @@ -294,6 +294,9 @@ class ModelsTable: or_( Model.name.ilike(f"%{query_key}%"), Model.base_model_id.ilike(f"%{query_key}%"), + User.name.ilike(f"%{query_key}%"), + User.email.ilike(f"%{query_key}%"), + User.username.ilike(f"%{query_key}%"), ) ) diff --git a/src/lib/components/admin/Functions.svelte b/src/lib/components/admin/Functions.svelte index 67a1fbbdfd..06de4576b2 100644 --- a/src/lib/components/admin/Functions.svelte +++ b/src/lib/components/admin/Functions.svelte @@ -86,7 +86,10 @@ (selectedType !== '' ? f.type === selectedType : true) && (query === '' || f.name.toLowerCase().includes(query.toLowerCase()) || - f.id.toLowerCase().includes(query.toLowerCase())) && + f.id.toLowerCase().includes(query.toLowerCase()) || + (f.user?.name || '').toLowerCase().includes(query.toLowerCase()) || + (f.user?.email || '').toLowerCase().includes(query.toLowerCase()) || + (f.user?.username || '').toLowerCase().includes(query.toLowerCase())) && (viewOption === '' || (viewOption === 'created' && f.user_id === $user?.id) || (viewOption === 'shared' && f.user_id !== $user?.id)) From 7a42efec53e50e102680d8b77d6c23c141182370 Mon Sep 17 00:00:00 2001 From: Toru Suzuki <35589743+zolgear@users.noreply.github.com> Date: Mon, 19 Jan 2026 18:42:58 +0900 Subject: [PATCH 0035/1854] `i18n: Update translation.json (ja-JP)` (#20772) * i18n: Update Japanese translation * i18n: Update Japanese translation --------- Co-authored-by: Tim Baek Co-authored-by: joaoback <156559121+joaoback@users.noreply.github.com> --- src/lib/i18n/locales/ja-JP/translation.json | 168 ++++++++++---------- 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/src/lib/i18n/locales/ja-JP/translation.json b/src/lib/i18n/locales/ja-JP/translation.json index 641c92f282..76f5d9e934 100644 --- a/src/lib/i18n/locales/ja-JP/translation.json +++ b/src/lib/i18n/locales/ja-JP/translation.json @@ -16,9 +16,9 @@ "{{COUNT}} hidden lines": "{{COUNT}} 行が非表示", "{{COUNT}} Replies": "{{COUNT}} 件の返信", "{{COUNT}} Rows": "", - "{{COUNT}} Sources": "", + "{{COUNT}} Sources": "{{COUNT}} 件のソース", "{{COUNT}} words": "{{COUNT}} 語", - "{{LOCALIZED_DATE}} at {{LOCALIZED_TIME}}": "", + "{{LOCALIZED_DATE}} at {{LOCALIZED_TIME}}": "{{LOCALIZED_DATE}} {{LOCALIZED_TIME}}", "{{model}} download has been canceled": "{{model}} のダウンロードがキャンセルされました", "{{NAMES}} reacted with {{REACTION}}": "", "{{user}}'s Chats": "{{user}} のチャット", @@ -32,7 +32,7 @@ "A task model is used when performing tasks such as generating titles for chats and web search queries": "タスクモデルは、チャットやウェブ検索クエリのタイトルの生成などのタスクを実行するときに使用されます", "a user": "ユーザー", "About": "概要", - "Accept Autocomplete Generation\nJump to Prompt Variable": "", + "Accept Autocomplete Generation\nJump to Prompt Variable": "オートコンプリートの提案を受け入れる\nプロンプト変数へ移動", "Access": "アクセス", "Access Control": "アクセス制御", "Accessible to all users": "すべてのユーザーにアクセス可能", @@ -57,7 +57,7 @@ "Add Content": "コンテンツを追加", "Add content here": "ここへコンテンツを追加", "Add Custom Parameter": "カスタムパラメータを追加", - "Add Custom Prompt": "", + "Add Custom Prompt": "カスタムプロンプトを追加", "Add Details": "より詳しく", "Add Files": "ファイルを追加", "Add Member": "", @@ -78,7 +78,7 @@ "Adjusting these settings will apply changes universally to all users.": "これらの設定を変更すると、すべてのユーザーに変更が適用されます。", "admin": "管理者", "Admin": "管理者", - "Admin Contact Email": "", + "Admin Contact Email": "管理者の連絡先メールアドレス", "Admin Panel": "管理者パネル", "Admin Settings": "管理者設定", "Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "管理者は全てのツールにアクセスできます。ユーザーからはワークスペースのモデルごとに割り当てられたツールのみ使用可能です。", @@ -100,13 +100,13 @@ "Allow Chat Share": "チャットの共有を許可", "Allow Chat System Prompt": "チャットシステムプロンプトを許可", "Allow Chat Valves": "チャットバルブを許可", - "Allow Continue Response": "", - "Allow Delete Messages": "", + "Allow Continue Response": "続きの応答を許可", + "Allow Delete Messages": "メッセージの削除を許可", "Allow File Upload": "ファイルのアップロードを許可", "Allow Multiple Models in Chat": "チャットで複数のモデルを許可", "Allow non-local voices": "ローカル以外のボイスを許可", - "Allow Rate Response": "", - "Allow Regenerate Response": "", + "Allow Rate Response": "応答の評価を許可", + "Allow Regenerate Response": "再生成を許可", "Allow Speech to Text": "音声をテキストに変換を許可", "Allow Temporary Chat": "一時的なチャットを許可", "Allow Text to Speech": "テキストを音声に変換を許可", @@ -131,7 +131,7 @@ "and {{COUNT}} more": "および{{COUNT}}件", "and create a new shared link.": "そして、新しい共有リンクを作成します。", "Android": "", - "Anyone": "", + "Anyone": "全員", "API Base URL": "API ベース URL", "API Base URL for Datalab Marker service. Defaults to: https://www.datalab.to/api/v1/marker": "Datalab MarkerサービスのAPIベースURL。デフォルトは https://www.datalab.to/api/v1/marker です", "API Key": "API キー", @@ -164,7 +164,7 @@ "Ask a question": "質問する", "Assistant": "アシスタント", "Async Embedding Processing": "", - "Attach File From Knowledge": "", + "Attach File From Knowledge": "ナレッジからファイルを添付", "Attach Knowledge": "ナレッジを追加", "Attach Notes": "ノートを追加", "Attach Webpage": "ウェブページを追加", @@ -186,7 +186,7 @@ "AUTOMATIC1111 Api Auth String": "AUTOMATIC1111のAuthを入力", "AUTOMATIC1111 Base URL": "AUTOMATIC1111 ベース URL", "AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 ベース URL が必要です。", - "Automatically inject system tools in native function calling mode (e.g., timestamps, memory, chat history, notes, etc.)": "", + "Automatically inject system tools in native function calling mode (e.g., timestamps, memory, chat history, notes, etc.)": "ネイティブの関数呼び出しモードにおいて、システムツール(例: タイムスタンプ、メモリー、チャット履歴、ノートなど)を自動的に注入します", "Available list": "利用可能リスト", "Available Tools": "利用可能ツール", "available users": "利用可能なユーザー", @@ -216,7 +216,7 @@ "Boosting or penalizing specific tokens for constrained responses. Bias values will be clamped between -100 and 100 (inclusive). (Default: none)": "特定のトークンの強調またはペナルティを適用します。バイアス値は-100から100(包括的)にクランプされます。(デフォルト:なし)", "Brave": "", "Brave Search API Key": "Brave Search APIキー", - "Builtin Tools": "", + "Builtin Tools": "組み込みツール", "Bullet List": "箇条書きリスト", "Button ID": "ボタンID", "Button Label": "ボタンラベル", @@ -273,7 +273,7 @@ "Citations": "引用", "Clear memory": "メモリをクリア", "Clear Memory": "メモリをクリア", - "Clear status": "", + "Clear status": "ステータスをクリア", "click here": "ここをクリック", "Click here for filter guides.": "フィルターガイドはこちらをクリックしてください。", "Click here for help.": "ヘルプについてはここをクリックしてください。", @@ -295,7 +295,7 @@ "Close Banner": "バナーを閉じる", "Close Configure Connection Modal": "接続設定モーダルを閉じる", "Close modal": "モーダルを閉じる", - "Close Modal": "", + "Close Modal": "モーダルを閉じる", "Close settings modal": "設定モーダルを閉じる", "Close Sidebar": "サイドバーを閉じる", "cloud": "", @@ -362,8 +362,8 @@ "Copied to clipboard": "クリップボードにコピーしました。", "Copy": "コピー", "Copy Formatted Text": "フォーマットされたテキストをコピー", - "Copy Last Code Block": "", - "Copy Last Response": "", + "Copy Last Code Block": "直前のコードブロックをコピー", + "Copy Last Response": "直前の応答をコピー", "Copy link": "リンクをコピー", "Copy Link": "リンクをコピー", "Copy to clipboard": "クリップボードにコピー", @@ -384,7 +384,7 @@ "Create Model": "", "Create new key": "新しいキーを作成", "Create new secret key": "新しいシークレットキーを作成", - "Create note": "", + "Create note": "ノートを作成", "Create Note": "ノートを作成", "Create your first note by clicking on the plus button below.": "プラスボタンをクリックして最初のノートを作成します。", "Created at": "作成日時", @@ -415,9 +415,9 @@ "Default (SentenceTransformers)": "デフォルト (SentenceTransformers)", "Default action buttons will be used.": "デフォルトのアクションボタンが使用されます", "Default description enabled": "デフォルト説明が有効です", - "Default Features": "", + "Default Features": "デフォルト機能", "Default Filters": "", - "Default Group": "", + "Default Group": "デフォルトグループ", "Default mode works with a wider range of models by calling tools once before execution. Native mode leverages the model's built-in tool-calling capabilities, but requires the model to inherently support this feature.": "デフォルトモードは、実行前にツールを一度呼び出すことで、より広範なモデルで動作します。ネイティブモードは、モデルの組み込みのツール呼び出し機能を活用しますが、モデルがこの機能をサポートしている必要があります。", "Default Model": "デフォルトモデル", "Default model updated": "デフォルトモデルが更新されました", @@ -480,12 +480,12 @@ "Discover, download, and explore model presets": "モデルプリセットを探してダウンロードする", "Discussion channel where access is based on groups and permissions": "", "Display": "表示", - "Display chat title in tab": "", + "Display chat title in tab": "チャットのタイトルをタブに表示", "Display Emoji in Call": "コールで絵文字を表示", "Display Multi-model Responses in Tabs": "複数モデルの応答をタブで表示する", "Display the username instead of You in the Chat": "チャットで「あなた」の代わりにユーザー名を表示", "Displays citations in the response": "応答に引用を表示", - "Displays status updates (e.g., web search progress) in the response": "", + "Displays status updates (e.g., web search progress) in the response": "レスポンスにステータスの更新(例: ウェブ検索の進行状況)を表示します", "Dive into knowledge": "知識に飛び込む", "Do not install functions from sources you do not fully trust.": "信頼できないソースからFunctionをインストールしないでください。", "Do not install tools from sources you do not fully trust.": "信頼できないソースからツールをインストールしないでください。", @@ -521,16 +521,16 @@ "e.g. \"json\" or a JSON schema": "例: \"json\" または JSON スキーマ", "e.g. 60": "", "e.g. A filter to remove profanity from text": "例: テキストから不適切な表現を削除するフィルター", - "e.g. about the Roman Empire": "", - "e.g. alloy, echo, shimmer": "", - "e.g. en": "", + "e.g. about the Roman Empire": "例: ローマ帝国について", + "e.g. alloy, echo, shimmer": "例: alloy, echo, shimmer", + "e.g. en": "例: ja", "e.g. My Filter": "", "e.g. My Tools": "", "e.g. my_filter": "", "e.g. my_tools": "", "e.g. pdf, docx, txt": "", - "e.g. Tell me a fun fact": "", - "e.g. Tell me a fun fact about the Roman Empire": "", + "e.g. Tell me a fun fact": "例: 面白い豆知識を教えて", + "e.g. Tell me a fun fact about the Roman Empire": "例: ローマ帝国についての面白い豆知識を教えて", "e.g. Tools for performing various operations": "e.g. 様々な操作を実行するためのツール", "e.g., 3, 4, 5 (leave blank for default)": "e.g. 3, 4, 5 (空白でデフォルト)", "e.g., audio/wav,audio/mpeg,video/* (leave blank for defaults)": "e.g., audio/wav,audio/mpeg,video/* (空白でデフォルト)", @@ -543,7 +543,7 @@ "Edit Default Permissions": "デフォルトの許可を編集", "Edit Folder": "フォルダを編集", "Edit Image": "", - "Edit Last Message": "", + "Edit Last Message": "直前のメッセージを編集", "Edit Memory": "メモリを編集", "Edit User": "ユーザーを編集", "Edit User Group": "ユーザーグループを編集", @@ -559,7 +559,7 @@ "Embedding Batch Size": "埋め込みモデルバッチサイズ", "Embedding Model": "埋め込みモデル", "Embedding Model Engine": "埋め込みモデルエンジン", - "Enable API Keys": "", + "Enable API Keys": "API キーを有効にする", "Enable autocomplete generation for chat messages": "チャットメッセージの自動補完を有効にする", "Enable Code Execution": "コードの実行を有効にする", "Enable Code Interpreter": "コードインタプリタを有効にする", @@ -786,7 +786,7 @@ "File": "ファイル", "File added successfully.": "ファイル追加が成功しました。", "File content updated successfully.": "ファイルコンテンツ追加が成功しました。", - "File Context": "", + "File Context": "ファイルコンテキスト", "File Mode": "ファイルモード", "File not found.": "ファイルが見つかりません。", "File removed successfully.": "ファイル削除が成功しました。", @@ -804,11 +804,11 @@ "Firecrawl API Key": "Firecrawl APIキー", "Firecrawl Timeout (s)": "", "Floating Quick Actions": "フローティング クイックアクション", - "Focus Chat Input": "", + "Focus Chat Input": "チャット入力欄にフォーカス", "Folder": "フォルダー", "Folder Background Image": "フォルダーの背景画像", "Folder deleted successfully": "フォルダー削除が成功しました。", - "Folder Max File Count": "", + "Folder Max File Count": "フォルダー内の最大ファイル数", "Folder Name": "フォルダ名", "Folder name cannot be empty.": "フォルダー名を入力してください。", "Folder name updated successfully": "フォルダー名の変更に成功しました。", @@ -854,7 +854,7 @@ "General": "一般", "Generate": "生成", "Generate an image": "画像を生成", - "Generate Message Pair": "", + "Generate Message Pair": "メッセージペアを生成", "Generated Image": "", "Generating search query": "検索クエリの生成", "Generating...": "生成中...", @@ -942,7 +942,7 @@ "Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive.": "生成されたテキストからのフィードバックに対するアルゴリズムの応答速度を影響します。低い学習率はより遅い調整をもたらし、高い学習率はアルゴリズムをより反応的にします。", "Info": "情報", "Initials": "イニシャル", - "Inject file content into conversation context": "", + "Inject file content into conversation context": "ファイル内容を会話のコンテキストに挿入する", "Inject the entire content as context for comprehensive processing, this is recommended for complex queries.": "全文を取り込むことで全体を処理します。複雑な問い合わせの場合に推奨されます。", "Input": "入力", "Input Key (e.g. text, unet_name, steps)": "入力キー", @@ -954,9 +954,9 @@ "Install from Github URL": "Github URLからインストール", "Instant Auto-Send After Voice Transcription": "音声文字変換後に自動送信", "Integration": "連携", - "Integrations": "", + "Integrations": "連携", "Interface": "インターフェース", - "Interface Settings Access": "", + "Interface Settings Access": "インターフェース設定へのアクセス", "Invalid file content": "無効なファイル内容", "Invalid file format.": "無効なファイル形式", "Invalid JSON file": "無効なJSONファイル", @@ -988,7 +988,7 @@ "Key": "キー", "Key is required": "キーは必須です", "Keyboard shortcuts": "キーボードショートカット", - "Keyboard Shortcuts": "", + "Keyboard Shortcuts": "キーボードショートカット", "Knowledge": "ナレッジベース", "Knowledge Access": "ナレッジアクセス", "Knowledge Base": "ナレッジベース", @@ -999,7 +999,7 @@ "Knowledge Name": "ナレッジベースの名前", "Knowledge Public Sharing": "ナレッジベースの公開共有", "Knowledge reset successfully.": "ナレッジベースのリセットに成功しました", - "Knowledge Sharing": "", + "Knowledge Sharing": "ナレッジベースの共有", "Knowledge updated successfully": "ナレッジベースのアップデートに成功しました", "Kokoro.js (Browser)": "Kokoro.js (ブラウザ)", "Kokoro.js Dtype": "Kokoro.js Dtype", @@ -1022,7 +1022,7 @@ "Leave empty to include all models from \"{{url}}/api/tags\" endpoint": "空欄にすると \"{{url}}/api/tags\" エンドポイントからすべてのモデルを読み込みます", "Leave empty to include all models from \"{{url}}/models\" endpoint": "空欄にすると \"{{url}}/models\" エンドポイントからすべてのモデルを読み込みます", "Leave empty to include all models or select specific models": "モデルを選択。空欄にするとすべてのモデルを読み込みます", - "Leave empty to use first admin user": "", + "Leave empty to use first admin user": "空欄で最初の管理者ユーザー", "Leave empty to use the default model (voxtral-mini-latest).": "", "Leave empty to use the default prompt, or enter a custom prompt": "カスタムプロンプトを入力。空欄ならデフォルトプロンプト", "Leave model field empty to use the default model.": "モデル欄を空欄にしてデフォルトモデルを使用", @@ -1066,8 +1066,8 @@ "Max Speakers": "最大話者数", "Max Upload Count": "最大アップロード数", "Max Upload Size": "最大アップロードサイズ", - "Maximum number of files allowed per folder.": "", - "Maximum number of files per folder is {{max}}.": "", + "Maximum number of files allowed per folder.": "1 つのフォルダーに保存できるファイルの最大数を指定します。", + "Maximum number of files per folder is {{max}}.": "フォルダー内のファイル数は最大 {{max}} 件までです。", "Maximum of 3 models can be downloaded simultaneously. Please try again later.": "同時にダウンロードできるモデルは最大 3 つです。後でもう一度お試しください。", "May": "5月", "MBR": "", @@ -1075,9 +1075,9 @@ "MCP support is experimental and its specification changes often, which can lead to incompatibilities. OpenAPI specification support is directly maintained by the Open WebUI team, making it the more reliable option for compatibility.": "", "Medium": "中", "Member removed successfully": "", - "Members": "", + "Members": "メンバー", "Members added successfully": "", - "Memories": "", + "Memories": "メモリー", "Memories accessible by LLMs will be shown here.": "LLM がアクセスできるメモリはここに表示されます。", "Memory": "メモリ", "Memory added successfully": "メモリに追加されました。", @@ -1086,7 +1086,7 @@ "Memory updated successfully": "メモリアップデート成功", "Merge Responses": "応答を統合", "Merged Response": "統合された応答", - "Message": "", + "Message": "メッセージ", "Message counts and response timestamps": "", "Message rating should be enabled to use this feature": "この機能を使用するには、メッセージ評価を有効にする必要があります。", "Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "リンクを作成した後で送信したメッセージは共有されません。URL を持つユーザーは共有チャットを閲覧できます。", @@ -1134,7 +1134,7 @@ "Models configuration saved successfully": "モデル設定が正常に保存されました", "Models imported successfully": "", "Models Public Sharing": "モデルの公開共有", - "Models Sharing": "", + "Models Sharing": "モデルの共有", "Mojeek": "", "Mojeek Search API Key": "Mojeek Search APIキー", "More": "もっと見る", @@ -1155,7 +1155,7 @@ "New Note": "新しいノート", "New Password": "新しいパスワード", "New Prompt": "新しいプロンプト", - "New Temporary Chat": "", + "New Temporary Chat": "新しい一時的なチャット", "New Tool": "新しいツール", "New Webhook": "", "new-channel": "新しいチャンネル", @@ -1186,16 +1186,16 @@ "No models selected": "モデルが選択されていません", "No Notes": "ノートがありません", "No notes found": "ノートが見つかりません", - "No one": "", + "No one": "誰もいない", "No pinned messages": "", - "No prompts found": "", + "No prompts found": "プロンプトが見つかりません", "No results": "結果が見つかりません", "No results found": "結果が見つかりません", "No search query generated": "検索クエリは生成されません", "No source available": "使用可能なソースがありません", - "No sources found": "", + "No sources found": "ソースが見つかりません", "No suggestion prompts": "提案プロンプトはありません", - "No tools found": "", + "No tools found": "ツールが見つかりません", "No users were found.": "ユーザーが見つかりません。", "No valves": "バルブがありません", "No valves to update": "更新するバルブがありません", @@ -1209,8 +1209,8 @@ "Note deleted successfully": "ノートが正常に削除されました", "Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "注意:最小スコアを設定した場合、検索は最小スコア以上のスコアを持つドキュメントのみを返します。", "Notes": "ノート", - "Notes Public Sharing": "", - "Notes Sharing": "", + "Notes Public Sharing": "ノートの公開共有", + "Notes Sharing": "ノートの共有", "Notification Sound": "通知音", "Notification Webhook": "通知Webhook", "Notifications": "デスクトップ通知", @@ -1229,12 +1229,12 @@ "Ollama Version": "Ollama バージョン", "On": "オン", "OneDrive": "", - "Only active when \"Paste Large Text as File\" setting is toggled on.": "", - "Only active when the chat input is in focus and an LLM is generating a response.": "", - "Only active when the chat input is in focus.": "", + "Only active when \"Paste Large Text as File\" setting is toggled on.": "\"大きなテキストをファイルとして貼り付ける\"がオンの場合にのみ有効です。", + "Only active when the chat input is in focus and an LLM is generating a response.": "チャット入力欄にフォーカスがあり、LLMが応答を生成しているときのみ有効です。", + "Only active when the chat input is in focus.": "チャット入力欄にフォーカスがあるときのみ有効です。", "Only alphanumeric characters and hyphens are allowed": "英数字とハイフンのみが使用できます", "Only alphanumeric characters and hyphens are allowed in the command string.": "コマンド文字列には英数字とハイフンのみが使用できます。", - "Only can be triggered when the chat input is in focus.": "", + "Only can be triggered when the chat input is in focus.": "チャット入力欄にフォーカスがあるときのみ使用できます。", "Only collections can be edited, create a new knowledge base to edit/add documents.": "コレクションのみ編集できます。新しいナレッジベースを作成してドキュメントを編集/追加してください。", "Only invited users can access": "", "Only markdown files are allowed": "マークダウンファイルのみが許可されています", @@ -1250,7 +1250,7 @@ "Open modal to configure connection": "接続設定のモーダルを開く", "Open Modal To Manage Floating Quick Actions": "フローティング クイックアクションを管理するモーダルを開く", "Open Modal To Manage Image Compression": "", - "Open Settings": "", + "Open Settings": "設定を開く", "Open Sidebar": "サイドバーを開く", "Open User Profile Menu": "ユーザープロフィールメニューを開く", "Open WebUI can use tools provided by any OpenAPI server.": "OpenWebUI は任意のOpenAPI サーバーが提供するツールを使用できます。", @@ -1340,7 +1340,7 @@ "Prefer not to say": "回答しない", "Prefix ID": "Prefix ID", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Prefix ID はモデル ID に接頭辞を追加することで、他の接続との競合を避けるために使用されます - 空の場合は無効にします", - "Prevent File Creation": "", + "Prevent File Creation": "ファイル作成を防止", "Preview": "プレビュー", "Previous 30 days": "過去30日間", "Previous 7 days": "過去7日間", @@ -1356,14 +1356,14 @@ "Prompts": "プロンプト", "Prompts Access": "プロンプトアクセス", "Prompts Public Sharing": "プロンプトの公開共有", - "Prompts Sharing": "", + "Prompts Sharing": "プロンプトの共有", "Provider Type": "", "Public": "公開", "Pull \"{{searchValue}}\" from Ollama.com": "Ollama.com から \"{{searchValue}}\" をプル", "Pull a model from Ollama.com": "Ollama.com からモデルをプル", "Pull Model": "", "Query Generation Prompt": "クエリ生成プロンプト", - "Querying": "", + "Querying": "照会中", "Quick Actions": "クイックアクション", "RAG Template": "RAG テンプレート", "Rating": "評価", @@ -1381,11 +1381,11 @@ "Redirecting you to Open WebUI Community": "OpenWebUI コミュニティにリダイレクトしています", "Reduces the probability of generating nonsense. A higher value (e.g. 100) will give more diverse answers, while a lower value (e.g. 10) will be more conservative.": "無意味な生成の確率を減少させます。高い値(例:100)はより多様な回答を提供し、低い値(例:10)ではより保守的になります。", "Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "あなたのことは「User」としてください(例:「User はスペイン語を学んでいます」)", - "Reference Chats": "", + "Reference Chats": "チャットを参照", "Refused when it shouldn't have": "拒否すべきでないのに拒否した", "Regenerate": "再生成", "Regenerate Menu": "再生成メニュー", - "Regenerate Response": "", + "Regenerate Response": "回答を再生成", "Register Again": "", "Register Client": "", "Registered": "", @@ -1428,9 +1428,9 @@ "RESULT": "結果", "Retrieval": "検索", "Retrieval Query Generation": "検索クエリ生成", - "Retrieved {{count}} sources": "", + "Retrieved {{count}} sources": "{{count}} 件のソースを取得", "Retrieved {{count}} sources_other": "", - "Retrieved 1 source": "", + "Retrieved 1 source": "1 件のソースを取得", "Rich Text Input for Chat": "チャットのリッチテキスト入力", "Role": "ロール", "Rosé Pine": "Rosé Pine", @@ -1474,7 +1474,7 @@ "SearchApi API Key": "SearchApiのAPIKey", "SearchApi Engine": "SearchApiエンジン", "Searched {{count}} sites": "{{count}} サイトを検索しました", - "Searching": "", + "Searching": "検索中", "Searching \"{{searchQuery}}\"": "「{{searchQuery}}」を検索中...", "Searching Knowledge for \"{{searchQuery}}\"": "「{{searchQuery}}」のナレッジを検索中...", "Searching the web": "ウェブを検索中...", @@ -1542,9 +1542,9 @@ "Sets the random number seed to use for generation. Setting this to a specific number will make the model generate the same text for the same prompt.": "生成に用いる乱数シードを設定します。特定の数値を設定すると、同じプロンプトで同じテキストが生成されます。", "Sets the size of the context window used to generate the next token.": "次のトークンを生成する際に使用するコンテキストウィンドウのサイズを設定します。", "Sets the stop sequences to use. When this pattern is encountered, the LLM will stop generating text and return. Multiple stop patterns may be set by specifying multiple separate stop parameters in a modelfile.": "停止シーケンスを設定します。このパターンに達するとLLMはテキスト生成を停止し、結果を返します。複数の停止パターンは、モデルファイル内で複数のstopパラメータを指定することで設定可能です。", - "Setting": "", + "Setting": "設定", "Settings": "設定", - "Settings Permissions": "", + "Settings Permissions": "設定に関する権限", "Settings saved successfully!": "設定が正常に保存されました!", "Share": "共有", "Share Chat": "チャットを共有", @@ -1559,7 +1559,7 @@ "Show Formatting Toolbar": "フォーマットツールバーを表示", "Show image preview": "画像のプレビューを表示", "Show Model": "モデルを表示", - "Show Shortcuts": "", + "Show Shortcuts": "ショートカットを表示", "Show your support!": "サポートを表示", "Showcased creativity": "創造性を披露", "Sign in": "サインイン", @@ -1593,14 +1593,14 @@ "Start of the channel": "チャンネルの開始", "Start Tag": "", "Status": "ステータス", - "Status cleared successfully": "", - "Status updated successfully": "", - "Status Updates": "", + "Status cleared successfully": "正常にステータスをクリアしました", + "Status updated successfully": "正常にステータスを更新しました", + "Status Updates": "ステータス更新", "STDOUT/STDERR": "STDOUT/STDERR", "Steps": "", "Stop": "停止", "Stop Download": "", - "Stop Generating": "", + "Stop Generating": "生成を停止", "Stop Sequence": "ストップシーケンス", "Stream Chat Response": "チャットレスポンスのストリーム", "Stream Delta Chunk Size": "ストリームの差分チャンクサイズ", @@ -1611,7 +1611,7 @@ "STT Model": "STTモデル", "STT Settings": "STT設定", "Stylized PDF Export": "スタイル付きPDFエクスポート", - "Subtitle": "", + "Subtitle": "サブタイトル", "Success": "成功", "Successfully imported {{userCount}} users.": "{{userCount}} 人のユーザが正常にインポートされました。", "Successfully updated.": "正常に更新されました。", @@ -1636,7 +1636,7 @@ "Tags Generation": "タグ生成", "Tags Generation Prompt": "タグ生成プロンプト", "Tail free sampling is used to reduce the impact of less probable tokens from the output. A higher value (e.g., 2.0) will reduce the impact more, while a value of 1.0 disables this setting.": "Tail Free Samplingは、出力中の確率の低いトークンの影響を抑えるための手法です。値が高い(例:2.0)ほど影響を減らし、1.0の場合は無効となります。", - "Talk to Model": "", + "Talk to Model": "モデルに話しかける", "Tap to interrupt": "タップして中断", "Task List": "タスクリスト", "Task Model": "タスクモデル", @@ -1658,7 +1658,7 @@ "The evaluation leaderboard is based on the Elo rating system and is updated in real-time.": "評価リーダーボードはElo評価システムに基づいており、実時間で更新されています。", "The format to return a response in. Format can be json or a JSON schema.": "レスポンスのフォーマット。jsonか、JSONスキーマを指定できます。", "The height in pixels to compress images to. Leave empty for no compression.": "画像の圧縮後のピクセル単位での高さ。空欄で圧縮を無効化します", - "The language of the input audio. Supplying the input language in ISO-639-1 (e.g. en) format will improve accuracy and latency. Leave blank to automatically detect the language.": "入力音声の言語を指定します。ISO-639-1形式(例:en)で指定すると精度や処理速度が向上します。空欄にすると自動言語検出が行われます。", + "The language of the input audio. Supplying the input language in ISO-639-1 (e.g. en) format will improve accuracy and latency. Leave blank to automatically detect the language.": "入力音声の言語を指定します。ISO-639-1形式(例: ja)で指定すると精度や処理速度が向上します。空欄にすると自動言語検出が行われます。", "The LDAP attribute that maps to the mail that users use to sign in.": "ユーザーがサインインに使用するメールのLDAP属性。", "The LDAP attribute that maps to the username that users use to sign in.": "ユーザーがサインインに使用するユーザー名のLDAP属性。", "The leaderboard is currently in beta, and we may adjust the rating calculations as we refine the algorithm.": "リーダーボードは現在ベータ版であり、アルゴリズムを改善する際に評価計算を調整する場合があります。", @@ -1717,8 +1717,8 @@ "To select toolkits here, add them to the \"Tools\" workspace first.": "ここでツールキットを選択するには、まず \"Tools\" ワークスペースに追加してください。", "Toast notifications for new updates": "新しい更新のトースト通知", "Today": "今日", - "Today at {{LOCALIZED_TIME}}": "", - "Toggle Sidebar": "", + "Today at {{LOCALIZED_TIME}}": "今日 {{LOCALIZED_TIME}}", + "Toggle Sidebar": "サイドバーを切り替える", "Toggle whether current connection is active.": "この接続の有効性を切り替える", "Token": "トークン", "Too verbose": "冗長すぎる", @@ -1736,7 +1736,7 @@ "Tools Function Calling Prompt": "ツール関数呼び出しプロンプト", "Tools have a function calling system that allows arbitrary code execution.": "ツールは任意のコード実行を可能にする関数呼び出しシステムを持っています。", "Tools Public Sharing": "ツールの公開共有", - "Tools Sharing": "", + "Tools Sharing": "ツールの共有", "Top": "", "Top K": "トップ K", "Top K Reranker": "トップ K リランカー", @@ -1749,11 +1749,11 @@ "TTS Settings": "TTS 設定", "TTS Voice": "TTSボイス", "Type": "種類", - "Type here...": "", + "Type here...": "ここに入力してください...", "Type Hugging Face Resolve (Download) URL": "Hugging Face Resolve (ダウンロード) URL を入力してください", "Uh-oh! There was an issue with the response.": "レスポンスに問題がありました。", "UI": "", - "UI Scale": "", + "UI Scale": "UIの拡大率", "Unarchive All": "すべてアーカイブ解除", "Unarchive All Archived Chats": "すべてのアーカイブされたチャットをアーカイブ解除", "Unarchive Chat": "チャットをアーカイブ解除", @@ -1771,7 +1771,7 @@ "Update and Copy Link": "リンクの更新とコピー", "Update for the latest features and improvements.": "最新の機能と改善点を更新します。", "Update password": "パスワードを更新", - "Update your status": "", + "Update your status": "ステータスを変更", "Updated": "更新されました", "Updated at": "更新日時", "Updated At": "更新日時", @@ -1805,7 +1805,7 @@ "User location successfully retrieved.": "ユーザーの位置情報が正常に取得されました。", "User menu": "ユーザーメニュー", "User ratings (thumbs up/down)": "", - "User Status": "", + "User Status": "ユーザーステータス", "User Webhooks": "ユーザWebhook", "Username": "ユーザー名", "users": "", @@ -1865,7 +1865,7 @@ "wherever you are": "どこにいても", "Whether to paginate the output. Each page will be separated by a horizontal rule and page number. Defaults to False.": "出力をページ分けするかどうか。各ページは水平線とページ番号で分割されます。デフォルトでは無効", "Whisper (Local)": "Whisper (ローカル)", - "Who can share to this group": "", + "Who can share to this group": "このグループを共有できるユーザー", "Why?": "どうしてですか?", "Widescreen Mode": "ワイドスクリーンモード", "Width": "幅", @@ -1884,7 +1884,7 @@ "Yahoo": "", "Yandex": "", "Yesterday": "昨日", - "Yesterday at {{LOCALIZED_TIME}}": "", + "Yesterday at {{LOCALIZED_TIME}}": "昨日 {{LOCALIZED_TIME}}", "You": "あなた", "You are currently using a trial license. Please contact support to upgrade your license.": "現在、試用ライセンスを使用しています。サポートにお問い合わせください。", "You can only chat with a maximum of {{maxCount}} file(s) at a time.": "同時にチャットに使用できるファイルは最大{{maxCount}}個までです。", From be75bc506adb048ef11b1612c0e3662511c920d0 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Mon, 19 Jan 2026 13:49:12 +0400 Subject: [PATCH 0036/1854] refac --- src/lib/components/admin/Users/UserList.svelte | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lib/components/admin/Users/UserList.svelte b/src/lib/components/admin/Users/UserList.svelte index 97b647ba56..93490be59e 100644 --- a/src/lib/components/admin/Users/UserList.svelte +++ b/src/lib/components/admin/Users/UserList.svelte @@ -97,6 +97,10 @@ } }; + $: if (query) { + page = 1; + } + $: if (query !== null && page !== null && orderBy !== null && direction !== null) { getUserList(); } From 98cb2d3411d3a6f14f479c5013f17fb7a2c4dec3 Mon Sep 17 00:00:00 2001 From: G30 <50341825+silentoplayz@users.noreply.github.com> Date: Mon, 19 Jan 2026 04:58:48 -0500 Subject: [PATCH 0037/1854] feat: Add MATLAB syntax highlighting support for code blocks (#20773) * feat: Add MATLAB syntax highlighting support for code blocks Add MATLAB syntax highlighting support by fixing issues in both CodeEditor (editable) and CodeBlock (read-only) components. Changes: - CodeEditor.svelte: Added 'matlab' alias to CodeMirror's Octave language (MATLAB-compatible syntax) - CodeBlock.svelte: Fixed highlight.js usage to use highlight() directly when language is recognized, falling back to highlightAuto() only for unknown languages * revert: not needed --- src/lib/components/common/CodeEditor.svelte | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/lib/components/common/CodeEditor.svelte b/src/lib/components/common/CodeEditor.svelte index 50c2a7cd18..ef8ed503d5 100644 --- a/src/lib/components/common/CodeEditor.svelte +++ b/src/lib/components/common/CodeEditor.svelte @@ -104,6 +104,12 @@ }) ); + // Add 'matlab' alias to Octave language (MATLAB-compatible syntax) + const octaveLang = languages.find((l) => l.name === 'Octave'); + if (octaveLang && !octaveLang.alias.includes('matlab')) { + octaveLang.alias.push('matlab'); + } + const getLang = async () => { const language = languages.find((l) => l.alias.includes(lang)); return await language?.load(); From 6ae3ddd66bbb260b8f65cc6ab5adc4dfab9fe18a Mon Sep 17 00:00:00 2001 From: G30 <50341825+silentoplayz@users.noreply.github.com> Date: Mon, 19 Jan 2026 04:59:44 -0500 Subject: [PATCH 0038/1854] fix: truncate long model names and IDs in UI (#20696) - Added line-clamp-1 truncation and tooltips to long model names and IDs in the Evaluations and Models admin sections to prevent visual overflow. Model names now display truncated with full name and ID available on hover. --- src/lib/components/admin/Evaluations/Feedbacks.svelte | 10 ++++++---- .../components/admin/Evaluations/Leaderboard.svelte | 4 +++- .../admin/Evaluations/LeaderboardModal.svelte | 9 ++++++--- .../components/admin/Settings/Models/ModelList.svelte | 2 +- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/lib/components/admin/Evaluations/Feedbacks.svelte b/src/lib/components/admin/Evaluations/Feedbacks.svelte index 0ec5678f0e..ccf1735431 100644 --- a/src/lib/components/admin/Evaluations/Feedbacks.svelte +++ b/src/lib/components/admin/Evaluations/Feedbacks.svelte @@ -302,9 +302,11 @@
{#if feedback.data?.sibling_model_ids} -
+ +
{feedback.data?.model_id}
+
@@ -320,11 +322,11 @@
{:else} -
+ +
{feedback.data?.model_id}
+
{/if}
diff --git a/src/lib/components/admin/Evaluations/Leaderboard.svelte b/src/lib/components/admin/Evaluations/Leaderboard.svelte index e16e62c98c..0dd501a153 100644 --- a/src/lib/components/admin/Evaluations/Leaderboard.svelte +++ b/src/lib/components/admin/Evaluations/Leaderboard.svelte @@ -182,7 +182,9 @@ alt={model.name} class="size-5 rounded-full object-cover" /> - {model.name} + + {model.name} +
diff --git a/src/lib/components/admin/Evaluations/LeaderboardModal.svelte b/src/lib/components/admin/Evaluations/LeaderboardModal.svelte index fc3ec6eb10..6730e739d7 100644 --- a/src/lib/components/admin/Evaluations/LeaderboardModal.svelte +++ b/src/lib/components/admin/Evaluations/LeaderboardModal.svelte @@ -4,6 +4,7 @@ import { getModelHistory } from '$lib/apis/evaluations'; import ModelActivityChart from './ModelActivityChart.svelte'; import XMark from '$lib/components/icons/XMark.svelte'; + import Tooltip from '$lib/components/common/Tooltip.svelte'; export let show = false; export let model = null; @@ -60,9 +61,11 @@ {#if model}
-
- {model.name} -
+ +
+ {model.name} +
+
diff --git a/src/lib/components/admin/Settings/Models/ModelList.svelte b/src/lib/components/admin/Settings/Models/ModelList.svelte index cc86e52e5f..d501a485d4 100644 --- a/src/lib/components/admin/Settings/Models/ModelList.svelte +++ b/src/lib/components/admin/Settings/Models/ModelList.svelte @@ -50,7 +50,7 @@
-
+
{#if $models.find((model) => model.id === modelId)} {$models.find((model) => model.id === modelId).name} {:else} From 38bf0b6eec16879bd962c89edcd142c93758ee3b Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Mon, 19 Jan 2026 11:00:48 +0100 Subject: [PATCH 0039/1854] feat: Add new ENV VAR for custom error message on error on signup / password change due to password not meeting requirements (#20650) * add env var for custom auth pw message * Update auth.py * Update auth.py --- backend/open_webui/env.py | 2 ++ backend/open_webui/routers/auths.py | 4 ++++ backend/open_webui/utils/auth.py | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/backend/open_webui/env.py b/backend/open_webui/env.py index aeba69b480..0bbe1b89c4 100644 --- a/backend/open_webui/env.py +++ b/backend/open_webui/env.py @@ -455,6 +455,8 @@ except Exception as e: r"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\w\s]).{8,}$" ) +PASSWORD_VALIDATION_HINT = os.environ.get("PASSWORD_VALIDATION_HINT", "") + BYPASS_MODEL_ACCESS_CONTROL = ( os.environ.get("BYPASS_MODEL_ACCESS_CONTROL", "False").lower() == "true" diff --git a/backend/open_webui/routers/auths.py b/backend/open_webui/routers/auths.py index 30d4ebe4cc..b1e5bdc8ab 100644 --- a/backend/open_webui/routers/auths.py +++ b/backend/open_webui/routers/auths.py @@ -813,6 +813,8 @@ async def signup( } else: raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_USER_ERROR) + except HTTPException: + raise except Exception as err: log.error(f"Signup error: {str(err)}") raise HTTPException(500, detail="An internal error occurred during signup.") @@ -954,6 +956,8 @@ async def add_user( } else: raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_USER_ERROR) + except HTTPException: + raise except Exception as err: log.error(f"Add user error: {str(err)}") raise HTTPException( diff --git a/backend/open_webui/utils/auth.py b/backend/open_webui/utils/auth.py index c1f6910ddb..ef09a6004d 100644 --- a/backend/open_webui/utils/auth.py +++ b/backend/open_webui/utils/auth.py @@ -33,6 +33,7 @@ from open_webui.env import ( ENABLE_PASSWORD_VALIDATION, OFFLINE_MODE, LICENSE_BLOB, + PASSWORD_VALIDATION_HINT, PASSWORD_VALIDATION_REGEX_PATTERN, REDIS_KEY_PREFIX, pk, @@ -173,7 +174,7 @@ def validate_password(password: str) -> bool: if ENABLE_PASSWORD_VALIDATION: if not PASSWORD_VALIDATION_REGEX_PATTERN.match(password): - raise Exception(ERROR_MESSAGES.INVALID_PASSWORD()) + raise Exception(ERROR_MESSAGES.INVALID_PASSWORD(PASSWORD_VALIDATION_HINT)) return True From 85e92fe3b062ae669985c09495f6ff1baf8176ab Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Tue, 20 Jan 2026 16:41:46 +0400 Subject: [PATCH 0040/1854] refac --- src/routes/(app)/workspace/tools/edit/+page.svelte | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/routes/(app)/workspace/tools/edit/+page.svelte b/src/routes/(app)/workspace/tools/edit/+page.svelte index 8714a58c70..036c210d73 100644 --- a/src/routes/(app)/workspace/tools/edit/+page.svelte +++ b/src/routes/(app)/workspace/tools/edit/+page.svelte @@ -62,6 +62,12 @@ return null; }); + if (tool && !tool.write_access) { + toast.error($i18n.t('You do not have permission to edit this tool')); + goto('/workspace/tools'); + return; + } + console.log(tool); } }); From 91faa9fd5a1cfc5d3ab531d2d91d28db52bcc702 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Tue, 20 Jan 2026 16:42:20 +0400 Subject: [PATCH 0041/1854] refac --- src/routes/(app)/workspace/tools/edit/+page.svelte | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/routes/(app)/workspace/tools/edit/+page.svelte b/src/routes/(app)/workspace/tools/edit/+page.svelte index 036c210d73..3584ece2d5 100644 --- a/src/routes/(app)/workspace/tools/edit/+page.svelte +++ b/src/routes/(app)/workspace/tools/edit/+page.svelte @@ -56,19 +56,22 @@ const id = $page.url.searchParams.get('id'); if (id) { - tool = await getToolById(localStorage.token, id).catch((error) => { + const res = await getToolById(localStorage.token, id).catch((error) => { toast.error(`${error}`); goto('/workspace/tools'); return null; }); - if (tool && !tool.write_access) { + if (res && !res.write_access) { toast.error($i18n.t('You do not have permission to edit this tool')); goto('/workspace/tools'); return; } - console.log(tool); + if (res) { + tool = res; + console.log(tool); + } } }); From 4615e8f92bb96471a99e84c117f372d2c083df71 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Tue, 20 Jan 2026 22:28:10 +0400 Subject: [PATCH 0042/1854] refac --- backend/open_webui/routers/chats.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/backend/open_webui/routers/chats.py b/backend/open_webui/routers/chats.py index 9a43234aa6..885360aadd 100644 --- a/backend/open_webui/routers/chats.py +++ b/backend/open_webui/routers/chats.py @@ -357,9 +357,7 @@ def _process_chat_for_export(chat) -> Optional[ChatStatsExport]: return None -def calculate_chat_stats( - user_id, skip=0, limit=10, filter=None, db: Optional[Session] = None -): +def calculate_chat_stats(user_id, skip=0, limit=10, filter=None): if filter is None: filter = {} @@ -368,7 +366,6 @@ def calculate_chat_stats( skip=skip, limit=limit, filter=filter, - db=db, ) chat_stats_export_list = [] @@ -424,7 +421,6 @@ async def export_chat_stats( page: Optional[int] = 1, stream: bool = False, user=Depends(get_verified_user), - db: Session = Depends(get_session), ): # Check if the user has permission to share/export chats if (user.role != "admin") and ( @@ -455,7 +451,7 @@ async def export_chat_stats( skip = (page - 1) * limit chat_stats_export_list, total = await asyncio.to_thread( - calculate_chat_stats, user.id, skip, limit, filter, db=db + calculate_chat_stats, user.id, skip, limit, filter ) return ChatStatsExportList( From ecbdef732bc71a07c21bbb679edb420f26eac181 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Wed, 21 Jan 2026 23:51:36 +0400 Subject: [PATCH 0043/1854] enh: PDF_LOADER_MODE --- backend/open_webui/config.py | 6 +++++ backend/open_webui/main.py | 2 ++ backend/open_webui/retrieval/loaders/main.py | 4 +++- backend/open_webui/routers/retrieval.py | 8 +++++++ .../admin/Settings/Documents.svelte | 24 +++++++++++++++++++ 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index ed7df33ed2..c062977652 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -2809,6 +2809,12 @@ PDF_EXTRACT_IMAGES = PersistentConfig( os.environ.get("PDF_EXTRACT_IMAGES", "False").lower() == "true", ) +PDF_LOADER_MODE = PersistentConfig( + "PDF_LOADER_MODE", + "rag.pdf_loader_mode", + os.environ.get("PDF_LOADER_MODE", "page"), +) + RAG_EMBEDDING_MODEL = PersistentConfig( "RAG_EMBEDDING_MODEL", "rag.embedding_model", diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index 82a87e3fd9..9d1d85060f 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -288,6 +288,7 @@ from open_webui.config import ( ENABLE_MARKDOWN_HEADER_TEXT_SPLITTER, TIKTOKEN_ENCODING_NAME, PDF_EXTRACT_IMAGES, + PDF_LOADER_MODE, YOUTUBE_LOADER_LANGUAGE, YOUTUBE_LOADER_PROXY_URL, # Retrieval (Web Search) @@ -944,6 +945,7 @@ app.state.config.RAG_OLLAMA_BASE_URL = RAG_OLLAMA_BASE_URL app.state.config.RAG_OLLAMA_API_KEY = RAG_OLLAMA_API_KEY app.state.config.PDF_EXTRACT_IMAGES = PDF_EXTRACT_IMAGES +app.state.config.PDF_LOADER_MODE = PDF_LOADER_MODE app.state.config.YOUTUBE_LOADER_LANGUAGE = YOUTUBE_LOADER_LANGUAGE app.state.config.YOUTUBE_LOADER_PROXY_URL = YOUTUBE_LOADER_PROXY_URL diff --git a/backend/open_webui/retrieval/loaders/main.py b/backend/open_webui/retrieval/loaders/main.py index bf7c7286b5..83adb8823f 100644 --- a/backend/open_webui/retrieval/loaders/main.py +++ b/backend/open_webui/retrieval/loaders/main.py @@ -361,7 +361,9 @@ class Loader: else: if file_ext == "pdf": loader = PyPDFLoader( - file_path, extract_images=self.kwargs.get("PDF_EXTRACT_IMAGES") + file_path, + extract_images=self.kwargs.get("PDF_EXTRACT_IMAGES"), + mode=self.kwargs.get("PDF_LOADER_MODE", "page"), ) elif file_ext == "csv": loader = CSVLoader(file_path, autodetect_encoding=True) diff --git a/backend/open_webui/routers/retrieval.py b/backend/open_webui/routers/retrieval.py index 763a9aacc3..318e7bf8ce 100644 --- a/backend/open_webui/routers/retrieval.py +++ b/backend/open_webui/routers/retrieval.py @@ -468,6 +468,7 @@ async def get_rag_config(request: Request, user=Depends(get_admin_user)): # Content extraction settings "CONTENT_EXTRACTION_ENGINE": request.app.state.config.CONTENT_EXTRACTION_ENGINE, "PDF_EXTRACT_IMAGES": request.app.state.config.PDF_EXTRACT_IMAGES, + "PDF_LOADER_MODE": request.app.state.config.PDF_LOADER_MODE, "DATALAB_MARKER_API_KEY": request.app.state.config.DATALAB_MARKER_API_KEY, "DATALAB_MARKER_API_BASE_URL": request.app.state.config.DATALAB_MARKER_API_BASE_URL, "DATALAB_MARKER_ADDITIONAL_CONFIG": request.app.state.config.DATALAB_MARKER_ADDITIONAL_CONFIG, @@ -659,6 +660,7 @@ class ConfigForm(BaseModel): # Content extraction settings CONTENT_EXTRACTION_ENGINE: Optional[str] = None PDF_EXTRACT_IMAGES: Optional[bool] = None + PDF_LOADER_MODE: Optional[str] = None DATALAB_MARKER_API_KEY: Optional[str] = None DATALAB_MARKER_API_BASE_URL: Optional[str] = None @@ -786,6 +788,11 @@ async def update_rag_config( if form_data.PDF_EXTRACT_IMAGES is not None else request.app.state.config.PDF_EXTRACT_IMAGES ) + request.app.state.config.PDF_LOADER_MODE = ( + form_data.PDF_LOADER_MODE + if form_data.PDF_LOADER_MODE is not None + else request.app.state.config.PDF_LOADER_MODE + ) request.app.state.config.DATALAB_MARKER_API_KEY = ( form_data.DATALAB_MARKER_API_KEY if form_data.DATALAB_MARKER_API_KEY is not None @@ -1180,6 +1187,7 @@ async def update_rag_config( # Content extraction settings "CONTENT_EXTRACTION_ENGINE": request.app.state.config.CONTENT_EXTRACTION_ENGINE, "PDF_EXTRACT_IMAGES": request.app.state.config.PDF_EXTRACT_IMAGES, + "PDF_LOADER_MODE": request.app.state.config.PDF_LOADER_MODE, "DATALAB_MARKER_API_KEY": request.app.state.config.DATALAB_MARKER_API_KEY, "DATALAB_MARKER_API_BASE_URL": request.app.state.config.DATALAB_MARKER_API_BASE_URL, "DATALAB_MARKER_ADDITIONAL_CONFIG": request.app.state.config.DATALAB_MARKER_ADDITIONAL_CONFIG, diff --git a/src/lib/components/admin/Settings/Documents.svelte b/src/lib/components/admin/Settings/Documents.svelte index 732d824692..3f4434084b 100644 --- a/src/lib/components/admin/Settings/Documents.svelte +++ b/src/lib/components/admin/Settings/Documents.svelte @@ -362,6 +362,30 @@
+ +
+
+
+ + {$i18n.t('PDF Loader Mode')} + +
+
+ +
+
+
{:else if RAGConfig.CONTENT_EXTRACTION_ENGINE === 'datalab_marker'}
Date: Thu, 22 Jan 2026 03:09:04 +0400 Subject: [PATCH 0044/1854] refac --- backend/open_webui/models/knowledge.py | 29 ++++++++++---------------- 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/backend/open_webui/models/knowledge.py b/backend/open_webui/models/knowledge.py index 8612842015..81aa4099d9 100644 --- a/backend/open_webui/models/knowledge.py +++ b/backend/open_webui/models/knowledge.py @@ -243,7 +243,7 @@ class KnowledgeTable: query = has_permission(db, Knowledge, query, filter) - query = query.order_by(Knowledge.updated_at.desc()) + query = query.order_by(Knowledge.updated_at.desc(), Knowledge.id.asc()) total = query.count() if skip: @@ -303,7 +303,7 @@ class KnowledgeTable: query = query.filter(File.filename.ilike(f"%{q}%")) # Order by file changes - query = query.order_by(File.updated_at.desc()) + query = query.order_by(File.updated_at.desc(), File.id.asc()) # Count before pagination total = query.count() @@ -430,6 +430,9 @@ class KnowledgeTable: .filter(KnowledgeFile.knowledge_id == knowledge_id) ) + # Default sort: updated_at descending + primary_sort = File.updated_at.desc() + if filter: query_key = filter.get("query") if query_key: @@ -443,27 +446,17 @@ class KnowledgeTable: order_by = filter.get("order_by") direction = filter.get("direction") + is_asc = direction == "asc" if order_by == "name": - if direction == "asc": - query = query.order_by(File.filename.asc()) - else: - query = query.order_by(File.filename.desc()) + primary_sort = File.filename.asc() if is_asc else File.filename.desc() elif order_by == "created_at": - if direction == "asc": - query = query.order_by(File.created_at.asc()) - else: - query = query.order_by(File.created_at.desc()) + primary_sort = File.created_at.asc() if is_asc else File.created_at.desc() elif order_by == "updated_at": - if direction == "asc": - query = query.order_by(File.updated_at.asc()) - else: - query = query.order_by(File.updated_at.desc()) - else: - query = query.order_by(File.updated_at.desc()) + primary_sort = File.updated_at.asc() if is_asc else File.updated_at.desc() - else: - query = query.order_by(File.updated_at.desc()) + # Apply sort with secondary key for deterministic pagination + query = query.order_by(primary_sort, File.id.asc()) # Count BEFORE pagination total = query.count() From 8eebc2aea63b7045e61c9689a65a2dfa9c797bcb Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 22 Jan 2026 03:11:33 +0400 Subject: [PATCH 0045/1854] fix: mcp get_discovery_urls --- backend/open_webui/routers/configs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/open_webui/routers/configs.py b/backend/open_webui/routers/configs.py index 152e2c3edc..4dee4488cf 100644 --- a/backend/open_webui/routers/configs.py +++ b/backend/open_webui/routers/configs.py @@ -224,7 +224,7 @@ async def verify_tool_servers_config( try: if form_data.type == "mcp": if form_data.auth_type == "oauth_2.1": - discovery_urls = get_discovery_urls(form_data.url) + discovery_urls = await get_discovery_urls(form_data.url) for discovery_url in discovery_urls: log.debug( f"Trying to fetch OAuth 2.1 discovery document from {discovery_url}" From 8c70453b2e3a6958437d951751e84acbbaafd9aa Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 22 Jan 2026 03:18:38 +0400 Subject: [PATCH 0046/1854] enh: password valve type --- src/lib/components/common/Valves.svelte | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/lib/components/common/Valves.svelte b/src/lib/components/common/Valves.svelte index de1487c64f..cad66c5b7f 100644 --- a/src/lib/components/common/Valves.svelte +++ b/src/lib/components/common/Valves.svelte @@ -4,6 +4,7 @@ const i18n = getContext('i18n'); import Switch from './Switch.svelte'; + import SensitiveInput from './SensitiveInput.svelte'; import MapSelector from './Valves/MapSelector.svelte'; export let valvesSpec = null; @@ -103,7 +104,19 @@ }} /> {:else if valvesSpec.properties[property]?.input ?? null} - {#if valvesSpec.properties[property]?.input?.type === 'color'} + {#if valvesSpec.properties[property]?.input?.type === 'password'} +
+ { + dispatch('change'); + }} + /> +
+ {:else if valvesSpec.properties[property]?.input?.type === 'color'}
Date: Thu, 22 Jan 2026 03:20:59 +0400 Subject: [PATCH 0047/1854] refac/fix: default oauth2.1 mcp tool --- src/lib/components/workspace/Models/ToolsSelector.svelte | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/lib/components/workspace/Models/ToolsSelector.svelte b/src/lib/components/workspace/Models/ToolsSelector.svelte index bbc484f907..d002ac6296 100644 --- a/src/lib/components/workspace/Models/ToolsSelector.svelte +++ b/src/lib/components/workspace/Models/ToolsSelector.svelte @@ -12,7 +12,13 @@ const i18n = getContext('i18n'); onMount(() => { - _tools = tools.reduce((acc, tool) => { + // Filter out OAuth2.1 MCP tools - these cannot be set as model defaults + // because OAuth authentication is per-user and would fail for users + // who haven't completed the OAuth flow. + // The `authenticated` field only exists on OAuth2.1 MCP tools. + const availableTools = tools.filter((tool) => tool.authenticated === undefined); + + _tools = availableTools.reduce((acc, tool) => { acc[tool.id] = { ...tool, selected: selectedToolIds.includes(tool.id) From 4d9a7cc6c0adea54b58046c576250a0c3ae7b512 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 22 Jan 2026 03:25:23 +0400 Subject: [PATCH 0048/1854] refac: fr-FR priority --- src/lib/i18n/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/i18n/index.ts b/src/lib/i18n/index.ts index e5c2d183b2..d7361a5e79 100644 --- a/src/lib/i18n/index.ts +++ b/src/lib/i18n/index.ts @@ -58,6 +58,7 @@ export const initI18n = (defaultLocale?: string | undefined) => { lookupLocalStorage: 'locale' }, fallbackLng: { + fr: ['fr-FR'], default: fallbackDefaultLocale }, ns: 'translation', From 00b3583dc2fe77f7f2223ea2fa2fe4302d4cfdcd Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Thu, 22 Jan 2026 00:36:08 +0100 Subject: [PATCH 0049/1854] fix: fix reindex not working due to unnecessary dupe check (#20857) * Update retrieval.py * Update knowledge.py * Update retrieval.py * Update knowledge.py --- backend/open_webui/routers/retrieval.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/routers/retrieval.py b/backend/open_webui/routers/retrieval.py index 318e7bf8ce..5a3a346ab7 100644 --- a/backend/open_webui/routers/retrieval.py +++ b/backend/open_webui/routers/retrieval.py @@ -1425,8 +1425,16 @@ def save_docs_to_vector_db( if result is not None and result.ids and len(result.ids) > 0: existing_doc_ids = result.ids[0] if existing_doc_ids: - log.info(f"Document with hash {metadata['hash']} already exists") - raise ValueError(ERROR_MESSAGES.DUPLICATE_CONTENT) + # Check if the existing document belongs to the same file + # If same file_id, this is a re-add/reindex - allow it + # If different file_id, this is a duplicate - block it + existing_file_id = None + if result.metadatas and result.metadatas[0]: + existing_file_id = result.metadatas[0][0].get("file_id") + + if existing_file_id != metadata.get("file_id"): + log.info(f"Document with hash {metadata['hash']} already exists") + raise ValueError(ERROR_MESSAGES.DUPLICATE_CONTENT) if split: if request.app.state.config.ENABLE_MARKDOWN_HEADER_TEXT_SPLITTER: From 474427c67e953bb9f7d122757a756a639214e0b2 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 22 Jan 2026 03:55:07 +0400 Subject: [PATCH 0050/1854] enh: dynamic select options valve --- backend/open_webui/routers/functions.py | 11 +- backend/open_webui/routers/tools.py | 11 +- backend/open_webui/utils/plugin.py | 138 ++++++++++++++++++++++++ src/lib/components/common/Valves.svelte | 21 ++++ 4 files changed, 177 insertions(+), 4 deletions(-) diff --git a/backend/open_webui/routers/functions.py b/backend/open_webui/routers/functions.py index ad47318911..a31b958e21 100644 --- a/backend/open_webui/routers/functions.py +++ b/backend/open_webui/routers/functions.py @@ -19,6 +19,7 @@ from open_webui.utils.plugin import ( load_function_module_by_id, replace_imports, get_function_module_from_cache, + resolve_valves_schema_options, ) from open_webui.config import CACHE_DIR from open_webui.constants import ERROR_MESSAGES @@ -446,7 +447,10 @@ async def get_function_valves_spec_by_id( if hasattr(function_module, "Valves"): Valves = function_module.Valves - return Valves.schema() + schema = Valves.schema() + # Resolve dynamic options for select dropdowns + schema = resolve_valves_schema_options(Valves, schema, user) + return schema return None else: raise HTTPException( @@ -546,7 +550,10 @@ async def get_function_user_valves_spec_by_id( if hasattr(function_module, "UserValves"): UserValves = function_module.UserValves - return UserValves.schema() + schema = UserValves.schema() + # Resolve dynamic options for select dropdowns + schema = resolve_valves_schema_options(UserValves, schema, user) + return schema return None else: raise HTTPException( diff --git a/backend/open_webui/routers/tools.py b/backend/open_webui/routers/tools.py index 03018d24a1..7f9b23c7ce 100644 --- a/backend/open_webui/routers/tools.py +++ b/backend/open_webui/routers/tools.py @@ -25,6 +25,7 @@ from open_webui.utils.plugin import ( load_tool_module_by_id, replace_imports, get_tool_module_from_cache, + resolve_valves_schema_options, ) from open_webui.utils.tools import get_tool_specs from open_webui.utils.auth import get_admin_user, get_verified_user @@ -553,7 +554,10 @@ async def get_tools_valves_spec_by_id( if hasattr(tools_module, "Valves"): Valves = tools_module.Valves - return Valves.schema() + schema = Valves.schema() + # Resolve dynamic options for select dropdowns + schema = resolve_valves_schema_options(Valves, schema, user) + return schema return None else: raise HTTPException( @@ -662,7 +666,10 @@ async def get_tools_user_valves_spec_by_id( if hasattr(tools_module, "UserValves"): UserValves = tools_module.UserValves - return UserValves.schema() + schema = UserValves.schema() + # Resolve dynamic options for select dropdowns + schema = resolve_valves_schema_options(UserValves, schema, user) + return schema return None else: raise HTTPException( diff --git a/backend/open_webui/utils/plugin.py b/backend/open_webui/utils/plugin.py index 965b0a688f..79a1c0f0dc 100644 --- a/backend/open_webui/utils/plugin.py +++ b/backend/open_webui/utils/plugin.py @@ -6,6 +6,7 @@ from importlib import util import types import tempfile import logging +from typing import Any from open_webui.env import PIP_OPTIONS, PIP_PACKAGE_INDEX_OPTIONS, OFFLINE_MODE from open_webui.models.functions import Functions @@ -14,6 +15,143 @@ from open_webui.models.tools import Tools log = logging.getLogger(__name__) +def resolve_valves_schema_options( + valves_class: type, schema: dict, user: Any = None +) -> dict: + """ + Resolve dynamic options in a Valves schema. + + For properties with `input.options`, this function handles two cases: + - List: Used directly as dropdown options + - String: Treated as method name, called to get options dynamically + + Usage in Valves: + class UserValves(BaseModel): + # Static options + priority: str = Field( + default="medium", + json_schema_extra={ + "input": { + "type": "select", + "options": ["low", "medium", "high"] + } + } + ) + + # Dynamic options (method name) + model: str = Field( + default="", + json_schema_extra={ + "input": { + "type": "select", + "options": "get_model_options" + } + } + ) + + @classmethod + def get_model_options(cls, __user__=None) -> list[dict]: + return [{"value": "gpt-4", "label": "GPT-4"}] + + Args: + valves_class: The Valves or UserValves Pydantic model class + schema: The JSON schema dict from valves_class.schema() + user: Optional user object passed to methods that accept __user__ + + Returns: + Modified schema dict with resolved options + """ + if not schema or "properties" not in schema: + return schema + + # Make a copy to avoid mutating the original + schema = dict(schema) + schema["properties"] = dict(schema.get("properties", {})) + + for prop_name, prop_schema in list(schema["properties"].items()): + # Get the original field info from the Pydantic model + if not hasattr(valves_class, "model_fields"): + continue + + field_info = valves_class.model_fields.get(prop_name) + if not field_info: + continue + + # Check json_schema_extra for options + json_schema_extra = field_info.json_schema_extra + if not json_schema_extra or not isinstance(json_schema_extra, dict): + continue + + input_config = json_schema_extra.get("input") + if not input_config or not isinstance(input_config, dict): + continue + + options = input_config.get("options") + if options is None: + continue + + resolved_options = None + + # Case 1: options is already a list - use directly + if isinstance(options, list): + resolved_options = options + + # Case 2: options is a string - treat as method name + elif isinstance(options, str) and options: + method = getattr(valves_class, options, None) + if method is None or not callable(method): + log.warning( + f"options '{options}' not found or not callable on {valves_class.__name__}" + ) + continue + + try: + import inspect + + sig = inspect.signature(method) + params = sig.parameters + + # Prepare kwargs based on what the method accepts + kwargs = {} + if "__user__" in params and user is not None: + kwargs["__user__"] = ( + user.model_dump() if hasattr(user, "model_dump") else user + ) + if "user" in params and user is not None: + kwargs["user"] = ( + user.model_dump() if hasattr(user, "model_dump") else user + ) + + resolved_options = method(**kwargs) if kwargs else method() + + # Validate return type + if not isinstance(resolved_options, list): + log.warning( + f"Method '{options}' did not return a list for {prop_name}" + ) + continue + + except Exception as e: + log.warning(f"Failed to resolve options for {prop_name}: {e}") + continue + else: + # Invalid options type - skip + continue + + # Update the schema with resolved options + schema["properties"][prop_name] = dict(prop_schema) + if "input" not in schema["properties"][prop_name]: + schema["properties"][prop_name]["input"] = {"type": "select"} + else: + schema["properties"][prop_name]["input"] = dict( + schema["properties"][prop_name].get("input", {}) + ) + schema["properties"][prop_name]["input"]["options"] = resolved_options + + return schema + + + def extract_frontmatter(content): """ Extract frontmatter as a dictionary from the provided content string. diff --git a/src/lib/components/common/Valves.svelte b/src/lib/components/common/Valves.svelte index cad66c5b7f..4557ab490c 100644 --- a/src/lib/components/common/Valves.svelte +++ b/src/lib/components/common/Valves.svelte @@ -116,6 +116,27 @@ }} />
+ {:else if valvesSpec.properties[property]?.input?.type === 'select' && valvesSpec.properties[property]?.input?.options} + {:else if valvesSpec.properties[property]?.input?.type === 'color'}
From 5d48e48e15b003874cc821d896998a01e87580a0 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 22 Jan 2026 03:59:00 +0400 Subject: [PATCH 0051/1854] fix: ENABLE_PERSISTENT_CONFIG redis issue --- backend/open_webui/config.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index c062977652..e84f1fa519 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -257,7 +257,7 @@ class AppConfig: self._state[key].value = value self._state[key].save() - if self._redis: + if self._redis and ENABLE_PERSISTENT_CONFIG: redis_key = f"{self._redis_key_prefix}:config:{key}" self._redis.set(redis_key, json.dumps(self._state[key].value)) @@ -265,8 +265,8 @@ class AppConfig: if key not in self._state: raise AttributeError(f"Config key '{key}' not found") - # If Redis is available, check for an updated value - if self._redis: + # If Redis is available and persistent config is enabled, check for an updated value + if self._redis and ENABLE_PERSISTENT_CONFIG: redis_key = f"{self._redis_key_prefix}:config:{key}" redis_value = self._redis.get(redis_key) From a3600e8b219fc4c019b95258d16bd3e2827490c6 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 22 Jan 2026 04:12:57 +0400 Subject: [PATCH 0052/1854] refac --- .../chat/MessageInput/InputMenu.svelte | 56 +++++++++---------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/src/lib/components/chat/MessageInput/InputMenu.svelte b/src/lib/components/chat/MessageInput/InputMenu.svelte index 83d6abc5a5..6e2d7724b2 100644 --- a/src/lib/components/chat/MessageInput/InputMenu.svelte +++ b/src/lib/components/chat/MessageInput/InputMenu.svelte @@ -4,7 +4,7 @@ import { fly } from 'svelte/transition'; import { flyAndScale } from '$lib/utils/transitions'; - import { config, user, tools as _tools, mobile, knowledge, chats } from '$lib/stores'; + import { config, user, tools as _tools, mobile, knowledge } from '$lib/stores'; import { getKnowledgeBases } from '$lib/apis/knowledge'; import { createPicker } from '$lib/utils/google-drive-picker'; @@ -269,37 +269,35 @@ - {#if ($chats ?? []).length > 0} - + - - {/if} + +
+ +
+
+ + {#if fileUploadEnabled} {#if $config?.features?.enable_google_drive_integration} From 886c12c5664bc2dd73313330f61c2257169da6d1 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 22 Jan 2026 14:54:00 +0400 Subject: [PATCH 0053/1854] refac --- backend/open_webui/utils/payload.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backend/open_webui/utils/payload.py b/backend/open_webui/utils/payload.py index 458687b371..5094c910ca 100644 --- a/backend/open_webui/utils/payload.py +++ b/backend/open_webui/utils/payload.py @@ -287,7 +287,11 @@ def convert_payload_openai_to_ollama(openai_payload: dict) -> dict: Returns: dict: A modified payload compatible with the Ollama API. """ - openai_payload = copy.deepcopy(openai_payload) + # Shallow copy metadata separately (may contain non-picklable objects) + metadata = openai_payload.get("metadata") + openai_payload = copy.deepcopy({k: v for k, v in openai_payload.items() if k != "metadata"}) + if metadata is not None: + openai_payload["metadata"] = dict(metadata) ollama_payload = {} # Mapping basic model and message details From 1a4bdd2b30017d901b9cac1e2e10684ec1edd062 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 22 Jan 2026 14:59:15 +0400 Subject: [PATCH 0054/1854] refac --- backend/open_webui/tools/builtin.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/backend/open_webui/tools/builtin.py b/backend/open_webui/tools/builtin.py index fcd1d4d233..874a073af8 100644 --- a/backend/open_webui/tools/builtin.py +++ b/backend/open_webui/tools/builtin.py @@ -892,6 +892,7 @@ async def search_chats( end_timestamp: Optional[int] = None, __request__: Request = None, __user__: dict = None, + __chat_id__: str = None, ) -> str: """ Search the user's previous chat conversations by title and message content. @@ -921,6 +922,10 @@ async def search_chats( results = [] for chat in chats: + # Skip the current chat to avoid showing it in search results + if __chat_id__ and chat.id == __chat_id__: + continue + # Apply date filters (updated_at is in seconds) if start_timestamp and chat.updated_at < start_timestamp: continue From 68b2872ed645cffb641fa5a21a784d6e9ea0d72b Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 22 Jan 2026 15:03:31 +0400 Subject: [PATCH 0055/1854] fix/refac: file batch process issue --- backend/open_webui/routers/retrieval.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/open_webui/routers/retrieval.py b/backend/open_webui/routers/retrieval.py index 5a3a346ab7..ce9153c8df 100644 --- a/backend/open_webui/routers/retrieval.py +++ b/backend/open_webui/routers/retrieval.py @@ -2721,7 +2721,7 @@ async def process_files_batch( for file_result in file_results: file_result.status = "failed" file_errors.append( - BatchProcessFilesResult(file_id=file_result.file_id, error=str(e)) + BatchProcessFilesResult(file_id=file_result.file_id, status="failed", error=str(e)) ) return BatchProcessFilesResponse(results=file_results, errors=file_errors) From 14f6747dfc66fb7e942b930650286012121e5262 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 22 Jan 2026 15:07:14 +0400 Subject: [PATCH 0056/1854] refac --- backend/open_webui/utils/middleware.py | 8 ++------ backend/open_webui/utils/tools.py | 4 +--- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index fe2d7e5dc1..48ebddb7ef 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -1808,9 +1808,7 @@ async def process_chat_payload(request, form_data, user, metadata, model): # Inject builtin tools for native function calling based on enabled features and model capability # Check if builtin_tools capability is enabled for this model (defaults to True if not specified) builtin_tools_enabled = ( - model.get("info", {}) - .get("meta", {}) - .get("capabilities", {}) + (model.get("info", {}).get("meta", {}).get("capabilities") or {}) .get("builtin_tools", True) ) if ( @@ -1856,9 +1854,7 @@ async def process_chat_payload(request, form_data, user, metadata, model): # Check if file context extraction is enabled for this model (default True) file_context_enabled = ( - model.get("info", {}) - .get("meta", {}) - .get("capabilities", {}) + (model.get("info", {}).get("meta", {}).get("capabilities") or {}) .get("file_context", True) ) diff --git a/backend/open_webui/utils/tools.py b/backend/open_webui/utils/tools.py index 77f985ebbc..7984878344 100644 --- a/backend/open_webui/utils/tools.py +++ b/backend/open_webui/utils/tools.py @@ -398,9 +398,7 @@ def get_builtin_tools( # Helper to get model capabilities (defaults to True if not specified) def get_model_capability(name: str, default: bool = True) -> bool: return ( - model.get("info", {}) - .get("meta", {}) - .get("capabilities", {}) + (model.get("info", {}).get("meta", {}).get("capabilities") or {}) .get(name, default) ) From 9e5d6069fef751b4a5bdb38583cab7da00aaba11 Mon Sep 17 00:00:00 2001 From: G30 <50341825+silentoplayz@users.noreply.github.com> Date: Thu, 22 Jan 2026 07:07:07 -0500 Subject: [PATCH 0057/1854] feat: Sort Tools and Functions dropdowns alphabetically (#20871) Alphabetically sort Tools and Functions selection dropdowns in Chat Controls sidebar for easier navigation and better user experience. --- src/lib/components/chat/Controls/Valves.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/components/chat/Controls/Valves.svelte b/src/lib/components/chat/Controls/Valves.svelte index 83fda5ff19..a63b0d3b81 100644 --- a/src/lib/components/chat/Controls/Valves.svelte +++ b/src/lib/components/chat/Controls/Valves.svelte @@ -172,7 +172,7 @@ >{$i18n.t('Select a tool')} - {#each $tools.filter((tool) => !tool?.id?.startsWith('server:')) as tool, toolIdx} + {#each $tools.filter((tool) => !tool?.id?.startsWith('server:')).sort((a, b) => (a.name ?? '').localeCompare(b.name ?? '')) as tool, toolIdx} {/each} {:else if tab === 'functions'} @@ -180,7 +180,7 @@ >{$i18n.t('Select a function')} - {#each $functions as func, funcIdx} + {#each $functions.sort((a, b) => (a.name ?? '').localeCompare(b.name ?? '')) as func, funcIdx} {/each} {/if} From 907dba4517903e5646e40223a0edca26a7107bc8 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 22 Jan 2026 18:27:42 +0400 Subject: [PATCH 0058/1854] feat: easter eggs flag --- backend/open_webui/env.py | 2 ++ backend/open_webui/main.py | 2 ++ src/lib/components/chat/Settings/General.svelte | 6 +++--- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/backend/open_webui/env.py b/backend/open_webui/env.py index 0bbe1b89c4..aa296da5b8 100644 --- a/backend/open_webui/env.py +++ b/backend/open_webui/env.py @@ -199,6 +199,8 @@ ENABLE_STAR_SESSIONS_MIDDLEWARE = ( os.environ.get("ENABLE_STAR_SESSIONS_MIDDLEWARE", "False").lower() == "true" ) +ENABLE_EASTER_EGGS = os.environ.get("ENABLE_EASTER_EGGS", "True").lower() == "true" + #################################### # WEBUI_BUILD_HASH #################################### diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index 9d1d85060f..398a666d63 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -491,6 +491,7 @@ from open_webui.env import ( WEBUI_ADMIN_EMAIL, WEBUI_ADMIN_PASSWORD, WEBUI_ADMIN_NAME, + ENABLE_EASTER_EGGS, ) @@ -1932,6 +1933,7 @@ async def get_app_config(request: Request): "enable_websocket": ENABLE_WEBSOCKET_SUPPORT, "enable_version_update_check": ENABLE_VERSION_UPDATE_CHECK, "enable_public_active_users_count": ENABLE_PUBLIC_ACTIVE_USERS_COUNT, + "enable_easter_eggs": ENABLE_EASTER_EGGS, **( { "enable_direct_connections": app.state.config.ENABLE_DIRECT_CONNECTIONS, diff --git a/src/lib/components/chat/Settings/General.svelte b/src/lib/components/chat/Settings/General.svelte index bb8a63eedc..e65683bde6 100644 --- a/src/lib/components/chat/Settings/General.svelte +++ b/src/lib/components/chat/Settings/General.svelte @@ -210,9 +210,9 @@ - - + {#if $config?.features?.enable_easter_eggs} + + {/if}
From c7f996d593e4bb48103b91316204fe7e50e25b35 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 22 Jan 2026 18:30:16 +0400 Subject: [PATCH 0059/1854] refac: AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL for mcp connections --- backend/open_webui/utils/mcp/client.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/backend/open_webui/utils/mcp/client.py b/backend/open_webui/utils/mcp/client.py index 6edfca4f6c..33803648be 100644 --- a/backend/open_webui/utils/mcp/client.py +++ b/backend/open_webui/utils/mcp/client.py @@ -8,6 +8,15 @@ from mcp import ClientSession from mcp.client.auth import OAuthClientProvider, TokenStorage from mcp.client.streamable_http import streamablehttp_client from mcp.shared.auth import OAuthClientInformationFull, OAuthClientMetadata, OAuthToken +import httpx +from mcp.shared._httpx_utils import create_mcp_http_client +from open_webui.env import AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL + + +def create_insecure_httpx_client(headers=None, timeout=None, auth=None): + client = create_mcp_http_client(headers=headers, timeout=timeout, auth=auth) + client.verify = False + return client class MCPClient: @@ -18,7 +27,14 @@ class MCPClient: async def connect(self, url: str, headers: Optional[dict] = None): async with AsyncExitStack() as exit_stack: try: - self._streams_context = streamablehttp_client(url, headers=headers) + if AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL: + self._streams_context = streamablehttp_client(url, headers=headers) + else: + self._streams_context = streamablehttp_client( + url, + headers=headers, + httpx_client_factory=create_insecure_httpx_client, + ) transport = await exit_stack.enter_async_context(self._streams_context) read_stream, write_stream, _ = transport From 0df561c33c105640e7f3f3d7e98033a7b1ebd657 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 22 Jan 2026 18:40:54 +0400 Subject: [PATCH 0060/1854] refac --- src/lib/components/chat/Settings/General.svelte | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lib/components/chat/Settings/General.svelte b/src/lib/components/chat/Settings/General.svelte index e65683bde6..db232a5df4 100644 --- a/src/lib/components/chat/Settings/General.svelte +++ b/src/lib/components/chat/Settings/General.svelte @@ -112,6 +112,10 @@ languages = await getLanguages(); + if (!$config?.features?.enable_easter_eggs) { + languages = languages.filter((l) => l.code !== 'dg-DG'); + } + notificationEnabled = $settings.notificationEnabled ?? false; system = $settings.system ?? ''; From 9af40624c5f0f8f7f640a11356e167543b07b2bb Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 22 Jan 2026 18:58:00 +0400 Subject: [PATCH 0061/1854] refac --- backend/open_webui/routers/retrieval.py | 80 +++++++++++++++---------- 1 file changed, 47 insertions(+), 33 deletions(-) diff --git a/backend/open_webui/routers/retrieval.py b/backend/open_webui/routers/retrieval.py index ce9153c8df..a37fc50b05 100644 --- a/backend/open_webui/routers/retrieval.py +++ b/backend/open_webui/routers/retrieval.py @@ -39,7 +39,7 @@ from langchain_core.documents import Document from open_webui.models.files import FileModel, FileUpdateForm, Files from open_webui.models.knowledge import Knowledges from open_webui.storage.provider import Storage -from open_webui.internal.db import get_session +from open_webui.internal.db import get_session, get_db from sqlalchemy.orm import Session @@ -1431,7 +1431,7 @@ def save_docs_to_vector_db( existing_file_id = None if result.metadatas and result.metadatas[0]: existing_file_id = result.metadatas[0][0].get("file_id") - + if existing_file_id != metadata.get("file_id"): log.info(f"Document with hash {metadata['hash']} already exists") raise ValueError(ERROR_MESSAGES.DUPLICATE_CONTENT) @@ -1602,6 +1602,9 @@ def process_file( ): """ Process a file and save its content to the vector database. + Process a file and save its content to the vector database. + Note: granular session management is used to prevent connection pool exhaustion. + The session is committed before external API calls, and updates use a fresh session. """ if user.role == "admin": file = Files.get_file_by_id(form_data.file_id, db=db) @@ -1763,6 +1766,13 @@ def process_file( } else: try: + # Release the database connection relative to the 'file' object + # to prevent holding the connection during the slow embedding step. + db.expunge(file) + db.commit() + + # External embedding API takes time (5-60s+). + # No DB connection is held here. result = save_docs_to_vector_db( request, docs=docs, @@ -1778,27 +1788,29 @@ def process_file( log.info(f"added {len(docs)} items to collection {collection_name}") if result: - Files.update_file_metadata_by_id( - file.id, - { + # Fresh session for the final update. + with get_db() as session: + Files.update_file_metadata_by_id( + file.id, + { + "collection_name": collection_name, + }, + db=session, + ) + + Files.update_file_data_by_id( + file.id, + {"status": "completed"}, + db=session, + ) + Files.update_file_hash_by_id(file.id, hash, db=session) + + return { + "status": True, "collection_name": collection_name, - }, - db=db, - ) - - Files.update_file_data_by_id( - file.id, - {"status": "completed"}, - db=db, - ) - Files.update_file_hash_by_id(file.id, hash, db=db) - - return { - "status": True, - "collection_name": collection_name, - "filename": file.filename, - "content": text_content, - } + "filename": file.filename, + "content": text_content, + } else: raise Exception("Error saving document to vector database") except Exception as e: @@ -1806,13 +1818,15 @@ def process_file( except Exception as e: log.exception(e) - Files.update_file_data_by_id( - file.id, - {"status": "failed"}, - db=db, - ) - # Clear the hash so the file can be re-uploaded after fixing the issue - Files.update_file_hash_by_id(file.id, None, db=db) + # Fresh session for error status update. + with get_db() as session: + Files.update_file_data_by_id( + file.id, + {"status": "failed"}, + db=session, + ) + # Clear the hash so the file can be re-uploaded after fixing the issue + Files.update_file_hash_by_id(file.id, None, db=session) if "No pandoc was found" in str(e): raise HTTPException( @@ -2709,9 +2723,7 @@ async def process_files_batch( # Update all files with collection name for file_update, file_result in zip(file_updates, file_results): - Files.update_file_by_id( - id=file_result.file_id, form_data=file_update - ) + Files.update_file_by_id(id=file_result.file_id, form_data=file_update) file_result.status = "completed" except Exception as e: @@ -2721,7 +2733,9 @@ async def process_files_batch( for file_result in file_results: file_result.status = "failed" file_errors.append( - BatchProcessFilesResult(file_id=file_result.file_id, status="failed", error=str(e)) + BatchProcessFilesResult( + file_id=file_result.file_id, status="failed", error=str(e) + ) ) return BatchProcessFilesResponse(results=file_results, errors=file_errors) From 5a0488bb183c2e5337762053b0b6d4567497e4ed Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Thu, 22 Jan 2026 17:30:07 +0100 Subject: [PATCH 0062/1854] init (#20881) --- backend/open_webui/utils/task.py | 4 ++++ src/lib/components/channel/MessageInput.svelte | 8 ++++++++ src/lib/components/chat/MessageInput.svelte | 8 ++++++++ src/lib/utils/index.ts | 17 +++++++++-------- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/backend/open_webui/utils/task.py b/backend/open_webui/utils/task.py index ecedd595a7..4acb2c3718 100644 --- a/backend/open_webui/utils/task.py +++ b/backend/open_webui/utils/task.py @@ -69,6 +69,7 @@ def prompt_template(template: str, user: Optional[Any] = None) -> str: USER_VARIABLES = { "name": str(user.get("name")), + "email": str(user.get("email")), "location": str(user_info.get("location")), "bio": str(user.get("bio")), "gender": str(user.get("gender")), @@ -92,6 +93,9 @@ def prompt_template(template: str, user: Optional[Any] = None) -> str: template = template.replace("{{CURRENT_WEEKDAY}}", formatted_weekday) template = template.replace("{{USER_NAME}}", USER_VARIABLES.get("name", "Unknown")) + template = template.replace( + "{{USER_EMAIL}}", USER_VARIABLES.get("email", "Unknown") + ) template = template.replace("{{USER_BIO}}", USER_VARIABLES.get("bio", "Unknown")) template = template.replace( "{{USER_GENDER}}", USER_VARIABLES.get("gender", "Unknown") diff --git a/src/lib/components/channel/MessageInput.svelte b/src/lib/components/channel/MessageInput.svelte index bff703c51f..2b6c2b96ff 100644 --- a/src/lib/components/channel/MessageInput.svelte +++ b/src/lib/components/channel/MessageInput.svelte @@ -147,6 +147,14 @@ text = text.replaceAll('{{USER_NAME}}', name); } + if (text.includes('{{USER_EMAIL}}')) { + const email = sessionUser?.email || ''; + + if (email) { + text = text.replaceAll('{{USER_EMAIL}}', email); + } + } + if (text.includes('{{USER_BIO}}')) { const bio = sessionUser?.bio || ''; diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index d02bda4fa9..103da88f9a 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -221,6 +221,14 @@ text = text.replaceAll('{{USER_NAME}}', name); } + if (text.includes('{{USER_EMAIL}}')) { + const email = sessionUser?.email || ''; + + if (email) { + text = text.replaceAll('{{USER_EMAIL}}', email); + } + } + if (text.includes('{{USER_BIO}}')) { const bio = sessionUser?.bio || ''; diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index 265c47cec2..2ea221ab82 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -357,9 +357,9 @@ export const generateInitialsImage = (name) => { const initials = sanitizedName.length > 0 ? sanitizedName[0] + - (sanitizedName.split(' ').length > 1 - ? sanitizedName[sanitizedName.lastIndexOf(' ') + 1] - : '') + (sanitizedName.split(' ').length > 1 + ? sanitizedName[sanitizedName.lastIndexOf(' ') + 1] + : '') : ''; ctx.fillText(initials.toUpperCase(), canvas.width / 2, canvas.height / 2); @@ -515,10 +515,10 @@ export const compareVersion = (latest, current) => { return current === '0.0.0' ? false : current.localeCompare(latest, undefined, { - numeric: true, - sensitivity: 'case', - caseFirst: 'upper' - }) < 0; + numeric: true, + sensitivity: 'case', + caseFirst: 'upper' + }) < 0; }; export const extractCurlyBraceWords = (text) => { @@ -973,9 +973,10 @@ export const blobToFile = (blob, fileName) => { return file; }; -export const getPromptVariables = (user_name, user_location) => { +export const getPromptVariables = (user_name, user_location, user_email = '') => { return { '{{USER_NAME}}': user_name, + '{{USER_EMAIL}}': user_email || 'Unknown', '{{USER_LOCATION}}': user_location || 'Unknown', '{{CURRENT_DATETIME}}': getCurrentDateTime(), '{{CURRENT_DATE}}': getFormattedDate(), From 4c6f100b5fe2145a3d676b70b5f7c0e7f07cee20 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Fri, 23 Jan 2026 00:56:50 +0400 Subject: [PATCH 0063/1854] refac --- src/lib/utils/index.ts | 52 +++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index 2ea221ab82..96f290a2b7 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -32,6 +32,18 @@ function escapeRegExp(string: string): string { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } +// Replace tokens outside code blocks only +export const replaceOutsideCode = (content: string, replacer: (str: string) => string) => { + return content + .split(/(```[\s\S]*?```|`[\s\S]*?`)/) + .map((segment) => { + return segment.startsWith('```') || segment.startsWith('`') + ? segment + : replacer(segment); + }) + .join(''); +}; + export const replaceTokens = (content, char, user) => { const tokens = [ { regex: /{{char}}/gi, replacement: char }, @@ -47,20 +59,8 @@ export const replaceTokens = (content, char, user) => { } ]; - // Replace tokens outside code blocks only - const processOutsideCodeBlocks = (text, replacementFn) => { - return text - .split(/(```[\s\S]*?```|`[\s\S]*?`)/) - .map((segment) => { - return segment.startsWith('```') || segment.startsWith('`') - ? segment - : replacementFn(segment); - }) - .join(''); - }; - // Apply replacements - content = processOutsideCodeBlocks(content, (segment) => { + content = replaceOutsideCode(content, (segment) => { tokens.forEach(({ regex, replacement }) => { if (replacement !== undefined && replacement !== null) { segment = segment.replace(regex, replacement); @@ -841,19 +841,21 @@ export const cleanText = (content: string) => { }; export const removeDetails = (content, types) => { - for (const type of types) { - content = content.replace( - new RegExp(`]*>.*?<\\/details>`, 'gis'), - '' - ); - } - - return content; + return replaceOutsideCode(content, (segment) => { + for (const type of types) { + segment = segment.replace( + new RegExp(`]*>.*?<\\/details>`, 'gis'), + '' + ); + } + return segment; + }); }; export const removeAllDetails = (content) => { - content = content.replace(/]*>.*?<\/details>/gis, ''); - return content; + return replaceOutsideCode(content, (segment) => { + return segment.replace(/]*>.*?<\/details>/gis, ''); + }); }; export const processDetails = (content) => { @@ -1655,6 +1657,10 @@ export const getCodeBlockContents = (content: string): object => { } }); } else { + // Remove details tags from the content to check if there are any code blocks + // hidden in the details tags (e.g. reasoning, etc.) + content = removeAllDetails(content); + const inlineHtml = content.match(/[\s\S]*?<\/html>/gi); const inlineCss = content.match(/ From 5ac502e93f453ccc0a411488d540bd83bfd3b9c4 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Fri, 27 Feb 2026 17:24:34 -0600 Subject: [PATCH 0614/1854] refac --- src/lib/components/chat/FileNav/FilePreview.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/chat/FileNav/FilePreview.svelte b/src/lib/components/chat/FileNav/FilePreview.svelte index 6aba5da66a..8f7af32b59 100644 --- a/src/lib/components/chat/FileNav/FilePreview.svelte +++ b/src/lib/components/chat/FileNav/FilePreview.svelte @@ -213,7 +213,7 @@ {@html renderedHtml}
{:else if isCsv && !showRaw && csvRows.length > 0} -
+
From ab3f03bbd54acb95196da210adc7fe5d3468f72a Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 28 Feb 2026 00:40:20 -0600 Subject: [PATCH 0615/1854] refac --- .../admin/Settings/Integrations.svelte | 20 ++++++++++++------- .../Integrations/Terminals/Connection.svelte | 2 +- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/lib/components/admin/Settings/Integrations.svelte b/src/lib/components/admin/Settings/Integrations.svelte index 4d7204eb39..7c051709db 100644 --- a/src/lib/components/admin/Settings/Integrations.svelte +++ b/src/lib/components/admin/Settings/Integrations.svelte @@ -87,10 +87,7 @@ }; const addTerminalConnection = (server) => { - terminalConnections = [ - ...terminalConnections, - { ...server, id: server.id ?? uuidv4() } - ]; + terminalConnections = [...terminalConnections, { ...server, id: server.id ?? uuidv4() }]; saveTerminalServers(); }; @@ -246,12 +243,17 @@
-
+
-
+
{connection.name || connection.url || $i18n.t('New Terminal')}
@@ -272,7 +274,11 @@ - + { diff --git a/src/lib/components/chat/Settings/Integrations/Terminals/Connection.svelte b/src/lib/components/chat/Settings/Integrations/Terminals/Connection.svelte index 97e9ac057e..1be15783af 100644 --- a/src/lib/components/chat/Settings/Integrations/Terminals/Connection.svelte +++ b/src/lib/components/chat/Settings/Integrations/Terminals/Connection.svelte @@ -50,7 +50,7 @@ -
+
{connection.name || connection.url || $i18n.t('New Terminal')}
From f5bf2a2ed76148018ccebc862db9bfc8fed43782 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 28 Feb 2026 00:41:10 -0600 Subject: [PATCH 0616/1854] refac --- src/lib/components/chat/FileNav.svelte | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/components/chat/FileNav.svelte b/src/lib/components/chat/FileNav.svelte index 88c0675971..8994b9f2e8 100644 --- a/src/lib/components/chat/FileNav.svelte +++ b/src/lib/components/chat/FileNav.svelte @@ -61,8 +61,8 @@ const getTerminal = (): { url: string; key: string } | null => { const systemTerminal = $selectedTerminalId - ? ($terminalServers ?? []).find((t) => t.id === $selectedTerminalId) ?? null - : $terminalServers?.[0] ?? null; + ? (($terminalServers ?? []).find((t) => t.id === $selectedTerminalId) ?? null) + : ($terminalServers?.[0] ?? null); const userTerminal = ($settings?.terminalServers ?? []).find( (s) => s.url === $selectedTerminalId @@ -421,7 +421,7 @@ {:else if loading}
{:else if error} -
{error}
+
{error}
{:else if entries.length === 0 && !creatingFolder}
From c71beb0a7df1a4e4a3ac7ace757fe67a73e4935a Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 28 Feb 2026 02:05:22 -0600 Subject: [PATCH 0617/1854] refac --- CONTRIBUTOR_LICENSE_AGREEMENT | 6 +- src/lib/components/AddToolServerModal.svelte | 453 ++++++++++--------- 2 files changed, 236 insertions(+), 223 deletions(-) diff --git a/CONTRIBUTOR_LICENSE_AGREEMENT b/CONTRIBUTOR_LICENSE_AGREEMENT index ca9f48b02e..594e1506ac 100644 --- a/CONTRIBUTOR_LICENSE_AGREEMENT +++ b/CONTRIBUTOR_LICENSE_AGREEMENT @@ -1,7 +1,7 @@ -# Open WebUI Contributor License Agreement +# Contributor License Agreement -By submitting my contributions to Open WebUI, I grant Open WebUI full freedom to use my work in any way they choose, under any terms they like, both now and in the future. This approach helps ensure the project remains unified, flexible, and easy to maintain, while empowering Open WebUI to respond quickly to the needs of its users and the wider community. +By submitting my contributions to this repository in any form, I grant Open WebUI Inc. a perpetual, worldwide, irrevocable, royalty-free license, under copyright and patent, to use, modify, distribute, sublicense, and commercialize my work under any terms they choose, both now and in the future. -Taking part in this process means my work can be seamlessly integrated and combined with others, ensuring longevity and adaptability for everyone who benefits from the Open WebUI project. This collaborative approach strengthens the project’s future and helps guarantee that improvements can always be shared and distributed in the most effective way possible. +I represent that my contributions are my original work (or that I have sufficient rights to grant this license) and that I have the authority to enter into this agreement. **_To the fullest extent permitted by law, my contributions are provided on an “as is” basis, with no warranties or guarantees of any kind, and I disclaim any liability for any issues or damages arising from their use or incorporation into the project, regardless of the type of legal claim._** \ No newline at end of file diff --git a/src/lib/components/AddToolServerModal.svelte b/src/lib/components/AddToolServerModal.svelte index aac8f71ee1..db61a58e77 100644 --- a/src/lib/components/AddToolServerModal.svelte +++ b/src/lib/components/AddToolServerModal.svelte @@ -19,7 +19,8 @@ import Tags from './common/Tags.svelte'; import { getToolServerData } from '$lib/apis'; import { verifyToolServerConnection, registerOAuthClient } from '$lib/apis/configs'; - import AccessControl from './workspace/common/AccessControl.svelte'; + import AccessControlModal from '$lib/components/workspace/common/AccessControlModal.svelte'; + import LockClosed from '$lib/components/icons/LockClosed.svelte'; import Spinner from '$lib/components/common/Spinner.svelte'; import XMark from '$lib/components/icons/XMark.svelte'; import Textarea from './common/Textarea.svelte'; @@ -59,6 +60,7 @@ let enable = true; let loading = false; let showAdvanced = false; + let showAccessControlModal = false; const registerOAuthClientHandler = async () => { if (url === '') { @@ -440,30 +442,94 @@ }} >
- {#if !direct} -
-
-
{$i18n.t('Type')}
+
+
+
{$i18n.t('Type')}
-
- -
+
+
- {/if} +
+ +
+
+
+ +
+ +
+ +
+
+ {#if !direct} +
+
+ +
+
+ +
+
+ {/if} +
+ +
+ + +
+ +
+
@@ -521,103 +587,6 @@
- - - {#if showAdvanced} - {#if ['', 'openapi'].includes(type)} -
-
-
-
-
- {$i18n.t('OpenAPI Spec')} -
-
-
- -
-
- -
- -
- {#if spec_type === 'url'} -
- - -
- {:else if spec_type === 'json'} -
- - + +
+ {#if queryError} +
{queryError}
+ {/if} +
+ + {#if queryColumns.length > 0} +
+
+ + + + {#each queryColumns as col} + + {/each} + + + + {#each queryRows as row, i} + + + {#each row as cell} + + {/each} + + {/each} + +
#{col}
{i + 1}{cell}
+
+ {/if} + {:else} + +
+ {#if columns.length > 0} + + + + + {#each columns as col} + + {/each} + + + + {#each rows as row, i} + + + {#each row as cell} + + {/each} + + {/each} + +
#{col}
{page * pageSize + i + 1}{cell}
+ {:else} +
{$i18n.t('No data')}
+ {/if} +
+ + + {#if totalPages > 1} +
+ + {page + 1} / {totalPages} ({totalRows.toLocaleString()} rows) + +
+ {/if} + {/if} + {/if} +
+ + diff --git a/static/sql.js/sql-wasm.wasm b/static/sql.js/sql-wasm.wasm new file mode 100755 index 0000000000000000000000000000000000000000..b32b66473d5a3947a89eaa0cd54caef9e0cda9ef GIT binary patch literal 659730 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%0AUur`umG`g>}HDGtk^` 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
tD`saR49Z|p;*n+SI zToVWF>V9ctd{=RXYJsf8*5>;I5Dc^)poy(&Aa$`!(B|vPuHTwwe7F$#k_dY~q&&Qt zV>+Mw?CDSOZ2x)B)R|BqNrLyqYN7KpnJii+-mP6 zSb7I8!ns#@WV)^@g9L=i*R7AGbt8Xe(9~=aSHwqF(GGTCCUv$tmxG?Q(aeT7Te`ky z@PjhH)$#Af#+*=q4L|%!xi~Kz`ygjutPJ{`hmm=BG6sAShWw3cO&)hVYj7o>?Zg~ zUy}rsOpKtCv0Ns4UO)Wb5>-6$l$4yKqk)N`@FVuCt~@nimH{i)Oh2cr;4nWxmZ}&F z1!PlEq1LXhyXv}b+qe=nK%GI$nuD=os%}*BLDswixEyL{e)|J)ws|MtxZ(Gy3D)xX zMeejz9l4nWj`F4!=Cwm^r$&JmepmP3O7;{tRn6BUIfIa*t0wh=lo)_%Zqn}N4R&^f z^{A4104A+Z>ULl7>AIf$1eP;k-`Ng06`MIyDGs(f?Ncb9E5xV<3cqGZeqLlVf5w^E z6mP{XIOm<_fodxKKD}7G$>>EP4$l#vp-yIJhQ}ppHY+*Q8$|nw8TS+kp#zjXi10hf z2WetPjxVh}O(r1YG0W4KMtYQ$+MZR2eOb0Y7wB>zLh%yH%uXiR>NAL|^&^8Ehv`~; zIc5)GX}!CHS^SxLDT16Peda$|Go;7+cU5b#=c%*CRLww+d?!W8&VX?vPg;LOy>0F0y(J;oGV}mC>Lo>q)<`W z$;F8d_2IV79E|ujB|)s%7t4t~Ayuz`_}(L!Y{C-AInxUw`Qam`uJ)OXO5~K2Bn3)B zN?c;C%Sl`~K%?*J3}gBXq&m)NKzl34=3)7eoYx zABK$R6Ea*6ai=$6kPVqEH~`DSn0+2>u;4&eIH~R-p{Hno!_m&+P|KldT>5avG92t3 zWoCvM3K7FMOaUJHny*z)JYbF0v+NY4q`Jcz!!!Yl$9Za!U~U-!y+WIzV$#2&=OH>X zh8v*@%XX8>8fDoh_hj0s5~vDyIy%TPtVw`|aH}c%jOyT7&KrfcrhH5&*bXL;k^R8B zmUygYiI9=QQ(_&vD z#m8GbOrwxh`M7wD61EQ-x$%c9WLlCy9AQF3NsfUg zhbeE8!Bm>%_;_ouJcJEjYFN&UG8x>kug5A{D{5O^88h2!b~kF-yIPx5Ef`4c12a3R zq#OrU0V{DNNjjzCwIUBuE7^vWnegUXBw~G{cYLBjUHNIxipe|Ho!iXi&iZ$U;&SFa zOO$g^y_5X}4IL`|5`Y+_W-keRAZ?l8ql1H#f-);Q{FJ$%T3aazW08-UCd@F$z6h(9 z#qn17_pMa&X-Eu)2aWtDiHCaqAt`OeaiSnrkfzO`+7)XBK$nrucJJ0O+Z?m?Jbz+l zK6bN8>;id(UCWjk+6fEQ0nKXOxXOMv0t-XnE<+$kcK==kdcu*A7u}#QvV4v0Hs*%T zieHC@-`|U$8o#osb13559$L4Wp$=|laW_OHg^w5;N8N`Wn9<@;G`{pf>SvsoGg&2; z5&f^@>npZypX+z{YYSPW0F*t~<_8^q+NFjbbPfMy9m9bSvwx&{OsHjpCCHcpnWCBmF1?JR+^0-bbtv3*%a*86c6; z3f`w~Lxz5YnjBysGT}|w-5Sb-l}(kPm8;jVx5)E6_`MPOTpAdo{KF2R_EIP+Mh{SJ zMpGwSV2ay@QcQ_GV2;{wYu0=g_kMqmGp70f z!T61a9hi$^lnSN&u+a7(@Mc~<-D2!V#gAy#J2irK1@@wQiPd)`P zI=@W}?Z<&SodGcnA@Y-E31hyzb`QDYQQ1f>kikFEjGpG+nHU$oY+EFWj^e$DDq799 zxM=>?LO#5X%FkX7mNbWxfNvjr3hdlvWW-pfxGL_m8;#i_sYYhr%mz43DRTgZLRJ*0 z?Z}HJX~X9%$d1bj#}SRn6H;)-1QFWXKDlYTTE z5HxKOM!7&AEf%v{|IU_k6nENQBTUCC2BBv_0S3u^6lDqkz^oH~EN5S$TJbdH?`wl9 zUW-to=0KbG?8}y=+ZUl%0p7L|L44mWnFIoQ758~}u%#Vpr0&h<()gv&w1r7a;f<9n zxo-3`^4Q8#G5{7l%O{|`cJX`ek4)5IJLN0lsPf=DuGZ<)~KTHiIJ+#2a-fjC&^*&op&1)D6{$L8#v z?^2GaMRtz;w%erH;BrL35cq3vm3%5q4V!ymT5X5dY8QS%CT53ewJzQnh*3g%6AhDz zTmmvoP>_-8(#rtQEYSk0XknUsR>DI(DXUZG=@(i?d*0+F?VV9BnG-uONf|oR1eB0s zJq3r5>NvY!roN{U#;agq>pNW-l!DzK>AyqiJ{?3`HLlRr4)Urw36;&HK%gw61f^=D%jy zg1xqh&@Or07cI4oc(#2JI9t7@+Eb^p{Vhw5D88Ak#;P7)52dFihaxYIh)^;+Nb6FA zw3X++xGy*eA~c)vJ7{Wa8GLtUuXH)DC6<$t+LxOExffMi6q@T$Y44Eh?_IJhxz_IR z2I%@>WhoS6oKTFTECcQ%rlHHspcJ>Qyy$9|s0q3q=Ig3IVgOpYioIDN{}b_-)E6ew z>>)KRKpqL}X2wlRW9v^E*cT-M<^qcmkQK%0wp7&woTmM%SV`-VETYs|v8Wj5k1>&t zsD%I)bc5LfYU5$Uzqap-IxG8{q@mnOEf*~2u0yEC9Yw}uV5{wHOJSJ7<}F0fqNIOB zElRdADSiC46kW5|ZSHGf5%RR3cmQonX95a+d#Jf~Rlrw{InAzaP(5R^PUzbf2sCfK zYg48SXQHPbfYA0VY6KqIGJ;)(JxEy)d2q=%)SJ*qEwDY25%9>iG-?wX56iyHuRM8l zI&-}IFw0(!&~8%qtO2q`jb4@L008Er?R9$e*^*C)9 z@Duyq%%_rTEic#37h1^)4tOIL1bTyGF#(&8rF)AzWX1U`ql_5IL>VN$oNJp@Sbs<@ zh-GKE__Gp#))0Ul;^mnTiJyWpHcJIU?CWme9Q>E4&X2MYSfDB+qF;qlgR_Zrugrxt4OTz*;m!eb0pe&L~58{7+}v^!F(L$jiRncWj5~)In51Ae@NoPpG+hQWnBVK*nVa>;Bc1t(8d`203RsOXq0S((V18E+>OjLf!03I(Ea|i**B&qR=hnW%C;)YF9H+RYzYP!==Qe`MpdejHRL=UegCi`0g4# zwUJ+)w`ox&Ye01>A1f|$w1;V(^OccHp2Jaduu-rgUNfAtm{;MrBQwA(UE`e2SEl|7swgJF^4qitSQiG)dao`ltn))S{ls zrPk3MgTw8ZM8ien#U!K(s~>A-s;De9W^)qH+##?ee4;WacO^#cP-GpM78NKa;%D(m z%4vmKoxgVQd0d!H=}fqb!`A6o1J%K+Bf_DbKYP5Ln6FB%AFfkFx{7o#cm$dzobr6U z4S1X3T?+Go8kz1nO6w~js6j4fl0`HwV2gK9Kx>Cxu_D14<#T+Xi`hYNGWagv4z*?@ z+~GeS$p=ZfB?f()jw|GhY<6KL&lj=y&x7aBxwjh*Wg=c91Y{P7Gx`;(0osS~i9?JV zf-iL{80wvIkdzOVx{4#dst?@fioJ2Q$PRorRXQL$-#x}NQW8R&ZMbH)yauFp>O=U& zlMib56b;Ru!7oGLl0N_+KKrL(O!{e>PA+!+f)@2LQ$StQe`@^tndyW}PhR4v8+o%$`ECdij19#k=C&Epb+H zo@OgUzOV~q?`R|o?4xj8-yRl!#Otqx^?99B>?}G7N((ezKhr+b8KMkGqJ~qiX7Xk? z*9=4SWZF&Ihi}j%iBoyL3RN7>x5q+ivs6PLZnKs!7@pe2N1918?IqAsv97w3&^m(C z;9loHpK1fQr4a#O7|&a#gAOR8d~_gfqW*XwJ#JZ3eN0j`u~6Pw>LmGD5HxfqXvxPw z#{`zx&sal5UBZVge({6HIZv<_4^5iVyN;d+nP#>T${EmEm)tS$hpoB|ePo=$L^v~e z0{lLMgvI{k_3nd+vL5&$*TjfhsHKJaa4SdD1FcW>))g@Iy0T$-fQWzxnqK20F}veD znZJSjRva3GQmd!@PjO~h*OQ0R& zBgtys8VOu98A3H9g6B)B8=H&L&b|dGn{woC$bm7y*ebfx@p_-UT{zYOg*WJ*|1|aQ@Y7{ynxnI zWS&%yKM@W70Wf1alMV6LM=WF1_>R-hxtlq0lqb@3$#Gt07^=RRyudG8peTpc0ci34 zfT&I{O)YYkVSwVm97tpH+cu3d!8d4JvNsJg&M4MFxk|d5RKS=H)S&E3{lHS3PXR$> z&EX*OCb*)9qwta0 zpTcDy6gR98OVl*)*M%vCwfMY$KUy$vNzMayJCsB2_pyD_AD~X%q>?KEJE(rR= zr*Jj=0y5zQ4`7uVl~jsRuwR!jr*J z3|ivJXp;VFw$OkSI2&FWvkm>Xk*N?IfvLyjeM0K##2q8YFu=4R{QxGbHgO1 zGSlyprwm2rIqcR5Wpf}>Cd0~_64_t-(cA%6v;~;k&Jtajq{SHVhn=ZAwU<_t226s? z=n$zn4A0>yi z_p%B13(Sb=MjT(YAN!zz(48TGQYD1=V@z6-lrJ7;*^6E>r@oAKjI)M{Uv$iCCTK+A zmV9W_WR?&kFzMCI`i7*>=_)1D<`Q20P~v&FQIXO z07$^S7B%Gt=E*zSE^UbX+wDlp{+@QcqOf-GPB0B6N=`pYRWNbMncVA4XTr^NFRKoD z*cNI*SM}N@B0~KXxQg>c)K;M{3J5u9f@8~IGheToF^d;YR*%@3>$XsUQzc6OO>kNU z@ZyBJj+;vL>1$g|VCv*jIV}tuBg{NER?G)Ym~ni$+J%-A%a_Q|vMEIcmcFf={948z z^Qcc{CAe1VXzDh(#a&Vguwi#p#y~Cr4ks@w9oWga#ev=7KwPdJiOV42>p%=DQSP%= z#}b7}sZi%ki4ZWI$;)j=;6c-%{7a}#?!NT?xBBI{HN~AgUkzfcrAZ3IOB`gPc2{wS z*U2d>`h?bUen<<9^TWu;_))xJaP@_B4U&gS|HRW9_{bW(j!sG#th~r>vfrE+i9^BX zQ5nuvNwSg0-i?lhk;*dXv4BN(1O}-U`OOj`bDMF1HCVhc$+F1=q*HVXv*UUD**!G3 zcVC0#;@ErYM9_^f7Ya_fzwDDdp9~t(V{x$m5*di;@lqzONlD(umYTPqMEXpXAvnUs zfCJ$G6A0QJ^(khLGIQD-JNP0Me)$(Wcs^Z?&Nd5)Nz_J5$)ii8+t5j24p*+wg*J z-I?@g=_!xPw2vP_J=KtY7$r_R4@%Xafr*p#c$%;pd|<4manc%$g1*Ox8hn}E4n?)| z1}z*cE=CAIgcL6v8YO&7&BsG1KBHluuhMj;nd}7)|3vr2C6;Fvvxz_7A6THH0kSv% zmL|#xtAwdwSXpGSunARc^d|pMzd6bQA+GXn``BD%vv2x*M>P9hnVOJKp$$sj?n`Rg zS#OSV5*A+oQ^Hk2QD14vY^A-v5}uv7(lm&;$CFq?P$Uc=Vwr^cQfsN|&q*W)ng@@L zJEKl}U8{r+WoBs|%=-)j(J~0(yE~d5-NS$d+jMnSah3G-9XudI#UwLuO67kd_8&g+ z5n*v!WuNPjk!j%?wN{0%XiROt?B{n8bKwo>zcQS1FHqV>X)T*Z!aF-JCK-sPJcVf- zEZVix3MP>B3Fnxn!kd~3w+_}t(6ihZ^5cw=7M_oThqP%K7R-0dF6NrlobVgzo9JrR z67fjabY&rETs0*9te5g%{DFqUF-+u&(}cf~Y5`w5s20@0E$7^*w3{lYf+=M-Sx_|v zmKeuq+1`q5hEwIKqt_N!M>t90wX#Nm+R;Kd3rPiwPmY;-f?2J9Xkbd(`UIA@piq`r zS?TgI+10Yzz8jY0pfv65FB|&CBHpS0I#T;u`-V%4To|$jYFYPn9CQtj)81nNpoP6b z4=6xnUwhUz@cK9S6Bw~b7u@oY=%I?JoPbI9|B?6Z;g(g^f$w_keO`N?s#R1$9XJK7 zy{*V8>J(Kf7A2H&)@dGvfD)TF?=OAxr91RFn42mH+DSnjp+w?MkQh6y2}vqm4JNS? zOiYJ18ViL;qRB@(kG7*G=!d!X{k$DJ!M>(Hl>7UQx%NJ%08KjoUW%%{9&^n(=9uF( z#~gFa>LZ2V`#pgtA^+es5fByf9gf^QS$xq+3nsB1MdHJ_x0V)Sr>M$MZhL2s)mhoWXQ^ZQzrT5hQSPIWbXd*=6Axm zh{J#ffU~#3DZ+pSXkN{5S|4H1auO@am|kXdVR*L03<`SeY#ChO{@H290<|fd8g-?joG>~Bmr@c6F|vGTJt@Ib-g zVyiuw3*t8iFbtYbEpVwpyPynizXl}hkAxE6pr%#U6~ho_fFO@9M5UutLQs_lQV%2w ziJb^RO~D<(7Td*E-d(Z1?MIyUSx zINFfps)KRTPVP=~Pqfg9?G|`+`BE|DEe$Uj80vBlVZY+!?b$0HUA<{^4VEJc~S;U0u$zjEYr6wSP_5SRDJgGICE){$rRlVI|qlHji zd@;FFysU2HcABAZg|xI_@H4 zQAChMdaX^QwgFb_nr1z!G^%QZCXR*H1YKI)8M8jNWR1uRH9V39v756Fl&Oam2q5zB zV>hmPdBEar@WoImqklh+?V4d`Dwc4vD{8>U6ozmlpNjm}Caf{;yXQ&g|B z0u1cP&y6V^(bpw38)4dX0(axXuS^1x3IFIgxO5iWL}dDsOxnEIb}`ly?hUU9Jz}yF z)_U~b8_apmCF1c)f5E#%j2kr<}ZqnTo*mWCN1%Cd{ZK;&u{SD4VTBXowh zA9>~(({?W)mlFzCNt}S8xi?>^zKZulTn`~^X5h%vDdd(}pRfwuSfhw#9ti4DkJ#Rr zJ(uMtaI9k?KaE4kNEU2IDbW*2JIT$(j)xe1iYp1(zXvKwAT5dT>^OT(YV3E`=oX4M z5M>ABGz!(JVhOaeAi>};WV}6!F5>gZj990TPe&!JP$J9sWW)j-!B==`Hl>2X#zYwe z)Cqu8he?kRH}9+dv>c*2s1$rffj0~@KG|QqfmX9<345h=5>O|F^q%meVt0VRu%!VF z_Zxn?`_|8|<$&eTp6%E{Ru|CK5M(e>7jp$mb zL~>iiMuZ_aG7y#tXJFo`>eF33FwAzjS;TZEws>CjY2 zBak2c6r>ES%=da1*&vaPc`0i_Zq&!uaaDs-U(dCM152)NEXIzgv`DI*YoU<1&4cgn zR2Pm|!n&l3y!yR-D6u*bmQp{HZ<*i~u(ACxm8NZ!9?PVlmhtyh^WhDZX+FB)J>N0tEWq$_U4%yhLa$z8Bo3TLJJt8-2ml(Oh2nKBQBqGdcj1DC2clz)pu1moc@*Qb`rXbT)}qGj;U}AlEQhc(b5hL^^@duh3u5H~ z7lc{`p6Ppte!e-_9Kc6Wg9@@Hp+#)WqI?5C#o))6xC8S?FurV~n*w%WLytq+8C~aYv5tu|a#a-@^uCWlEmQ);(<%)S($UxUZM9p;8YLHr ziSw%Z4Bo6@6#{SLqCdK*h%vVWaY3J+E~jyxpACM`hQyO{@Hcg(L<`8tQOKnMGG&7oq}h$zqUVY7pd<}Fl~5b|BLFrG z1W6sI_@%4OZSI<2y-5WPIDArfPJXnWU7oq)=<>eXhqKG?_|3omf}k!8HToKJor`cwXy?5K@+8==jB)#MUYKDi%q3wl>_v zi`R@wQc=Ar6+;8hesH+?WhKJ47(>7u@(NDN<-foAXa5T7C&u*Y$sq|8J#Tro-gNs1 zWi#$?|KQK`URGjk*%%JQX!XgA#euk*8C~E_!p3U*wR36Q!Ro(2-~qa*!0PZ#{k|7P|doZ~vB)*ZjtfS3LEi%YO7zPhI@Ssh%gZajDe*`;U!ax@~m98o$l_ z%sc(>KVIHme8-1cNLn_u$nSjkKmV7%I{N9CU$OWTfAz0!oH_ErRK#Iehh$&(-X|}5 zX7}zZ9=Yn=H{5jL2ObzfGA@ODtS5Gh-`(ZZiQ(q9V_!bTq;T{9HlJ|MI2$6iS!`mV zOxFE;(1a@2*>I+C&N$~(=aYMPM1aNxKYz;g1glo1&kbwH+gkC z`0L#~?shjC+LL{+e8#v~zX9<7J-aHYl?MS26+8A2$gkkjQWU-@--&0Es@uo-2~his zfRl_~9b7-|d0B%|Pp2iwNun#?$p+1gF*F>?(G?}S!T08;KFdr5 zba?;NUm=NE*kH05&Uw@lDa2WPb{+yy_L7Y`&O>5dS#&@4Xol5&r+gRzkXi4Zyj|f! zXSbG}C@>BvY#-FV=tb3vvgPVVv#RC?mCFMm+PiXP%*I+S{;LOfOkCY~K4;t>G;> z?%A+FS;_h8y*{FrqIuuLUgCuGN+QkFcW8gs_K^ulfNW4SUq01&sWy1?(8maW!CXE$ zoVfj;^YT>O4=0zyzk4jf`>#{kKTE{3z47Cnls@AFX*vWN_VwSxfTS=tCQ7l z=P}y<6JH9H7O@vDU6;-64hS1s+ZSNJ;gC}AhbaudOyR3}fb*>~J&5lYnRz1z-NnDLFw@2 z6ufNKD70RB)2*DgV)3#q4pfA6{S>$4&W~8P?gMNpS>wOzJLd;ZgH!A`(-)>FM4ms` zFQx&|Ix83A1g56*?80=2$Y_My1afDHlum%0dwNnhXiN>6uG-a3W(h+YKvZBDuMDy> zDl^E~vBMMwdwVj+jVr<#X-OM6tzEUuA|=P|-|-OUQlgCH?FIH%_Ei zV>5(9h)-h?osl?|8v?z92L?Qh4xHL@r~8IdO>a zWUh!;KH^Us!hFQl?@{c7;V;lFEMqhSKg>UIl{cR;l7T6J->o4Rh-r@JpYl0$3SMV! z1K7h9;NtSbJeF6PK$KS4;SsM4s#YIj(6>ujNSVu`B*T&%k1>YeB4zc1>u>D_y`w>Y!qvt~y)ytli`jeXCf*TV zI%t#EBX@XrS_7qZrZ5yLELQBodI=ig!_I9@iX`DK%5Q+MDOY*`5shfKYLPO<8P9@R zEdC?VN7M!Ni^u;zqYutUQn1m3gXHlLhMQ}I&mdd)ttH42YsT0=4^O)5U<#Z{zGz9v zwq?s60+bB}|3tP-T)2TP6Q8zh`5Z1x%(;PEH?n2+P1q8;hxXRK4);&pM!GD&8#5_r zLU@TLo`$_v26mA5>2`w1kpaTdy=6(z@`FiOrym1_v*yFqVS;{Q_d{e|VdHCxrfI|} z!6uj=z21^GGQ0sk8$j?90VJ)m{?l}SkcNLqiA0#tm&2&>#m*nZPm!-g1?OXE!WJz* zX3NiHuf_hF#8$&Gi2-mC4Qx=Dm?G5$$_0Cu(N0nQ9xitKA8xk)eOw$X+5+iNJ$J%E z9OJ!MZw+ezP)@Xuvg+f7p1u=wA?%AVj%`BY;cpArI7$O3JH(h-rQo=BLmp5K@j1t4 zRhW9b4mU()$A=Y04mb^4#c&A2K6*b8xYJ!7wxh{=HJ%{PoTa4DRDsrY3gcbpg7DJl>G_U>|i-UFUtom;x z3urfq>O4*jV;Eq!rcUJVtM0K!GhFh;x}Q76`{Wnni9MA!_ZCF(I5F&Amg~QL zTMojoK3w5}=0raIiiu(P+|z-BW$)i+g`<*3x9bH+Z+iOZdtPz0g5Qq0&R{~~)w z**px?ZsQH$p~SOjtW3;SHXr4wf-rUtnv#Gwm*tF4vnyHd9~&1Kf(Ca})69Yd3Q$G$ zHb6=DW%CF{HTKz$ZI!3Bo4&Pr=g_?`ck;-1IM{dgMWzS{#r4d3|BcGp8?D^nC36pZnV2wA3=l& zxB^x5qPlK%#bA zj*dP)PBtDW6PSCT!0NtI5a}s8*n9Y-2}q{s-+E+-Ys?;`L%tyyVbi{eM@80nCk?g$Vj*qP9R+b!lyzZUZqlLG7@uwB#@E~vB9+);)m_{E<>a) zIwEpj7sN!1VAb3pm@X_sbgtxLlHJ7kSz7O`o%>`_eOKBk$)XV3W^!P2YlqyDl9QzF z0ar}k^4{0Ve4^!+E)<7$m8H9bDTf{eCf{G$eUY4GG>lwlf3B&u448@gn)^2*!s^k3 zojl+a$DN~lbb}u(jP7-0@qTf1zc0Pt7orx-A>Ujn#wJPg4&cHEXVVA$5@}kdT^&)7 z^d+djco@4moK}oZ3eQtE*!1yI_47T8+0QFdBXp7=G9E_fea9Ll2~3;?Oauo6>NIck zc>P?@O~w#}>^0HsG|B>J2MH@2JF0Yj(7hsX#J45cN@ORa7*lqBnOY&PkqJt_Xp zn~1!P))uSZYIi;kllub!-~2|*_oFDP27F)xO@`K?7uNG zOi~FL0QZIe7O4a_C54j{+!y-RUAnAZnh=C)D&H;(r2xNTsrt*@ zYMSho&`WOe_U4g?JHc3>syOBy!{g(RcEAV^5#>*H2J9W7+(UnxQg+t$bihNodIf$m>r%&J=KRaMqeiqG;_O!}3!TK*`TOHd^zO4KN;IO9dY|o6%)No^m6+Nf!|? zx#x?9&6ZU2gAmY9e};0YsJChYk)%?IM`((+Twy-`1N=n9Z{b`CAt=TXo+eO2kP*`a z+mkvMNhm6!@hWoVFfro5*o5ki_;B&s@BIxdmD*5|I8Xd+{PTl&2JF3l~*5mNv zdh;z!^?EX44Y}yQeuzBq@T5(*G*hqV#J|leEYS6CX(nG!QQ|}STbcT2Ccc^`<5PUK znTFZHGelO^2uF{=W>amHnIwmHlsT*BBt>3F&HPKN9KFP!t%Oh2XT*bkJ-afTjpEzc z+sgBP6p!a5a3F1Syd=rHjnM*7l9sQ1Gx>U?7iakafd=Swyq>XDI!70PkY_Y}#tKoa zov4apWK*+!syahpNNZ$i2#D-J&R<2;M159NK_5~T_N(qj6)cxoU+Ni|l_=sHs$j(r zNVeB=@$E!SBwNB9UvqXgl+Xmm|B-D{I~5^Hf6OIDHe4W?AXx;Vzf$Qe zJUtyjr=1hd;uJjy2WnT;m>j>H55tE|&E(T?)2$9zXJ4$&p}OKA`A(1SU^SA_PpOJE zI?+3%vjBxx=lDaNk=&mjA-hx#(lD*VAV!$*4Y#LX>&cxjAd|6TL}S(eEYh-*j5GM-95UbZl+dz;ThnuPm)l?`dte=nOS-q+!<6E04@pM45mJpO@BGxXxb zzw0!=mvKc`J~eLr$$*d5IC}gar<-)EdVL~Z)Ui^SIUxBU^SjjeO!Y%dAOL5won^cJ z7^|bugHy7+`BZjubKj3U55BVcO^z35C{f??AE{zH%{xh``v+*Rta&?kC&qUgH0~UM zUR1n!^P#r~k7UjJDA$LUhN}0?Xh$XL?3ztQz&6EYsYMuvH#XD z-u(!S=EVsLwWIik!w^w1A4y-D_ff!!O!Hm}U^6r`uLEp;|AKf&pP%A+6nJQKk-9CT zLW>sRObgLYMSYA4(7Q6h5?;8WT0_Bw zylffqVL}R4b1{JCk4oPZ4G-w|>$bwU$COMlWR5a$lT-)6QJy+N8-=bD7i?mskd|zh zPkdB&2}a~zLK4 z1fVyAET}j~A%A7>*IE}33!*V;RrvN9391AyHmi8;H2*b|hC9vQrC$ggL~-5>R%~o> zN?V>0psdm%cKD)`q>lOJJ^{K!2nizN3x!k%LcKV)3O(nGkEi0+oi?A9_8={Qy*Ez@ z4HCS7DB6gxexDLGuYQ!QN`R)n?-dRqc;~%^zAD-5bgbnh$0t4|0x}P0C<~B02j!rb zu6>1bnY-1lRyUXtfF3{$2yti`V3HqlY2|tgm2&LqU zIRmjH^y3G|fDcL0r{}Fsceoq4%bbNcOV{^~dj_;%h8cURKJO%_C^W~2h3|leV_X_= zb8$Fc%oi2Wy=C=Da^!#)jrP>@*qj^`S$)Ci*fP>k?8$Zq3E3Y>qG+&TXxy3A1iKH& z5oOXUW*E#pGhQ29Etvzagvgt9MH}oQY6AWkg>})|`|LW!l)>y-_2?v0@hyLBs=0Ql zeoyxA`J}BmYwnGA`UGQ89t$aUX7h*-h|_7_w(;AGazH_HG-s=z=|ppO>nGyo`{B@q zn=xBl>nTjhY`&hh9D@>Fd6FQ6E8z%+a_tRGj)}on=UqF`gc0QTaji|RMA=3w?OvJ7!&Kc5Opk^zYE3S*cp zqVcWS65M(RKtSpCuOh6!pbty1u3a|wJt`j?HVWAzz_kL3rRMGNIE@TC3Wq11N%;i$ z9@AvV0!q=WJxUj&XmbYz%G+MgPL@n3CuQcaOeyRTq%V?92GSr*vp(?@VnDW*%{Eqo zxy3Kxjz&>|BMRbh$33e^yhq^bUl|s3gdMc)Js;>D3{PUF;irEI0t2rl0SC=JkG6UW zF+fZ};wns!V0tJYXpwN>S$nF547HRQfo*&P$OA0%C^O%LARqiVY#GzvhD-FmvIU23 za~w?Y7hH;oga$)nAvZSRRel0C^lMqOSFA9kbupYyvAPl6r(A&HT$)0p+D%vr5hv!H zR<|$euBqpu$Cxa7mK;0(Fcz_v(Yzy#qZ|3X4p&$6uiSW! zx=2A^`zS6@$cZwBOggNSyHuw|`TP8JQa>J%gzFA;Nwb3hd?Q`a52&ivmj5Pnb^1^# zoh39DU(){cQ6(FOGZ951v~Ca@g@Vw`lJHL>G~_t4^f?4I?kAL(Xb2yE#&FQ$=`<9X z6^ef>4dJk8X^4)tG!$1GXb2OY6awFXhIkGFo|lG3<35I6ibV;ISqJ{eTGnSvEzA1v zeH1}~!PRm;ypdC)yzSOu?0NQajWB`55IK@Nd^1H50ECMUj9IV4gPKe~5C*H0&H2a} z8X~GM*=#T5ZtAul7#6FyLEOr)TaPraxJAxHF@|?tji}P#;1Rje{Y+5*v6d0BA@Z2p z>EZMl089i_EzQnhdB^U4*hEs0Ozz!~!8q^*_moX_;kJLFghi^I!8e~C& z2Ce*DXk6KiSQSLSgcgp+SR6A;3m86$xd~vlcf=;P?ToP0ZNO{eWbx`Cyh~NU;rirTDIj0BNi~cYs z12MX}65C;f*QWYxMCGX|7EC#$y5^Q-pOJtdq-gl4RQXUR>N?Cy%7 zh{^ZGis?Gq6aZPw;{Acx&gO06_o>A1V^p^Il}**I_}*&f>d3<^P##7GkHrOq?+7>N z-lhl$bP$Du=pz!8$H)gzO@A4Ux*LuSOmV1s3Q5^yEC?K_$%?~DG@~*eWBd|CKI4oi zmo^R}M01T2#j#Ao$TDf{kBN5MRT!Y^=_#PeSd9$>NS!>f+L{XL%657dLycyLn9>bH z4UdGraHuyZ%oysVFhQ2GZ8X$j`)(NOxNnC#*$sW>5MvH^PCnwMtUx)+f0%S`o(h%( zYh!NgwlTMF{+OC1aB|066N!$$CR>E`$Sv-Z}a419XHP7$>L(|gp-1f zw-hBZ77rh>sh|3lKl_#LEdubR#}d+-4~;I?>K@(|1UH07epoUo)f3mxPBjlj3&Spr zJ(w=B3iQ5DT@O~LNw72xGg!}_Eb~-S#cKL9>Z0GCdaN_Z7*b?LhG#i^Ca#evLsqU~ zo32+=iLRLAzXxqbvMH!GN59b}KMS>lP(Xdi6RTjXt5YCbbxWR;ZXhm45R0A`V%SR| z+`XQ$p9Esd+5|W!qQR*IgR?55#N(hXsueWj-HYHC!2u^Es%LwjWW*$pHM}$e`e+Qb z2byA)406<-%DY?y6K@~32Zvp{7*7)N?NXYrfo^aB z1hIh1GxbcY7iP^Pw4my<&UhTQgNL~_?}oG!d3yKBmb@JK(DATcXnB+nI-X(V;sabT zw)CW7uRKl2EI9DBLEb>u*}*Y{Ce>T^$FUF31C*-2zSXnEifi|s=6(S9Vqk;vP5~L3 z>nT}YYgjgY?z7hI6@%Wz+Z3Ewm$XzyOPC|UqZ?*0Aer)jLygn~tkEVFKX031m}i8e z$h7MStqb>qj1dW3kOo237p^Lr|GQ%2pHZqAF_-4qY6~ZL&G%_G7&0g>U5}ik5-Q^9YB16+W_E;x8 zQ`*eH8rP%^flf@4;}AZVct%u05w@RaK`a0$RS-4>k7(S{G5N$z-VQ>Dr)CIkERsJe@bXzrD?1N7EffyI&3;|XdpO!#5%EM6j;+A6k*U~ zGQb?;xkQ1jz>Cvug_uhKbSXRHI!kkjY&@69i=|>|WQRb>+M*#reI|JZFwt;8RA5s; zd@+Y08qYZdsDKR8a@yE*D}tr58MKJB5kweKEX*O0IfO)t$(SRs=^N5vTE_$davtUw zi?MZ_TA{z_a_YJ3l=K2Ki6V0#q0gtS;*=4R#2M*4bd~8lWn?b@iCPa)#74SipF~5e z3Q$lU;}gUV|41a{>`X$!rS_5H#KuF9NvH}=7u?HLgXmg;ND@(aQTk_41I`w5lKVW% zTcL7I4vF;9^SL9Q^N~c8P@*jX(s5YoFiNY4+Mg`*>+>p#C5EWYqAAWH!RL4{nG&vF9>k99$v5tZ9G{- zAy5c$EA`_NF4BOJzWIH00-%xU}Z})#uawPuIC(#ZZ5`>tPu>_e!f)IxF zJQ4&Hha+PwL2$CR-iU0Y1PO_D>##faMZok)oCTFjiIYeWC_f`qm~hBh zDyj}L*yzpD>oW3)ZuDmHaaN-oLrhNM7|36LIP&+VDmJ>ZC>oT6r5WzfnD#&!>#i*P z0NgVsXe+*!5MMs`XWjtp>`^~5fy?Q#8 zVfQ|p$`Fbzm2qVl);g6juMH|Y-OCh{)!=w+p&Z_mz>tn(FBALBlhhEmkTgb+T3o4> zM%Y!1Ah960sZfvM&x-l5O)@5dYBy!Z!e(YN0oUeYRas(6e>80|Vw<%;NK3{5&ygx+ zk!L7>Hgtt!m@QHe$(}5SGA3?C6;VB(jqVgslo+2Vv*9JkP#raEpN#BDVX=;PY0le# z9c%7OuMgu`8Ext$oWEU1?Yhwk7#TqH8r~~3CKu>VbdnyFJXR7lm?94z7wxce<+dks z?vzb7u%WCmJd}&iusY$|6W0qKx&bC>+e0=W!>sxv(|acBvv2E(cNVCxNHHQrqw-l8 zZGdGG3aUyP-HKJh0vjy|Y)Tl#wxZF_tQ5qc@TX81Lb6ZE&Me&cl51?`2_mRz2;lis z{Rwn{Vy!MfhsM~(d2kEG(|Pr2`vBBW=j*Aqms<*do>bdkn8|1LDz7oOW3xqbyY^Z7 z6GMo<^wY_IL|z);>CSe2DFg}p3$}BG> zX}AiTn!|7Ct}};*C-Y3*>D|}kBv>nh;)q-IpGBTR3j_R16eJ)uvWqz`?Su_}Fy0}6 zgD~A2J_KOKyksOI>Ku%M!HbyF7j)_>XQIKWn5BN&27~ibT5s@qluPu~2`X=gCG;W& z7;%zoQaOW-qVYiPf>&O%&RTtZ`bu)c=-l8PF^i08s(_=%)5EqM8knt#GpS2zpi*24 zcW|oo=EDti6udshB^8BX212EE&Y0B0a4gKJzQFMno5_2t&CzRSCqNLT9fslN>R%7h z<*^CzsPUfK;6#)X68mbND%xi2J~5^Qlg>1gSMkrxRY$7db-%}`;=v4^#(8z^EPFh7 zZk?Edu|MW0RZOj{)VMrpxSSdUd3b_Wf+}Ew4~*1WeQ0G&z#SJ?^*2T;3akh2#U7=f*Rz${Ou4I|j2=WM zMbon}r{OdYQl;Ijrb!?d1eHA4g7vurV- zZ@JWnSr(FF62c~E8p4Jd_y<%*kKiJPcb%Y0cNqC{L`m2XVb!@(VpTEPj7bm_HC_vw zm!NGUQI*9yafmh=c{Y6<8j}P{z>2T%pF<&r#sejZ>kx807(#3ko1tZy(*a%cB$|4% z_dOBxwgOGUG8$v~l`IjsD4}S4?w>kWxOEy5dR2Me=}b>gPEAaZ z>yiJQqBUD1+eq{41Wf67K;M85K2nknCtRXX$N*8i2QZhG}uqH9qF61&YGLc^WN+kXKauE)LNw3cI~T-M7JT$KLL7zL;Eja%*f)8eFt+b zIA54M1mfM$AkA-XWP{8>Fh_4;!_;qq#i8BwU_Wk3Pee@9%gGq3UYw+(#X8FA6RQN|1LzNe?`|+AxDM2XO~l;*R1(dH@-oO6>yS=(6tE}-3$3t|LQi$W0kmwy2flG%C)gZfA0;HDX; z{+wujj{@xbPQ*nW$8!uix;*b$d}rD#hDSwruvMM$$xk6hQ;Xy>G0jI8((hB8!rO+5 zRe~1+U11Ke@ep&sryT%G_Qp_5aB3p(UBW!7qg?XAZ1tl4Ssref@i&@%_hj{9jUkfe zOMA`5<J;V1IEVPxoJ%9pVQHI*168u$T~J5fD&51> z^9vi;z`=~29VGkAukoD9_V@L3?a8)}oF0fGmEdV|NDf{RDGDOruFD;S4}MkN+vZ3H zStqA^1n0umh$T%PqsX@dV2r1ofna@tQGD|N@zc^`s~fnz2{wuI6!cm3w*qJLmH(OO ziPMcHnx8|iD`3ErQYToR2Wm2+h<$S@MeP18QAg@}?s!XjvVanq z$-Db-V`wwu8FYg!MxtABv*thTf@b%vaKwOBYplW*U{Q^;-31}IHx0<_S;4rar_+O% zkZx{D3j~o?-IGmV3tj>c4*@6Y;F_n^yCw|?<14(*5%Ix@xy!gCJ=w$%ljFvqKFQE} zt>l4`I|w!KOWjmDczcS@D7FStefs0>M0KDVH>>`_czSBV*4W0+)RkVP4fzQCl;weT zncs}QZ)>60)TW87+bJhKb`iEI@_~eg;x0bA^U&?yb|B;{5Kid&nTRSmIRfG;b2_Hdj{$-N~ zULz6N?m<#|Lc0ZGv^hVyU9gE-G*%xBNi@qal;ppgMY1K!gvn~Vvvfn@-$2&dI9QL3 z-qbmT2!_r*Jq0^|He@G#-G@ciV?laflvaEKTy>-u2dPO(%_%qXOJRMfcau2#nz7Eo z9-EYDn$wIpCU{d+_i)EC9;QXN8JsHO)~x8~}hB;CRWF=;Fn8Ytf!;ciNkT)~S9|&S-Nb9nzCWQ5c1e)QQ&k z7k^qkwPljk4z-7`s(nq`l$)BtJX_Eq#iu2f`Vg9|qa1-&9{m=o)K!Ika$ChlhC?p) z#MMz}9(*eD%wpwis3uJV12Q%yCz?Nlbp3;)j9@|>ZUBxm1e--{&N6i&fdJKjy`uUV z{Cro|vqxrK9-d)U;g8N$u6B3B~b$jbe8(=-46(-ATZ{dkJ9U^-_0+S<}IJ96x zX`-I;0j?iLKYS%+_(~86ISkLZh>hVC-V!)PR5+Q02GB%PsIhRGa32N|aqeNyEzBZ< zAuA44x(}#Sbn7+(R(ZHiNN52!R=?UKdj$mU1sM(2)i1zY(!5LpZ4MBWTQ--*zc0m+ zqtqmE*EW&3I`CvL?7xulr*mW6T|tMj0++(m3m0u90&d6F4A(b@IjxMy>ofRF7jxjf z`V|C?Q1XH_3FI)~AN}1t$N8QJEc_<4#*!0~#k?Y$;ekz{zF%+AQ4|FZg=2+6M=RKZ zqMMsbV(}ys*Y&JZvQBeZ^)HZ&ysflI11p*o&=sW!*_69T)xl`TM~Y(-r#JhPA3_B; zLE&b9Dn1SSdJi%!zU``c)4^^~cF_a$<2S~RwjPpXBJA6jrX>>6jf`OuY3sxp`ob`Vg6%c&RgkC{vY;!@zWU&Z_tiSsD zWb-3Vgi&Am1Z^O6DZIxlAey5_xEXP3KllU>YK&m8zw_!~e@7jOf+mrx{B%(vgU!eL z_oGD-|LqA~76=yuVob8&{wDvqIb1cIMVac#(Dx6fFh~3l4i&X<>bE!yW0$->z`!~H zf(AC%k=^P2dXZ1--ovNHIex`bEx%K_It~jq3|aYz2@meJ2nN93kSZ{yBAU?Bb2xtf z=C8i?kzAS@(x>^U;WqY282C?)E-kjMoaL(^>)WDq;LX)f2ICHI~H)Q)||KE)SiEQJy#N`~^>xhq9Y5y%bTr zOH!dz4sG>2`LGrJnI{UcYO@fre$Hy1fH4RhRpw>G8G1}hksOKpmvu3ejl^t+7fXCp)Ld~MyQ)yOsw7#U}SCPFF!C|PvMkRpQHbT(N{OCR&*akm_^PG zXv8c#e=iQ~bNu#U2arC1C`2z&KxNvzoJ$rGY&zRck2}{a3k6LT5BGMD0|jyh3uz!n zdBMWLJIKEWlOPb2=Y0zUgZv<8`Y%$iNz;#xzwWd{9cn^G>?dd<&VU}uY#5+iA!4*< z0ZMLVzO7s7ulF(#honS8A6QIdv?4Bnelv1@%yWbWWz{>e5O5`pn|D1+xiw-XtN9!O z+{72F>WNAGNQpDi*D0?gbj$f zVfWQb)ZI-{jr=#v16 z_$WeJK_{%vmkKowr@*|+vGzB74Y^xO^BR3NUP)Qq66DAvy1DqwB z$4SO}th#~ksz-}B!=idCeXD+drgsJaLZh)N%4PM_-QHCN$Wp%g!pcLHbkH9NKB|lJ zR3+ol#Pd!>?Qx?n<&!+8U6Pq9=iQ7NoX?~>R7@wp%~pGwha zmhq(ym6K+~&t->#DJ{+}PBn+8RLuyoxT53`y?U5Ch;*TNk`O8WGmAi`M+{C_y%l~q z|CRG7q$eSmg@TpOth#?v5!5M`mbrULUfsR?_=$(_?A~>QD6C#KoLDBzFrAr!Jbwi^ zjrGi|x;GD_ADJ=8VBI8TI;~Jql8}?e)%G_bU2`yrX5uL-Gm}Lb%Ea1r*?U(WsVx+0 zqdw=+=T4TDc^Y&Y2{A@LQD9PJPDYWd_?H<@Q^u+AY($BD;CTuzn_z8%mO&~D4{98M z93g{=ATR~l3SFl0!^#8{3yxxWgls{FuMBA-t@XZoOHm)2^2mr2*k)%W320_K$!suJ zb25VykuzLzyBO%wY*`XK6{`}&J~VI;$R3M9>It_ zBWcCC=2LD;W-*)|%@4QW%fESuwa->5cExYe@5BM8IEzkJuf}wlOYZAAvzppwa@F(W zq8dM#)y$(buT(r+F3lF}DL0xqf2KDvtAcS4@^bRB{6c;vF3T7A;bEPAc8JFlj3T$# zOjUZi6R*Y|hP-)!Uh%0oNqNY$L^qZidI$}ayaJ?UiSzMWE-9WWne|MWi;mj&dEGot z@v}{1%1xv&X|N>q!H~3M5iFF3Y>W zCy!skMb^ZzukcuqFZueaR-#egCH#G9^-|!nN*3d&+ucfYhv%!W7T^vvRF9KXgm){X zjobhhP|IUyn1XR9KWP1$#{LIxf-}O0#X)6!MC_PE&$^%|Ue?nNfj%C_agUtMl6w;2 zQ1T6AJwp=VsJJxS8@|a%!hmU`+%&5y4Ul2rZ6KriK9%#?)lW`RNmzIY!h`4nP+#~6 z4NQ4{I>SxPwBK^gYJu1sxz4Jw&+Kf(6=S~ckfhuk%ikMZTp50Z}9Zin956E9GL55 zaZ+Ilqe~c^vwaAYM@hY?zi-J{W z22`<}rGwYQZ*^rtNC|wvkh5q?^h?fGBFR(9en*{;G1zDs5yWFA)SQp*=5EHfu9lC< z4Z!wiYuaz{>%LI8?jj^ezHM){~phP`Q3!(9l^>qxI zv$!0in=xKc4vha8B7_D=tPiFZG#CO`ogqM0Lzbg`ZohCFtiEN-EojWrj++ z$T_5nD9Eu0^@R(LgBR}1kx4(>P51+|She*H2m%XMA1KrELs};uj~l`em}oeL4WX!= zJ?&xkWmB^7VWsR-*ppp?#+lcLI+zV&a!8yU4oN_uxP>)z1kN(n(*Z;xIjx<5!=XMM z5P1AzM9)aEafy(cjmAfy0*96xvW$Uj-nbK`+2x1cC!j9@gH}Af3zF&4-MeISoV*XG zq7PftWg<+Gnx9z@0EnN(<^ug%5zZ6KGK!pq;a1TV;}+^DjIGE&jM2L%TSRo6(VV#7 zMRKSgz0y_E;5IEnC{-~`!Et(0a7hlf0vLF?KJ4V)r5Qymbg=p2B)a{e+)%s3Uj1Eu zNjb&Ld%9*>2ie(tK08dxKI|}DkP4Q0I=`#F@c4jrQ%@ht4@-W#ma}^6JkPdzfCc~b z2Gh&gV0TM&$LdX56&#W*VR=*@h}%72V#xUJb5rt+T)Du>b$+GypK7$d8oCeJR zRxcbML{@t`zpw%j3)PP)=lMb^^ig$Bub1X~bZ*f@+8LFuQ%V57(CO3o(>M1V((yaU z=nICF)#WUnCzRN?%_`=a9nE__hX5h#nWARj3Ot}aG+m}p@rCj=#F95Eh9 zYKGXK#b!WLU>MVc6_t2)mRe|k@ffQS%OV_9Qu4(-B_;IJI9{FOXge~;LQZHPIPkmD zq>sX36`Zjr`wpE#hTv~?-s6s~1$xPV(>EgHtGl6EI;BVUO}#LYy`%P6`9nQmRBGxq zk4;3>hQx*DWpuh)WbhyWV|ObQ#}Zl!#ZAQKb9MGC!;}kM1=o~=0!jn?D4kP}FM@BB zy$j7-BdoA4u)IwgS+GEY0uq;EW)yOa2)hX0FPe-J7zMm}c-#TH1|f+HMSMuR7dPjv zfw%=WafTu5JR}|1 z_}6T7bZuwKmBDw-n_}Y3q zCzqee?~+ejn_#d75H6&*yN0`$i|>HEAQ1t*eMpxbWy5oB@F<}wFo3+(0B)xAY>#j* zRf>KiAYdqrnyKMpy^utnFy54a{_c=T6lfKx`z@5g3-#h%H^`Tvurb+)e4{EtGF_lV z^j8M9GZ0%G-t|JsHXawcO6Re{qZQK3<-q-LPmIIxB2M7EtG=k-vwZALcR3*SB3FYw zbe=U-A<-BcL2|lnghjhC3@vDRG8H4AE;`$UP(0 z?6gCs`bG@x7~)3__CV)APsoKGel12Z))sjE#x)2#{=M2F6N$Wu8)8%C!?7~Pj4L+fv4|tzaC$S1Q|hq^Cmjng zVmkC8>_gZ-4uX!-I-)raHLHE)Qf?R`%(^&cB=+@Xz_6x$TacH#a6wX5|L0f*dh_WA3{~PVb{8lDBzk8sHwD?daH?ZgCQR$bDSb4i%->^kRaT75#C!g z3A=+i7`WT~H6bS-QUd#mmLnwWa*_rM&yMB^!@KJ(d*S3$NhV{x%ncT#JbJp2Sk&<@ z>jk)Jun<(-Cz%=tlX9MEgk{{UjJ^&cCPd>VKsJ#1jMaJ@xy$W?>k*)48@=Nvt2n0^ zfVL<;5<7#Ax;>M5DZvFSSJvQN3DMb$y;mLOObe$#Tr8X!C`{FPCQCMN z$$P`I23-*W)t}~ToTxIoH=yHy`Nuxi2549PXqB`;};GLzPi+w`M z?oV-wYj(Bfp0%?6@WEIz5Ie+aOo&(jTg(<*vAgFcgs)uEe4w$`5puX z7Wr}~G5w%18o)~-LPY^QhspicNv$l7e5b3x<4w@y95k7Xk^nQ{wX#L#LU9Uphf}B% zcNDrH8NWN%v^@ccfnPvJq^rG&kD#}f_96;to%R~@<{K=Zj&Gs*2ZHEYaFu}Q$K`Dv zlm;jVl2B}EqD(ZQ*(HYKDXY@0moAtCNF^ma)Tw;&;~#fXZZWW#kc&4~1aal%il0xY+0DfVDU3@1SL`4X2}xS%ALKw(wW8kE?3k)fjQMxUJSJvE~_A}Nn? zD`1<>Rq|(aL5F`|Ie&7nhtW#5_nvQs@S}SR4~(3@5h1y-eED~Rg2j!s4;EbzTLfnd zcMtb2XZ3~k-n(v?KR#IOsi=;ksGLqTmm>s0=Br#JaGvt)HYIB8)_Wd6w6H*lc4)tb zHKe69e0Fg8@;5(VRjZa8ZU;@|`sNWk7$Mm-;CJGe92giyA06! z^~q!L{Pcx9nHz3~zBWr=!@Xk?Q4|eOK@wMLa5Dn5&gwI(&lkhZ*c6*7K^}=W69u$c zWHXcA0FNgdji6D%^@p3mLxV3L9rA;0ak(0ot|Yj@s1BrN-$Aj<(|j?gB^C$P!HDxu zp4;!jeq(}0_tV4?q73^^Zdvb#ZXtW}oGLU+V2rT^fQ=G5i7?#^1a7D1BvngQQsToP zhCSJ9Fd5s>S|ta{<*AueTWATY*_Ud&m>DBl;yxmt3`8=%cGBe%EIEKAhGWq!8dG#6 zMJyvEUKpMPF%_!a$SYnV{VV4WP^3;L#4H%97JD&8n5{QaTl6NDuMh{uXXE|~moHJb zh-bv3Y5TF>v+8Oi3L#D_!MxAXpX!%!*7@vW#v5(b{B{nRSPoC-9Kn~)&EJw+f&~k4 zgE8k)TxMhu*EgY6lI7P_p?w7l|5mkMnYW?i*bmxf+JYNIeAKWtiFmk&H9CeNKon7s zRJ2_Ey>@Qw%xnWyKH|A)8FN^miMa@1UXVVNO2&Yeny6U<6zecdR2SDU6P^!}uwsLc zg=CtDw`d^N4W0w`wgk2W1cIfBO>8dV&>BL$)Yx0ZtiG=sKz&S<&=)soQ>y20&;+^; z_KUmg+POT(Er4mFlhj(a=58$x;)Celd&##I{d^03m>V;Eo?QIzWKS z5a9CK$(MTfYZ&~n3bRDReO%=J)>pX*%Lxr6A7E=QXTw?2%b)|)hQ^XhQx$&U>e zmW$gJjJGf2;7gv?t@B)UuAN_=Iyzjy@GDmlE8XTiCXMIR3k~+@>dAY0-B>_(5&fC0 zN4bT7<2&c$60p8~{s9OCTAGBYd(|T34U9LjWrLsOJD8>GP*GC2*ify)b`GFnx_a16%|hiM@L~v^DJWD99=k*}GH9@7 zJ;2V!&kCEs1H;+s$Y4_f#|dDE_GyVfn^vj^45vaUrQPzAa!*??jF{^6;-{#15-q)- z9$yec2O1NVLgt1|8`=e13};8XLwRr$g<=N~?n0PP&{&UgS`JIoK}Mc$UV~``g_qQ) z^F{9ug2eSzXe9t=RP=621~pR&3zp$M(AyJsn@%F!QdC35H?XajE2e~5z3Z-IOhnVi z*H}kGq^uRV!eNrS$HWHj#_2F`-vDz*4FRFoXR-~p^+DqDW{QufoT!dttG9M&E$_-3 z@)0we8GO7iNFZxl0kEsn^muM~CjMYuJC~H-9u6PM^3g%a8Qy>y5g7_~<~@u}u{s>c zE;BVhq+Qd%JFnh-&jW)B42If1&)HInf(voFZuDcKs^I!5%3Xs#7G@6XI7pr?q)S+z zrFO{>+=eI3fnjdM&jEfw_$neQiztA$y9e69_4>SIFo$k{=%#6`SD&YjKzB`HJ2A41 zn+k!njbIX$g61G|$EDfJQ%A3mY*Ez2{kOgarf_?6$bit=>IijU;jk?4MAr3y5?W^L zpk*+?cZLAlikWn}4a{v(4h10* z5LTVg)c>HB z=b#-B2%2T!ehiCL-FgFkE6j|x%pSMew~62S%>=V zy)@fVpQWY(0m^HbenvW80{Opl3=>nI#C#fsG&#A#0bED0X&g>NZ=1=7>}%KBpS}5c zb*UvOx6Od7KX7?ml_}nR_*}&EP?)fu6i^_J1SyOPf0;OJNkdnZ4lL+qgd?PR6BY;% zDqmt2s$}8Q>p(K%1?uw0Ng2yNrm}c*L^XFBqneQ&Dq%Q2uFQ)OQ1TSL6zlIivP_Tm zB~Y#n$a1h5P_`EUYxU9rVzX^uQ70`bV7cA_4Pi{M>%}$nh*WN-Rw;vsC0f=h&mz#8 zN^UV&8PZ@xfWjybj8A(qm!yBkVPebBSq%J(B(zpE2j{f}64$sngHdV3Y0Bsi<&DDN zhwOu4>N$K-h?anP-O$tVfpQ1+OxGdeVLFm|rUdJZe*VnFRTERD#vlHw^wT8;~; zpnkx^!Q8#TaK95t+HcN-IC&|jKnvaGP9*M~kxY|?YzAFp&~=$OIClh|Q$P3cpb2O& zXl}Y?=>gkZTu0kRY;>{21@SQ?jS?>HQaY#ql8DQ+^F%YT1Sp>=xa7fdK-EwN%t!9O z#HQ_v?wfMnCDL_CafxrEG$YhA{E8L?;z&S5=%V+4&*#)q3TbThDA)ni9B3}3C5WMUS#yb4Fgmxr zc4-c~3cg#{Ls#%5F?qeMx!@Mry9B7K$hNdj0!*IwF;*BASZ^_~j4&k0jdEH8xzO%p zONzWUa*dLO0>jhYOtG@$Q0>jniFku>G}CV;PMRF1wAwJnfRF?B+*Qenq{Q+7up zw5h>-$g>z^=|EhzXgrM`^s7TIV+kH4O}bF$F8nOgt=RQ7X}3no*_V**B6CtRR4#HG zb}A7#E22BU>Xt~i$1Gga!&Me{56$W+RSW96XuYKHxLzm@tfBn$JZWi`doA)`NthNvtCX z$Si$O#XiN*wtPEe^Y9!d57-4AnuYzspfRNf6aEz=nC`l0gW>>v<9s|i9|U%8Vwl(uelA0!5SgxC2RtqM z&TY{bPR?^9R7V0tvxRqay(Ugb-lv?5eTUnyh0X^CWO&RRhMSt=&}>H6P*!9fNRMwy z{R0U*SX8m@ndWXI!s5D*MeU*rHwr@xj){hmibzFRd}CWL7E_7a~( zP#=daOntOqo2CvkFHdK(9KB=JaH(72G74xCpatC~oE0 zY%HMR=fTkrYyvWvO!^;#3gOkGTufH`HL{EV2Zx!34NPAee(D~BV%XsMeRM^7p$7ic z^*Pm>3;p=O72*}4V&E$EA9v2)jwdz-34r(`pzshI0`Ws`aJRGqaH|8=Z}!$u1A!t{ zMZ8Q>5{&S$Hjbyu3~Eb^N^DZ>V}6}k*Bj*m1GZ%)_F;{28%T0ro={q0zd1MBAd!J> zFz0h&#pj=6F$?nD8q!y9#kl|y#R%DSXhS4ZUROYfZrqQGXaTjOb}!BLA+R_hdJFZ=BZoFsSk+ne_ik2*U$_^&bSO?R zoT<+V(1Jk1DuRZ3?7>N3!*|cuvGdc+4a`%$WumS5MBbXp`(fw$}VTKiQ%h>&n?`w_1y0d$O6dRt+iN9SipT<|VlFc0i8E z8ftMbXaMyLXyy{M0*4Wc+xf=L!-6F~to08FOx7w3@w7cS>3pydVptfcmg3v%GRDV> z9E=EwEbUIJm*oK-M-$KamJR>$t-99Z7q_oMW3iJiBj2m|6x`6?d z7{kM@bSzBct@RFSDc9}d9my`H?XC6sm=H||PT4enq~3Ofg{UVJZ45Ti+?Hk{CW*=E zi2zRn{xr;o&SibJnO?!kg|A6TF&*Q(Ww6!$O4v-D!=cIbO|WAt9Ei)x;{9`Ez?Q@+ zPB4Pe`i#;&A^ zkPA_IBXXHeFm+#dV+LHE)xd>zi=dP>=1xqL zo3CXI2&+fx65k1t3o?%N5Q8cL zj1^2ibDo9i3y=s7dZ0y&qSkAJ+wfNYk+}W#Vuk+Ryx**GiXEO$rqFb0rg@>-OWtWN z80oR3(xiRteae8YN*B+i*(SfPF3m}n5~u;0A-TjL0STP<67uc?4LS3e`GeV zU*OA~5np>(3R@0T;wy8aH7Npdf>&Rg(F`llBPes>Y3Junajgazb0MQyGFF1nP0aj& zgkI=ijft+WsEJfnUiHQ7VN#*^dm9274+WmWnvhMheVKmo`4~P7wj`@V;6mZ2ZE3*o z5AR^6hO$B=;m2Z=IpQ0ve*YM`ry*AP8EB;{kL|t_uN!_sBte9GYKhlps#U^63^KWF z5qvhJ$K_nTtGP?_{=UgJ?UHrIUKq#}ngRtKje+FP!z_%sIrZr5Vy;Oc4|4~JS|M-? zX_F$?40$mSEGd`dbc-9-dcJ9&!SMli_|qtz#xvH=ZJ_X z{t%}a?}+KIkk5+6}?D zNuc3jzxm_rmI2YN+_D?U-fo|VbBe>*)A$t*N2pKdFis7EIF&@0FepMAP|o4+d6l+A zFcF9V6$T8*%47=m%Ee=r6v%vFgCwvN^XgHu^{s%zjz$9n%9pr7KsURX$H~&t`(NsY zdx1A`PX^+zmX|ALJF5-+GD^aU0s=*cT~y-)iv zZaCR1?9O~|URbc6fed6IVW!bAaY`oPNGCefM%eTo?B+Aa@W1AJvfb>((Mpc(xD6tU z&^tny_7Oe2lm3at0=QF2rE-`G2dIkxHeQevg~(CbE}G-ziU988o9f35A*6I?^h6^e zYySM<3@0VaqG{sUac;P19hy9R$7liP;!5?a6GDv89`GvFll%%#K1vOG6?TDq*b0BU zAnXpuA1uPC0hlPrF-?+L5kRQ8gX0Bqz*!7w~egyWHaV$%)$8#R`Ku5hLGp`Su$e7X~0 z%j&lz@QLbX{>7@YQ@9DETfD_%k-7R zm%cmRBBWF^TBn`f&ldRvOtt(>)@F`4m}QN*;(0WF_5cmw@w+t3t=L#D_RbJ&*%TB+ zPDT7+97UFoL(lRXgDA@qQNe_4qM6{(hWvr{%eoxWj4aL=Xfq1IYx#Hbo&lW67WjHX zw_>z9!N6J%XwlS!$q*sbM|jyDLvndOu1jMk)9ng{9L(6pzC1;Z4bjY;LQ}|F$C_!0 znmX2@0SG>9n-?=q(O60|p9q6*3dtBeNZs^Uy8(sL>ay?JPx}A3A{&XMH`VLSWEMMA zeWK`nzMpSy)8v~EoYgPbzlhqfHs$@DE7ePecpni$!%cXvo8SI)r@AnhIix+-oxgme zbl+5DIpQ5(EoLN8xS+;q+gbH#vcS#aj^4vkMR8R+5P%agm|Y6V_wbT6YTCmE2+dD4 zbGL%RwXc`#R=M>Ems5->cU;ZgcI3$ZY$y135p-(kOcm`H@+ly$S9*Xv@oHwrTjDGS zhG(kzn-*-&@8K5ENM1yw-;l{v^%nwHMmLVBY{}Y2g~QDXf|m@IzdO@fyR zZ|(8q32Z-D$g=%eUFUAkN50XhA|$PX!+=e3TT`soeF9*bAOB23A_&;3fm&PzswS?* zSmo#H6qMFhpQ^Kqqjn?Lu5RjQH$86Co*BM?9hW{Lm#D}cL%9xK6lKUZ#Y>hO=&?sm zG{4q@XdsmH29PmARhmT@@)orN$aM7@bAs_?VcmlL8GJ53-nM4Mn+EKY7XAHmyi$w z0#C@8!I9mLvx6A%pWV8z7&rsD#)P|iNgXGlcKL{Dc$$LpxkA9mpJ&iRq{yHYbA?r+ z_zWR_0}1;G4niEv53thHF`8DJuYa;$J(;go#Y6ic;dFjDTsht#Du#>lnn zB#qKM20aUlL0u&PDI?oP%Tc4KmW|D7#j0*bjS3=jr~`~D$Y$z3;uVsFwYK%odkWlsSp*wcj)slU1$^fEfxt3<^J9T{~rkf@RW zr?yOIB=3PnP@N00Nf}U!bx?~js6_&`Kz(X}TU+mKc_h_}DKg7-k2nO-1P11Van0VI z=BZO1|MCWUjNUa5#Y?WeiYzkChd9%fzfp?(g}yuGyXL*|@DL9)Cz^M^)iPW1488qT zYUVHZbz3tBkoB%)D^amzW+Wcl%`X;$v6iR1&v3^cxOnqK5x{EHY1FJ&-s}Bg9{HA1 zRTvV@z8GC{f;IJ#=BrL)ngY84#9{wnrAU(Lq@l9e$J|Iao3Gh%_LX#AQfyNz|3A{+ z1X`}EJkUKu-Kx5`>PknlY|FkfK2dH7P z$$A#tI>SDD`1e2WfBzfT>q&P)IpP zJT)3K7K#r{ zbF2!r55B5!g{Y~zF(tucNCR}44wxFhs#{;SN=iEmVF>fZtVu4F?<*h&du_9a>pzBFrSv zsd=ivEQImX(>X(3J-y?VMj=Ry`^P^-2s#Hqf|tMCLyyfyV1IKF`jY5B?UAl5ue8&v zKP=IID>Nxdp}8S=R;OISH_qz3P}_>PmmpRzjKhGRyp7gh{R$LG7Dr322m711%^X6@@)*DKK#QYjPl765OA;mNtx!ZvBvU6DMaPvIG2sw7+Fpl|U?5mg? zI)Q}Yi(d0g<1t{zG=iPa8X{mTuO!+6l4Dbv$_OGdX2}N^I*mqe;u169Z$jU)vDZ>3 zZywDLWQBt(Z+8{OO0(vf%{_tVj38gwp7RkexTYO??RdiGl?LNjwXGhX-qN3YKFpIa zSNRk(m%nq(?-;_v&{1sd>b5ZAg+qqBKBDyL#dOoXOefY7$1sKs4FWp~(95Cq?YS%U z-{(MrFsPLqQ3mbCmjy51{1{BU^E-Ld&*s?N=%%tuiW$;jTTze{P_o@xfSpeSMgLYp zD?O!;##1R}gDNF}31Xb)Q;iAAD=ZAPbS;bw3-jR2Tyt^L`ohe<+*#}x*6LdF ziHg=<<x4dve%bxPJHy?(73i!^zgPFpq z<;gSf&4l?>ce>U9_Bwkv>Zhgdv z%H0kLo)6-ED5T&t0vEZqlp>KvgpqDk_zur7rp-d75txfyo)v{?wfUzZv&-{K^Lh_g zENwZZFza-WtLOUt!QyyiAVK=uPZk_QbIhruR#s%HblVqJKSIh?>Fr-G(%ecZ zBB9W#$I1=Xxfm!$*j#geY1aPPi+PleB6lqcxDHWxR$g6JglAIcw&urJHkyR&gACfa zD=|Q7y3Td1SYl5GS+7=1#2$T79XMp03o0J>0NM1Rcb4hnY&l(mbKc(@FDfJ#R(7PU z{Sj0LXa&$Q!6!LGr`#-rasx~tD41AwzsyFXjV|&LW)~>nd3S*T3__%!TB>F!ku8D) zUl*%XC?cvfr9@yQ(~7N%nHr!2T=}Ir_pO8OVnI((>2a*5zO-XwT zoRr+F>#|sRM|=OoA!c>imp+R0S%PonKJb0{<9Yk=3{~m8=En@A<>Xjqo1G-3L78>Z zdIsen`c>%Rt15lx1io5F3?XXr@F&KPn+5GPqLhB+16^G)fM8zKO866BuCMF{4MWJk7Pd;?|wUw}JI?tX9 zFkMQ^E?ghs;c5p@i0#j-Cs72B^<&B2S~Dh=*PHg28oy6ha;HA|Af3vJ0?>TIztkbV zRsvE)55&Kx<-fIMaHL~_9bvyvqc;^eUr((p-~{)F+_QLjJRm2xFpa|0$Iai13I3q|DyYMsF&j+e5jP z7;zM}wXw5mZAYHFpU=X$>S~Ap7@Xoc!}P2(;d9copdTA)R%JX^e#E-PF31gD0a!sO zqO|aYRlLLA886>>^cavjQQSNkhiF&*@5{>|tp4()*f^oo)M!a@&NAJ$emu0ZJu6&> z`7Pn9LhCDK=MLXM2BTqJnLBlcMjC~-HX}^iv4nHQK6iqFTbwd zzrA$J4@Kya^#;mCNxB5$Q(YK}h zy(XY>93;c+3)D&oPOLhGRC`cwz`#efKgkFN9lv?=xl=abV1F632!cVjXFkPe4zbm5N0 zia#Gt`_x5GhrAm#_tlI!bjCqCeSdoIy=AIrt*uK9D@7(%V>OW$N)}qKjkT8El?VB~ zk(7PZg&bopr)v(dOu|xPk*yW0mcGme9lU=_HxIGajy%v%6}ZM&Hm|Fr6Z9X66RHW* zE`ZFNd?WIvym`4qSf=-V&?Uf7$NTB-+Pse|wRdef*|SCf;KfV?4prP~l=LX2?v}G7 zp#b;e)CN4r!TaeykU^2ns9en*N=Iv57T2URIj!-svbFeSCBX^2?en(3`mJ%B_ZQ$( zcyi;ScoLgpP5+&HE1G7YI3b?-)=91~YAr>90<0>ME{m8zC?y!@vpeBwf0N8dM>Id1^G~Ztxo`FrgOMFE2yn^B7{&)kbY^La3W)*%hPH(YEt9yjAO$JXm+#bso^0jfjHxt;f=MjL;l5dtx~v%l zQ40VBmj+eu0$*mRT`iRG+M=y3PVHFWv5iMIubqB+{?*YJ|}bj0o7RI6H^4fu1O@Phhipc;bx43ar4S^ zFvoiX0*od*3mulb0qC3NinE16w7uLAlPPTI98Y+zhfdAA2Qwz_5gOqUMpDJ%e+FYz z1Td&9M&W)x5+0t`&QBO&I49Ydy*E&prr2nd8!M*JnoV0D%f{qn+{X#c5TAhwwiAgqR_#O@#!jRd0h~opdgdn%uo2=5sv7F@X79c{{NeN?wr|I< zs&wvk(#U>5Qy-uZBdT&(X4g1iTY*DBOgOrYDe7Mt2+yd(fgo*QFT)JV)lj!58-OZ# zG#&_i`xyC)hsJdSxDHq$Q}4)IWF47Pgs>RqAZ&Ac=p+~|_VN$0Vvt_U2HXgA@?2^P z4AYqX-8tKs?%yQy2fyhXNXU-iJm^ zM_i|1DN~^j5~}b|)%=(6TEW_C&N3s2kP*F7jV|pp1G*2C7z>gmtEE6e^g8j65l6ua z1DaJ~;AkjQL?#gWNoU87PU+)^_LFY20>=-`xAVNYEO*tqA}D9&3-dryTQ%BdO{_J) z63%T@3-j=@HvP(%83qdiR3vYpVDmmznX>^W*Uw}y8K^nfRCVpO6%p|2K%5TZP!_PF z_#6|`yZI@;?=x6BFj(_q1g9$0&Wd`-%x83@8SLn^&DP{V!jQzFNgRXZhy| zfUd9RjJD{H6CmoOm(4AVpU57%DK-eU-9TxI%D0;-!jYsSjy6toGs_1VDS+CpI8;#Y zTSlX7V55o1TY2A8QEq-0!lbOW48I!y7U5BFCBCVeKdDiKDXcNVJo|xu>)m#RehO6H z>;Y7OkAeY8-u(0)w60Nl`=942h|HK*5PXJAWZ4q&VlL#nTPl)8>?? zo4Tj$6j)VubN948<>}V$>6TNTYWv&Tj#HjKx_f$QJgxI!*tW+){cJF&4k82Q2geQm zVWNhYK0K_W^Ewmq!n|+885IJ6W+CPnd|ubb3|J0iow--@Nt8MZE8AraOvfUCnNj?^ zygn%njC&Y8A*ygwX_YtzAhYdG@G^y#77q)#91H<0qi!DX)R#UF>e(-+A3e6Hc2%@3 zug-^1A@RVjFt77NEqlfimUF&lGe;Q?lF?(pUY*Olr*ihFh5{f~PvsfB-Cq7;neM|y zfiiI!*OW(92*Ex2)3TfkTN$n*n9#zIeQsnfnl~9;<})4f{5}WXO~BriWhY^k7dhdN zjC4AXHE_MPfco(YdqtR}7SJHw`^p@@7%P(~d0_%!&rmhWS*T4EuTf%Z)nfLs$ZB-I z#`*(ymzCOHU1oX)tB?eeIcFq8v?e_~SF;*6`h#B8_W;w_e;3@?paMXeuuu=^xJWk; zZ4x>S6{&NgSnQ7pqh5$O*UP&rkg2rvTm>Z^aAg5+l*Eqg0fyDCdRHQ3nOg)HQc_r; zMRf6>vCT&XG$IB@G0)Yi*p2)OwiK34z5}m~Kd+bpA~~1{Jq9k_ho5Jq*ZZfeT0Uv2 z<9=wPLl!@R?GYwL-&lI4&kIIN4dWn_!^=Ca@9b5#@^t?dEBkYflFDp}4>0eq@2;M@ zL_i4rh_IV|P8!NsgyIwbtr}XnPR{WAlA`ciHE;#2ZZZr7%sfMcWxt+YY3I^uxMX<7 z$9A@7%s~NYi%C&C@LpPXWnf8EakWu-Jp1fj5ubN}1sOieYbja%RM=?kuaBbX(gPDn zufRr=TK?tnMx-rRVW>Wibh_8}k&3cUa6t8My|^JmsPCk~qWK^F(M9w)z&13wwpdy; z@0wS5TabL%m^5Dt>@J$$oFDzziZpXYu5?8X(3LsQWExCLKL1 zi{`iI@fHRHfRY=uor)zB9WxGX^lAc;Kz49C(hrmkIiaH}O(tq#Nr&EZ!TPf*pIQ~v zd1pI!=i%jhio;lQH|LFxX%J)Jv{stWt5$v%*=OP-=8*yBr9r^LJ7q)AJ2#98kC+NU zF?vfG%sAMLBx2zr44{hZwlc~_f2Gg4$^*rtmYI@Y>muCP_{22@*97iA$- znvY=>Qu9#SfY6vU8Pk_ zV3u%G3FE!OsOan|ESmRm>UFQ#?VrbFJZ!$?X%B2n&oT0^EKjYO!3Q4+kD~Yvg3(fh zeIS#VD4Uv847!%AB0ioQO|ongBZR!$s8um59idDV=6UE-U_`e7&!Cx_FqdY_r!P8_ z{m6N+v5;qba{@E}6W~AaFO;wcK5Zduc8W3s(`wCSXPw^t*Xylc-<#c>{Oz4yc~kQL zL4P>Eez@}AT*$`Hpl#QQgVid6%$Neyw1>JVlod7k8BS8=+EoACVA2oFfHBK$_;MDg z#caWhl$zlzlINUS0I>Q7e0`8N6(&iRxfuB1rt^?KRVX@SY&q%Z3=q^K=gC3)bm416 zT8*j=8#YuMsNH`2jxoDD84OjAPa`s%@ibp!*Eg!I`@7j6iT`v!z;Z+d#Otr}+Vl_s+BDA_ z*n>j=6tzGK*FnG?w!rfRKChx6)P@K>kz?0l4=+rY=+7~@KC4fu$|mg?#nMPg5GuC9 zS!ASO?iGOKOzr1l%IPBh4eiM&a>fYyst=_X$GYson21Oh$J6bvC!HqWgq2#3Gk0}Q z?+d7xp~DxvJIo!+ak)1q5$8nOaYg6*V5a)WN(Wj4{4U;@sg0SKZS2T!o{82su!p#Z3hzWMJ?@Pr#{{DV}X|fiN z)h9n!uyVSG>pToPCI!p_!O2^a-p6i_-^j~+iPWm;{c%4^Jz!6|*Zt|8L!wIeECH_! zkeZNcuu1Hp$2kD4VDQ~|<4wIHtsQTD>UdFE{te^R_%%9bQ_P#(HO9L*PBk%f-FT2v zAXGUS0zc4>BdocA7^gHjBcu8F@Jgt39xzFFsKRZ3!fK>G+ANZ%Bh&y;Y+fFoJ{U%@+^{uy`6k0#tMmbcC3qY?uh^Vml;?af8HQ4&@5O_K%v`?!CqZVx zq4wh9uJAkTBkkp&3rl`WP0Vq42fImFK?f4LEZEcL#<}3iDgmzWj+Mi>Fb<#xLBWX3 z?PVKt=o&Ya#0ArU1G_i@ilUov zN}_wjS7x5T;*SZ8bx>h*)0_%!B7y1HVT39IcL#*46z~s_b&6_ekbWc91v{0o zSZJv-rX&Uc>)yM#ZdP*LC_$Nk97O^;v){ARu#KfD8x^x}6Ge2^Onpg}!DZenuH^37JAAmoV5rGbxq=nMOtP4OA5C zA#ry-cf1=wNK>4zGl+mhFbXA`P3A2WGzs&gNleE;>lI?;lttn};KCuASW}GneV2OD z+kP3^6`0w$Kr2QXMM&O21sUxq{1LIBDz^x;l;W%EUMwmE2~0mPRu-!yE&XGt1w-{W zlqK{WS&`Vy0&}bsrBh7n*TQxZFfRqkpeM$h<`hM#-*)dVZj z*|;=%qi>wiTRc)7u5T!>M}vPG(nWg(j!Aam5uK*n+1uLOqP*nGy7|2YjQwCE3%qvq zd`jl41~*~4`ID12No7Ml#P)0-=skHp$@k0550#sHxL&rS6A7WCv9af$c(k=4`U z@~ygDo=p8X=}}kUzUhrO!4^Ety15;#dLJ{1Mv40ay6H_L?2+h4;69ySfjq)*p0!6# zAA}hV==(qQfsTb33!~gwTp*l}LXlg%*I0UMIqkt{qgm3#xvs_2L&}1<`swf@HQ$Or zu}uP{Zl3R?@PPVZp7uJuWswuaoeCf)d)L{+asW$rJB((60~&EajThF>6FN**KmF>< z%jO~;_tU$+RWuhFq2%{M41vF`*vcvKgf{Us=0Q(AWC}i;KH6-bIN#RN&`~glHPpOS zCuWgTqqU4(-mJ(G-~v&z4bdAHdm|?%o(iFdfXWM1fc!$UJ*>HsMu;u@JX6XNA&tSI z1K#}_1Yxw?cG8V_gkjn#y!oAxb3Pz2ZG&cV@id3YQWlI(1c+IWG2g=k7z@YzYPbuN zl>$2e%6p^0jzEB*K-zY_8)Q-b22^pm@l;VugNzu%j>)0VLmrQ_4mKzT3I!sa)CX9x z5S|C@GVroD7uIhrBk8n?7E^lR?jruX`>xr=~iE zzn2w<(iYHB4y6;fA&Im%)#eBX1O)ICSqn8JYmIyh}Muf|Fd$K-5kC4rE z;7~^Ab#4D$Z=9_2;qzyR)Qx`ED|Wrfu8-gQrgr`9_w}6#+-Di@PEMinJ*@g(h(qVV z)zMXta@}%BQpckif~?E;fA4?YeB(#IRQ$-Iu?q{bNw=rLN6(KqOPpKjoXdS;KhHE-v;KwSao*8#-DBfEv)HS8+1VR+Xbc`qR%ULWnC8>VbtTH3m(G(v)8HQA^Qu zE)}#sYd1)~-celGx$bV=1+ZVH`E68P#UNTx4G?>pQ_ppO))zG;)*(p?-L3-_1 zZ4T`T3AROe4TNSgJoKJ&rr4=?xzD2~$Kqe?W&J(OHPJ4he>jFkY;)j$^ZR4kA) zXif!J06vJY$bi3l`=EUGcb6p;zIt%L&j3n~X5@PJ<1)O(zd`zymm;v?L3ub3lo*J^ zh9Nc2UoIv@4&YS~j?>d8r`5Ymi=Va_*~!w+&f<1t08D7Z_0!WXsh>AvcQJZ8HDhe; z>DNy;#Hr8yR6ibZgmmwRX}ES)8mlM@x0FwRMpGfW4wacmz91T-lYUhPYf& zL$2agFsvVdP(W+bE+NE;K|$iZcm1UFvRYPk$nqfQ)4Ov@BDom*^3k9B!eb5x<2|xG zfcGvBwLh9Y zj2!^YB@r~wi(4QC0yj<7IaF^09XSPN#;&kpIH)rccrJ|2jTMaLE$m8j1)|g^kL4)Q zV=0#-V+ah9D|qIi6Q%YKn|0cvt>OWeC?SWT$Ft>yhISTfMjyGLI`c@c+oZmBa{;BW zM2;uhKPF$DHf{l9shVu6ZfNHbH`7u2A*C`= znax{?I&DCgnwg5l7-E>Sr;mLe_$6>hDl-0jB1d}bf zW;MUPm`k_n>5RI=Awu!y7viWPa*iMK1b{Q>F5MtZ-%PtlTb7(nFYPDn95RP8-$yHE zO`eb`90tq>OLSuC*z{};OJ{$1yTqZ1lXINUaeDn(*k0#*?b~+gX`wy>e#B6$-V)@V zx&-5^OAEBaalngmsAZ&V8CX7|mDO`ic^tzVHD6z#K}XsAnj4=309=_4vmlpo>t2#} z6Q|^wq7^%O7GTP(p@SM}nBustiKYOVwunJ)?zPT1AuSLmuFwU^r^CyCAPSU4JcQCH zD~mH|xu+8k$b{2P>Q)S*Z60uh7lf!0 zRW~0i%`$-LD`Lsfs^+73AVgJkxCiaVY9xgHIGt`Yi#)#=u}{W=5f`9Jb~2?$?t|%V zi*OsBC{=wYP_H2(jf;kh{yqrzgT>_(=HkJ7_c9D`aAKe6GBqX~SZOGZ0jKK%yF5+Y>!j`Cl{ z`LrNVV07Lkvjti{sUEGq%B*58J&dFQIG0sP=5RSv{am^e%?orPBrI*+hfYEtHn_B! zCwxkbyhjIOOfe@J>K#SD)olF2g&Tm-$gw{;4Wuv@H2!`r>9%^tn_-i&B5Z^im3>R zhbWM~8$}%Xxj~bgogN^2r1oRq;9f_Cdj4D8i3xE&_*e>pa8&al>fkS&T=WRM`SZ=s z<2QqFR;a1h{60SWOiiq|N=<6}C`7CnW)(PEoSqe>(BP?W!iGL?(KP(SQ8&eO-SS&& zq|5?%0WoA!ZwFFaa07ftEsijhh@-VS3A-b3t1H`#n**) zW4f@pZH~?_G_M@A>#}?~T`7Vw#&*7q@C^4KPUgrrw2A*O)w|kFPX-}!qz;{8lM~sc z6aIZg?YiaL>o`QKw`;kWcrqL$!lAkBc}hp@O%3Tlh!T#&2ob=x0EU6F+YLh?zTYCj*kp}g*8Q{>6SstSjj>FS@x53Q*XCIq*hJq*K>T+_Dv&RpydGlmb zSXc~{mO?mU;^q&LhOT2#Zw9o_8#(SN^&<9eUWTPnatU#m>y#`Bao6lIFF#FqBEqIi z>f3=a6E?_@CJSXRnW4uruXO?;P_v*KTOOw&1~MC3{yGfl99{a-R1~ z5<%XgQee5ypSb1?Mwy?QTvwAv^as z9cli{s^?HxJa6*zAc%O7Ka>h%pM4spmTEU%>#-NT^f(+yfCy33+5dou86hrXEN8u%)1|TwoIMXf%9R)SyH1N?9c^a<5TA&8^ zns>6=J%0#8AcioOQ}*>_orX{WW1P_+R+MCWdBnMSm;i;`rk=^y}#&%IbVXfi=Mj7c&aW4vXe9!=#^)6nr9ZJbd;?%h1b#qO- zo^!PLHtT37iqJaj)~v(bSfk&7Wj|ckWD{axWDp4`!fzZ89iP-45QS9Gk?Hx-$QS?{ zH)G%!Rj4O(9&(Q~#;Nq5=yrYu>xuaZ=mwQVOKZ{(@ilCyxrF~eBC=ET+KqBz3h&j>e>_>7co7FkOdkw2TMIOeD+4R;L_Uhld!$g%6OP&i*|t zAMxMw66?tztQmXHWlQQKc_C2F3UN!_eBg(1E{U$1YPPU~5SijC-UwHm;-uW$Z2%mp zo{dgmX5eDx=&k-t7W(V*@7wm%3bQbdAQFbNN|nA(nZ9AD`&^DGR&#i43s;1#$p?& zxSo0=?+Sw`PgXctFKkZ(0?5MWdVU{s3q>P_$!o2H5Mkt_8j>U#W1uq1{Qg$ot!`N3 z5I3;U5v%&L8Ssa3feSL1z*@^I=XgtFXWA`Mt!U3|u1Oz2v~b1t3k;z}4x?jh@=Dgo z3mun=8_i)v%vK=yfNM>=>@W`%Rd+GI!9LZ)n>8+(oRzOYJDH$tizz>iZSsEs@-(-U zU>Cz1f(2?#WKMSEk+fnJ+63CsB)C(r;7+^Vv`VyS);oz}khiF*EVm1!Uz%CqLwmQzKLqvIU(EDuY%0h4(B&HGaw3d8 zhG#m*Yt81Y)N~YeG)Rg{dQ78p>uO&uq_C>c-5D3Qih%;S|Ys#W?K*YA$lf3*YwQDt+#kVJS<~Uh_`&^PSXC)lP4&;8QT#aeCCrk67QM zBhwd# zy48`NjLxyX{R(6D2<2PhT9OEe-FYmSIIl$HvQz3MQRkMW027@ThEd&(Si`Q}|SUa`;(t)ak~fLd&tQp6KX%;#4adMMQ1N{X_9##MqB^ zkipw6K||}&diHh%`RICZ1OP&pNI~D>p%qBkdyWRIoG(W96{zsC?i|96~T0348uqu z5^!Y`)1o1I^&w@nybZfmM8;Y&8C7_8!yX&T{4n~s;U zY-vF9Te6f>teA)&C~GaNF~6%tNX#MF#TfV*XPc9Ra?aKa1bcM}=5$Z-bo* zGgvWq0tBWqaq~@{w=B`IZBFP`V%qTjaXyiHRYVC)pm4lH=|e1Wgo2kRtd}l!$)|@_ z_YvMG9(zQxg`D$_Ah*1XUyK0os=>iaTFs}LibFe%Ua3Fn*3)^%1@1O3Z_dXealC9Q zfIhI%q!k$1OS6Y@N2ooMpx2|!-UMN_nGNa;P(;WqC2+LUds_X2VnwI-)apH=$->UU zWb+vk=rtOK{|^19h)tI({AUU*b-#uC#J%>hKlYZA2|Lm*5{G z$z)ifSXsw2I!K@&u}}whJ372}iHmxv^$-`9o@7B)cBgR-G-fVX%>MAgqOeIG#$;j(^w3L*$RJZD+1{%o0TVuap^T)l>lleHk zY<^Ngq$HP!%%#oWh>hu6Zx}VN%z>YZIGipHaui0@$(xj+0S`sJU^&6@$n<`H{x-C7#~xjcT} zl<*+Fm4a?9Bl#f}k?+G0U}{ZgHLrkNUUF*{dow(ooV{eeA+!1D4+z0#ckQ;~A_7wmgxhP(_GNoP0mC&fDmS}< z+;Lj_TE!YujFhndo;O(@Zl0snQuBh7oZ`HmdKbme7_zPj2MZ6jD?Y~cgu?uR*tQac zhq~k`7GfhE8?(-UV8o*mei&;BL1}kG19deeaFclmItsX4MW=hs(F*U%O4fbO8jy(@ji6;2YoasI4AB6w|v1$I*WiI(M&m z4VuKZ;%*`jA1_tfeF`?8cSG}bZfU%9xrFtU7#dNFofDIn&9BGK+5E}XqienZRJ&H}m zKHnVx$s31h_(Vs|u^+e`{dP$zY68ddd1$#|pa56jZbS~*e>^NG=x;8)Y~wyqX^?l# zs;(#4unHAgZyA_k7465xw(rbuOF$q>X-m97aXM&p@kV$_&PWnFQPp$P@G%5N39W zV>*esz*7Gx>e72oIdhORu!^nKSVJAye!_E?a$f+rP>WPn-4825 zIq)xj!o8GnhnP6RGlrpruU zw+1gPnonmJcGdiKq%3NYj1~nfP-qi#?X#h^z(dz{e1-zC@$8og$yZV~qtPQWZ%|sv z+=OT(WZ-uU&@a7ufAf*Nac7oB!Hu&&5`@Kxn1SS(icH2G-?QD_Zm{WmJ4aq{#dJYZ z?)>*~VD_vY3PLz|EwqL&*&QsazVz;K$?$k+SMetHJwnr>mb79V5G{$aPkvMXp}* zDnL`LBlv-ivtP2Ubt0bw(2#pLR=~lH0nGd<)i&{6v;X9$a-xc$KwwvnZmMHGoDoMF zj5Pp3<3)Poxvrc=mjMi2;a_}LfFq-))A{fpEQ#R6-!Fce(PbUStWnGgyei;Fd79u0htI`*#S@lR zmDQt6XPvpnKAz@X;mx=A6;HyHjlKvY$dj*WA}Aae#@f;HH*4g7s53?lezSJ#WXu>d z?=7o2{1Yno75j;UzeaWfTWCJRGBkaR?dYNlAe!~wBq_N_TXO&d*yCt(1a;M%7a3ay zqYJFLOih9s>8`3S8Mm{Fm&OT(8#kin3_5PECxGwxq4XqM0MoedhU1qRso~DJM z=_m$0F8E%B+TOF?Q66X#A7x*kns%=G0e_=G-GMM<+QJegDG6m^j3B? zf-NO+s{0lfbAKvs@K92>G2ra%z!cF)&9C zg3ts;XGa67y#H$7In|Ti&-%{6Z@KSFtXT`^33$g=fjsPm8ORXePNn@5L<9u{U&DV6 z^kSau1|ymc4jVw!3lDa7shqi&9ezZMUQG+wrn*!l>wE8o^_+oU8K=^NqqhJ$V_Q*A zn>Fi79BIA5V6HzL&X0;=S)H8`9Q=a5Xpp$ZBbEl8v405taU%QRh?6M^f>;t{pA(DH z^F(Nt#z~EgCg9tcVD@ufj9i^AEkEwX(@pKt3)@ZCPd24(?FOQ9il;7FaE2d~P1c_L zn8yBXl|O>YsgFOND0wEm;V^4FyZUm-s;3^%4mgQVttmZ}TojB;!v;<>snSQHqXTvo z9A~w(XqPBdUvvC07mHT0G+k=m+?VZQz4P7D9d1Pgi{$V+&0!}EAtp{`;t;?&Vly@^ zFC1mK3pZRpJ?9SagUg$i%O76i@|@-R8A~W3(AUp?tJn`uQwxI~i$b@oJQ)de_$-cN z=J$+;73Jh1?WR~t&z2oyTH@bBj!w^MA9BO>cg$+y(f`$+Ghx}(fbcnFAZSm@UNb5dcF`B$Ctm1Oi`!khVNS*zt@Nv1LsT=*n82s9t7?-ds63cTBpT z2jcXFbrCNDeLz@#Q4pYWFm}8|d8$?XqWKo#rAuUpe{zRt^6U^GQTnWteC3Vc79haR zigED;C1pV;*zpjdz5?2G`NL6id|kRbO3uEU zy?#oHy%Vdyce`QIuGJ9hz9WH+P^1;h9n+Q!Y~%5?G?fB z^o4s%MH`wT{1z=`#x9+vxp+I*y>&&uAuFN*YHF6q7_X-weUWJvcPB_>3Zw91ukKU`F8C!e0Dn*ml?46X=Ol-fgA8V0WYP0F2 zliJgCp1n6t>633L(|i7?;F+yN)C!o!7G@I&O)OLRc(Rv=yI#V%C>9k( zbMZZLW5hw&*^d|dq@5Cd&N;k=Zl7lJGCtH4^6&RD>>48yTLAN3<)aiK` z4Dc#Pc~{P49uDm8V*>R^qsr$FFpOgkpk{MHnCrom+m_vqxP@x0)#g%rO^JM@rXRN1 zIrWiWwgir&C{YVv89Lv-$!~eAm6kq^T~4oJqN1m0OQSFkLME7DA`>F`CWqxlP8G4W zf$AEo*e_rfPp{H)l_3sKSg$Ss(OCd<6o|$$T0)X0; zx!MAu$=MQBtD!RsQXrtoO^i$Ab({j+X}nzr5!|%Tc!;?0YcI@=%lE-!J6ha78Rzgd zw)Jb1;i*C(a>)-{yVKDR{MB|;GGfcPc%u51=OXtiaKL{s4e|%qMOCWZvd4{{aD`r> z-hlNyn0e0t2esBlDqhSSA>hu>h&3V7QCqP+cSYJi%ZX3h+!=B1>k!*aL7gs)+m$ju z3BuLso)6-KpuXiB33DN~e`|8Wtn7X0aK^sy-?#5CZeDf$6l=#XR&AvM^al7uE@#1~ zEV-<6etUZ6nwDd082vu?QT6Te`YL*=^>qLJpZ<@}4*$WqyAOZx=N@|e@o#zt_f&d& zxqtVLxm)hJ=>7{Y-2I`w=REH@7yRZO&0m**o(*d2xI?ja2|m7*&c@rZQK@`p#5*p<9-U!(`hElsdVZ(( z-;s78OtVTn3*<>>ww!W2oJ!-7^gOf zdBCUmvcORm&T~!N?%>w*BUHdM(gjbU-|PUoszu&BQRZr-O3A;$l}q_!Td^ipd07f= z71b_g#1KeLg;4Ne6&C6{p8konQ>PxARJ@(j%%B4o<2z0d^U1%hdk#ToyPHuND6ABJ zJ5*Tjs#jo#nd#s|HvLShFmM45iXVAP3cb{tf5Y^s=t@xZ(eF#9 z>5Fl4c%44?In*RL$J0QRPk*l1Qs4=k>F6L2TZ-60!RD^B2y3OVSs)HD$Xf#g^E};plS(XntM<)#h zhwSZ;F_Vw0N-LXv6no)Gj%TWd2)B>P1M23}CNP;!kS_lqH908y^ByNb@)(&F+_?%X&LL8F8-1>S+Oa%7PMqh(Rvq+}t`XYqFg8eW zG2;}Ea0=NvW+~Z2Cb{E;8cPQk(R17b#4?!O;SX;k=50y;3Awx6X~mjeISRteCv;jD zeF>rft_<`lz=6Ijk!7ml-Ubym2ux;+L0gUz3^-P5e{jI2q2w#XQT~is4^1$}9V^|m zmQ((=i|nN<#B3h%9{XB~y2w;Jwfo^g38$l+#CNSZ`?{X3)V8V&$P@*(r3(WcA)ex@ zX`d5bfa*!FK_EGFix$Ag{OJ?jh3I%ZE13cx9H8s>6xZSS>vK4j^B>@%!FT3hs1XK+UKs4hBvZ9JB1b(bG zv(^RO%zPIsGcbbqiha3wS2W`WCBo6=Q~@nwvrrcLu{I6DbW!vmK+pt6&JJcM;Eq`c z+*2(1g`o%!1LR4gP?Zusi82SJc9*MOj_5%s*CW^KvO6*Ko!iPtm586aA!5k23P=OH ztvZAg?08-@EL?dws;i=oREYo?{WR;7UwAkc==o|Ip=ItsjeJ9yQw1U)nhWg?^Jk?s zg6Vu9Vtq^J4DC`X?bjE%F<v^-QHD_YDN#FHq* zQz2?8Ey;BBrepYjv>fE(>{Ph%ren{;58@9NQq&U=uQhJ?dRlow=#L*_JYZ=3z=yy^ zNtKyxFfq)kS(m6m0$SCZNl8e7UlgOSl$oP z#`K!@lqepvK{5?rTPPY63bO;t@@LuyY4yuR^39K!SNtHyh%(8h5hh+hk4&NV1 zEk;@BSWtL@MP>R-A=Pih&(2uO^tQWd^_&A@7^7{zUylB4zFgC_z6c4kbOsd0U_O;? zsqSM(T5nhG9C&4gxpen3cj@Rbsv1RTl9W`@akW{KE<#6>Izl5!-PhqFsv9GF%L|y>F=B-RRjs*eRYH`B}yNpzRW|R%UW^5zB{i zzgAy1W7vSM$>?0;9<+Eb@c7XzFPN(411lfQO8Q-!OK#%3@0Yj%xfM`Qi8!2ZJWn3X zA?G(hpP9?giD_b_cX(blJrVqJZB`A~ua2CBv+~)e$Sn#5jMBP&80|YqnNji!u@Ubh zpx$1mbwCbCpYlB`Oq?_$I$O2~!Rx|QZVR+z*Ci;dHwP?*U^qgh$#hmUZ(%(PXb&Z* zK$uTe&W5-=>d3A@PnYb7wFu0Pp7qhohh1`cJKFF>9e^rlT9X`C@~k4H4qu;}N(Ndb*=dBe}2ihneSv2h&%(MV@{uIP-#+SiQ z>gGHvfm0jG;iL55V8ucP4i0WC2CqPVJPF|_w${d6sJY5qa3IFfkXhWoJ)8lRG>+E|~u8t!(=q@0w#gDBb;&yf*2BL{V!)lqx{L-)g)zxzcxNG)J%MVlSS42+EQASg|A1v0a^(`dNPZzYe+aa810DWtsRu$Z zig}m)ZQeAJ0m%UJ!Agi;W{2+R)U{e+z&DdfZQ&K`#Hfv%V)IqcxFYyqefAec09i@f6*AQ->DnCo6N$prw4gK@oI1okeblf&^%bY0=;ZAwcBo+i16~6m-<+-5tZ&>-Z0*fAhPkg); zCCV5vh?l5r=plsJ zJpJs^jao)Beo;<-2?baXG;(4qo{9-3XMn3_%-$gPEcgf_XTGFD=|4|3eW{od?jgV+ zgblb!!eb+@&0cfeAfFK=5V+#UM!!&}!Rm3o4fb(BUrX{Mifp{hA*P8$F6=Bv9t{XK~d+<=fjBT~~ z38n$Qh?wzb*d2jDHGb~et0@_<@}li*7V&aCjRiMb6Poue5C&mOAQEFf$`%m7NoW1D z8IvjA7;m2LCx(^)+T5+y7K_ojyk}z&sJIn8vG(XpYo7>7&4($_4KRM~6o<;S^t`mY zTWP#Yeif%rLOELlF{}mfHQT##k;h%VB)_QOK!1)si~5DS6;Lad8!|copRFBate|SH z&Sn`QxvuveysRMqf_jd@j-7dp4#aBxXtaUK1qKEK?SPlfn|q`GCzAn(v+h%~;iyE%-(a6q26gacZW8+Aapb$)z!b#n=v5GBtnmm4ps$@3!nW&MUR&Nes~qwkb6 z7bLqe(A_F#01E}n&{?PQ{}cu`+@Jf*&{(m!Hfz{S4E}+jJmE(|!ImFjb141JD=G~H zdoY)7c?@`?c{>SA2T2%XERx#&HaJN7_$P!v^{0^tzr4dEJX`NO=<uC%fF&~Gfq`Wdm2P**c?f7Sa zJ&3f6s8gPwJqfhfJu#>l4;>Mgo^#AUL?GXs+7b%I!fT#R_hVIr*tT|_^}cjO z!@O*pA7xPFrZ9a81qc>)Ckki!l?*3y(zfqGfeauPVEPeOkij(D?bL{9d6F<(vKKU_ zgh*g~_d(_1al%fwu8bKmF_{xwiay8jQthI7pHMTm6>+Md*hf6Cl%n|nD!9jk-}0bv z8gc5NTxO6DGORdtQ0W%zKe`s!yMhFG60$kn8{JgF#6h%~fmEVax19RG^u7h`#fJpn zJi$uIiE^J2;4xz$3CR4L`B+Z9+^nI2f%k=1H7%j|t7u?~bLs;@?2LpM{=9dhWJ`!O z&W`kS1yaM8AK{cXr4PIadTMSep$jIOeyp^^v^&Q~!lu{bjpPA^*CPR5BH2);#x*CN^ z#SSD$ku+8ag9BQnq6s15&1;bsG-cPf6=(7T6$d+FsfBLR9aU1w)2Ceil+wHa&(k-$ zJ%kQN0$8llcmFDHHp~O>SQH3hAP|a5aHin3F)-f8K-coy;t1!5gxIX)GHdLa7iJ8- z4ljg^tTxh1-CKYVP-Z!@RKeFMbOQ&*;}HxpC^g_c3I&}V>MB`BDAbW^Vaqil&JK>;8>NqbLiQM0-yz)^*^B7}5NJSGK6f%u=f?^-}D6z4fm%D!Olh zTJ#U22L|!%4?Lt(bWtigxwF+5SWhl_AQV00R;)E4n4AQoknS?N(${Qgm7Vw4(fUia zmCZU{>=sv1>335-Jm5s<09|#$ExZmLmp#A%n9*7~g2pDun&0HWp!bjJ(UIzg%3V!( zo#t?p=`D$)yuwIj>R6z1`J*ij*k%@up{QUPP)m8OoK1cSLqQGtke5E@wYq5>_X;IM zAjKB+Jous9_h|Vf*S*ph_y2WReCgI(B6M%mu5oXCZcOz)8iQj}WY!oh;mrP!4;B5R z>6+0LjF-x)bSAW2?-Jkacm+agZ1&RT%v;l+9$#)>bWHuIcRuy6UB2{1?b>DPzj=8JA8~o~zQN5@5SK^4z4qo@$J*uL zOL*r4-fZ-ma(=LdYd+`d(w7`NcFak~FM8nkXu9_40BWrY=Nu<50q{=iM7SCL@Zhjs zRFDH?Hc(5Hdltt5Yp5Zx==QJ3QR{X@Q-tZ*pTPBnXZdM)Ai5d z!Mb++vt#EYeb5dPi?ruzIc+cNjS=|~-KQqjEfvnR7R^k|@{BdEwdo-agiI$9iLv}v02$KHf{d3I)cpyFR#TA)YmDn&{q;Mqp z?CmV3F6E6G6k5S$Wy^Co*JgekWVl7+9fu8@xpCaw7CGVr0w#`88|3>b+vnQF%a@v` zO#1+UetUl)6fj4wkm4DNyXaq^=s57HLx-7kvw=4sl6*WlL>XR3oJjRy3=@I2ZlCPx%X1djn&sJQ53<%g&l8RNM2J;R+Phx)9rV4lS>x|NuCBe$zfr`tO{){&cI@T>Z|n6?~9UW zD$4rIiG!q5_|+n`0zTZ315F|cd$9aLpnf-W8FS zWt!&U7^lVP;ZcpOw92g102dVP5G{DxsL+M|D|Z*&e?K`Iy@Ne?AzIw2j>9ke{dxyc zKf^Z%|GXB|EUzVOA+uJ7wKWix{FSR4BF^58chkXBT_$e_PmgB9xGi82%vI^n{Iht? zQu(ua-En-Floi_BC6>NK z*zclwRL*u__tJ@b5KH(pNoVkd3cp>gYog1Mp$D*S-lVEhXn(9vkuu#jv)?)>@X^4y)sSQ3{ z9j5l2t%wo4J75YDj2;CxSaEv8=eTGtwVm+W=bbLWLR~+Eb^(lF6`D7J|8@E^4O3=d zDf_s~=EI~0#J$$#^Vr-GEygwd4>ahl!*~|RQX?~T-so^FMkoZJ*^41qEVx(DgGf=} z&O7xumU}8gmr9N!XlW7qSO<`q-K*yJ;9&7>U=n|D!=|IRMjb=?t8I?Qe|xzpEf6gk z>z!n{`n!5GdMZnuv(zuDX!K0;(MbgBV>uoi?6lG57MJERk3dtjW)?eTn6!7uHwM?C zz>Y@ul;Kjw>5=K=(!3JQ;B@$HOyi(6g!L9sH=-1@C4qKph5)db8(<515ljxC3bebt zj}R%#S7=o`3*>Cv>?{b3=pHAu52&4ePDG5egPO^S=sYZ#PYeONc}3P+cC#ahcFZ@z ztgD+ZAg)orZP&>Lp|S%|V7gyBGK79q0G7>+%Y(KMc+W@r z{QRg|^$`%vT9T}6a45>>s08-xvalNspb*cUz}$`6bro5VSL?3}t&=A5`r}r%xW+-d zxe5FoU9I#DeOsiFGQ;q-%MYkT$?f3!T_rvH$#}a@8UE4xj~=-emU(Ioqm^!CRgUd-JM{ zMq2{6b`}vr>Z&-#9DJNZ(}PH10%?8o4$Ql+R^>3-xfrPPk)oaY(Ps2ggWkxM|NfqA zy}}9t!8=TzVQlvq)6a(sY~%}cr`K~GW(N_fw9<`C5@BFVGZ4#mFs;(?;m>skJuXr% zGdz&`*Ekc@?kC#VW!Gb@*m>t{V zNk2^atJW3p8`NKXR-<&wdwL_RaYbm%Uk~~p?Ja;r-lzz`vL--8MDrJPG~_bzSaCr- zWWE?T56c%#^BMXG-`PGIeNbUrb?X3q>~ckV_Ec3sngt{0or<+N>OEfGgNo9imAS<{ z)IH)BxQx`x!~D^@P)%@SMOsNy>N;mGi^LZBS z{aqke^LL@u+#?!)hwzU@MzE#2yKG*`bA5ex=mv^d#p4{q8wni6pToQM4M82Xe`mfKxey9#`%Z~Jjw3drc${eis zbf`P8(zrln_#AUYKdFWjA0luruP6-+$pbo<$D*?WC5plPaH{dIY~G?>5PcrKW`5-W zdP0C`9U&YGi|P^*t@%yBRBecDMLh}Cx!%PPk=x@bKAK`mrLtGPjWLX6rN-hkx0jPh zo)HiceOjgZzw2wh8SZ5XfsMuBT)V(eR5UbP0Y+&f7~w-Dd`6nSRvY7&HPK~N6T2Fa z^a@oG;3MKu@b|C{9L}PsXkK5#xQXV#_+}W>xd}MKN<`i=iev!Zni2$0=6%ySbfX)m zCKVQ7k&f~~FBF_HiU(@8J{iX9gMf!OD@Cp)SXQri-97wNG2qg_SBIQ&Ub?}7ug*cosDMo#5! zEp$TWXbOKdv>=j@HF}W2l<6?IJ% z3)%f24FR{sY0_7Cubeve4U$a)a_l)3R+uLOtXKPpNOQJ60tEFIkT+j`v7D~4Ee&0A z9WfJq1=nl(XNSWSgkAaEZI-Yj1_X>*xz4_r1?E&!1u;QU#3jcOPi^axz7 zit^((M94ZoS~m}$kQ6g!ur=h7_-`F4A5)+Gz}93@p1mR^O8C@t!f_%1Duf_9`6anu z!P>w~>*QtgE5T39669I8_=gZlxQ|`9g^fl03$TE?Gs>3fRew4oB~&iD(P=d0=o@Pc zJj9pE|4~sQJ{|D>|NSSbG0t@F8)F@2&AA)T+;rL*XPjQF+pt(Jj7WPB%N)ZsYn%0( zmd-wFN$fHpna+#Kr=EFkB$Fue+h8Q`!dWIRQ~t3^fXe*#ApWGHmhNMeBbd#?-fjmg z^=3aonch9Cg&M!E10>Z<1octd-X)xUrjq0F_*^f~@aiF6o$1v%URi-@lgjkJqaaC* z%JkK^Bp4v5?1FtHPO?sC=k&zNWwndWg_)f$fYG7#3!*A*-y4h~-eeCUeT^l{mPz5# z%5$GxdMndEL_>tJm+6soBmuPC=40&rZ07Q#N3(mjD$1ziQhOZ{6OZufEGziZ$+{lp z!!u^C(-_2Kx($sKWY119jy63Etr(x_*Oz!j2B=)vnIOGQ0EdTc$zT2YzMRF4vyOdA zCR=i_oxD8DhhzjT)8EI#bzXiWE*rWO)7k+HDN_N+Ho~d_qv9rB5oZv#O8^a8Q{6dF zEwSX}5$bO<_#S=oGWr^iV+1=7q@U4AU#44P5S)l{Tb7r%1P!FXSP&2XRw% zch!o}*U`JcjGuyxtKZV4Uivg2F4EMytQtbL*RvEQT9@h3p{?PjSHsU^R|&{C;qU;p z&h&0rueToHq0X53#{Q{_fwO;AxM+)7>S}i%U zuufa{ahoHHGnoMkV4rJ<#hbZwzDPi9+PAv1?g2%fi1XRHM(yloC+uG9WT$#4eYA=g zU48=CR)FD`9YUcvsLE&Tk^|%k=-5lDpR|b6JRojdnV_WZNVrBPS4tVyb?OjdoMj4( zpg3ysYv*TGpJ)Hd^h*J+DqN8d1T8Ji2I>K1y5)O;aS$Zqa_m8Ffo2(GLGvi67_KV1Oy(an#!F-^@feClh_(_*c5fgk~-p!|gE-!4{YfQIy?rOH8Z+t4a~@_Om)5% zJGE(0hs0Zs(o8Pmg|WQ)6Q-;q#gP>niYT?9B2c=}H(PVKU04^N=Xqg!5y)mZLD%IN z#D$SBrvRgRa`$*8i?HjNF}!X@eIn+nDSE)r1Nc8ksV6^J4P~aCsfsBH^q!IRY+0ll zy|P!4`E?c#0l-iGYfJJFg=`!QhQp%7`v-`_SWh={x}Q6hoiWf96ysieB~$={XFE{5 zZ^=X)o5Mk(NvYGbmE7;doA&`NJ;i0}h>6!8Yid*TqZjtE1*wq5BdZZo43`Z+Wq#}uHZ+xu{i zb`?LY$n{y)3Zpm|W%r=)0h*|-L>p0)-qmB?_Pw3pa?OKELp&}h{t?eauAjlpc)-~F zNbtf5Z{mjsB?r*QdJAkVcVwmC`Xi5b&+_&!X*ZVpVcm&*CB({qL)1ZYEd3#<*$P0`LI$er?ksIhq$W&17)0hxYxTT zy3f)_?C}f18Ir`p@3*l9?IkO*4I9Ud2^JN)V{U(9HAN%!iJ;>`W&GUZJh#`W|PH`PQrPK!p-7-Xg5WGNt>uB-;FQ} zaJU{mytSUl2MiFn)DMJxqcx)`;z-xeQ4N7S&*Ut}m)nu@YM$3_bCS z=kbtTp6u>q^Xj;)4VQn&SHjlhGf`?l;~Y_Ec2KT1vScpXYcW9BAzh^=y3t%k*WwvF zlwnjlQq}*PZj?XZ5aOiU*nNBU!0H)Kd?8$kG+dg?}tytoCvx4!sJSp37l@ zKjEmLg15#wfXBmmOxI}=$+-g#s5;Cm;Nm!O;xFu@NYP@dHsOervQn7h^BBmG=h})2 zI5$#XH(nuGCxt4-{am3K?KIR@XHTHr)NwwFG4QD&Z`RO9M;Y-Pg#Hw90OQuie~pnE zC`>6ZOiFeK_p;bBKbXK4-k9n}3M)7olgKS`CU-d!ZXfH_E3(oO$0rZ8fu(5Uf*PMq)sl z#w5k)H$&|t;BFH?V#Eu5hb_2#C&(BePQ(Z{WqfO0zawfJ1C}t6iXR%o3D4X^Gq^)t z_#LShuuh!FLdXqza3p*SPaI6J`+;$B%b>WHQpV`v&hp23v+qU2C@L2mV>He{=sw6i zx{Ys|VKl_TNbE~$meFJ}Q;k2tdts{-#e{2m%(%IxS5=pz426EU1RppNE>=($D;n5f zeXGdCcXsz&&`z|$A9#xP9aQH19V6wTlmPN(SVu@m5?Sjc0RI9ONr zy%ltCA7!1l)5J=+e8c(_pSW`@9I1q>xCkRWs5EUL@Is)CzD28Q-d} zzZ!RO7%z;oCnmFh{-Rpoy@_fe0hpNjU^2hV}WH6dX;R6V};agmtc* zt#jqjwFFKE@Kb%ODo+T6A?%Dy_fYyo3;LjYtm@cZy0aF~ORPMRu)^*3%^eOj-XpVJ zAg8bNVStXXvt%bZJzZ=2t2wSmC|}B|TdW-oCN~u?8B9eb^(x-Zz9Q_|S3Mz5p+9AR zOYx^mckZI%s997^G~TZ-yi>TlpR!k|4SVlO}pC1;=@ut3nO%*;?>XQVmOfca)8IYFd>kWiqO&%Eb9)ac0@Fj%#=MPwAV%;`@+|nu%W|V+01J7`;b(bOY{56)+DN5@K#l0G=F)s%JVR7?hAd1< zhp~zW-3^$696nK-s9LQ0DjML9+yXgbB)AYXByQvU#Q^#BNU^{7i@HA}aRDc$WcAq2+ zIO92Vogr`U6Q4)`Kpdfgqo%(UPYdGA!Ku@rWir%4e>Dz;$o}DizDi=Nyg3DtaP{^H zl0zsQMW>L7e1JTwf0&i;ZBe1r!-&%Yj9^(ER-q6%+SDiOfhE@)2f$-piqaq7Tuq0f z*72SI%VRxMu<9I3YB1mi>ur^P9Lrck<*|xv`U^rKqs1b=&m9h=|413>qMr=XL+h6XBjEc_2?kS5&a$IKsescaoenNMtkpY4-o`S1mgp zZHAvn&T5Cf`LpeeYFV}4OS*&o%g^Sa3{YdaV(ZRRO~kYBNFd-PLf00F!In2>eR$Ro zSE{51;3_V%VCJLM{w49YtZu;S0C#vQaIYl337fr$@u4oTO^nH>)|Etdk3U5W;1o-y zoLglmTG0g8G?%P1bC|Pqyn`)J6z)X+ z?qRiC=i<$VQy@~mA!>MQ>N=(j%9FVl(i$$a2$In9M7A~r!6T3`9FGX-boN<++g949 zGOUK-XbAPCY9OTuOD|)n-R_GJDQO*>5`Tyhh{zzs^$(2_tqQhT_-EOUKSYO9yM^f@ ztPmdY?#=P?&Cex0KHv0nTIFLyR^Wv`VnlpC_KqD<0ps9?;Mwj4IqJ0|0|2p1OUc^9 z>ZqbIlg~5m$l+UT{t0bw9xjM3lTFiIWPSOpAl`yS52#-s4Zo{h+BRkc8jXwzjkIn) zIe4EkOzq_%UMZwV;OEo`!38Ykv$`NZPtMEdqH^J1=h-}XgS3Xg7j_t*g%gO`I5_Wn zzvk?pK;682Js1RZR~J_n0F=>jtlqW_+&S&MiTTCKKP>-9p+D!S{6iGCj@@wMvx@Gy z-D2wWIF5>qTT>t+0>O-UlxQP7`GMaYl9hcl3c0S%1Z1lm82g*T9#a*}H-ox!HRuI( z{6~hTX$!O?;p_y*)YIq1emPdYdj$Rfwi61$q;#VL3t-w>9%vlE%vJN*+P1eLVDYZhG)XW`8fiY-u@oh z*535KfBMG@@A}FOAGr|~Yjt{C@tAzb(@8Y9suER$Bcca5T*|>jI!T$1Ba@Jt5P|if z4m4}SJv1P^3h-~h^f@&5H0uE&va=A6JR3s`w#OlNiyePanpdVGW5HRJxFUw@@b+3BZ(BzwmjlTHwxKU=FBMF*DH! z9MV?-))^LSAed*G@c9xxw>YOjh$>T+v&S>T@Fwfe{ySkoikUS^-tlT&vzvYW)tRF1 zl1P_Fn~Tu?tenHpjE13S3sSHXUmTWm-fh)8ncWPm5RZwTpN|Cz-gzjoyY?}2G53z` zFQP6+{7gQWI2njc)YaoxYzKOj#p+7+GzJkhF$~s^AVL8RHu~)m>=YK!!n1+R(4*!> zD?r0&c}N()lRX6@AX<%?8_ufvsaq#EGg>X&%3H7lFE5D8)M>nh(ZUQuP}&UO@H~RT zRtIayxW(2H1_k^{|3Vqtq75Ql-78Hz`D`0bh|Rd}G!Oci)(QHcZ^D|i3tQ?C%*Rf_EaUCi=(RX z2(fG*+*&tBxCTN0OkID(%F`Etq+U>q!gaofhxRtWe*w2@HqR|B z^=u9dFE8wvqaA^^e_gmg($~-=D8ciBdxXTGRda?3fUw+hKr`VweyXS}&yNTxNcfN} zlFadn%Qj|U5K2xz0f)drCvV217j$KK%F?LJR6zcb3h!VTFhjMcu^ghf7A^=O5TdNx zwxwXVX|t7&e(DiqSlFO04%2!19cdAH7%YtLFYDtj2@piW0I?S~fj)&;j>zB`mo{Z@ zFqKm4G0>GnvbE|BZW?LHGBA3f-S)|5eVM4HXp>n&dPIUk?)U=jIv$z25L!283_g?Z zD$g=7ZMn(l;Ck)y+eKvH0>|i8m)^CSBS-O8!#Rbr_?5mxNdv*+6ZB822=y>N?Zbm} zhd;(i(C8is9sz`xC5mV!ESl3NKb$QZCR;7-Xv>1>&^_}3w*i_aQDqe=Tu%<$RaTu2 zfRF=qG~d7+T`(YqL4~pC>6~I93=?d|c1m!19ax%tSfk;iQ0hH$)@cjy0V?#O`d*Z* zVu7QKsD)*Td3f6>SK(8cV%kAE2CD4np3|NU!5&w?hew$7BmMJs8ex{!qs^PxRA@aRenT^zV{K;R0fMD5YzNG@^m02L6n zCP#42o6eKZ>*@lgAV&38Fbb4WN<_#qJ)+l$4$C5*Bo~&1r?%?PVKIZ!jHg4}ooWH+ zPGxRfayKqSMuC%8_Xk18?B-mj+!X_#G=~PV) z(HS5}>+8c9ozMVcVD%B2rX;hLvoQVU|C#}3)gV^$oVcVjxfL1N$Y_;j=q6_b%BnBd z(KTuU>45ZF!lzmg7 zhQduqe8w{bEzbPuCDI1Cnu7lB@`Eo@-|)ee4c6@T#kIWn zkQW?TLTZ9;`B%%UiNo^iG* zEL~d0LV;e&)ysKwU%>b;Q~N!$kuHL8g*(q+Y^$kbA)|T>h{zZOqIU2*nLAi#6@pXf z-{65Q-7n=vcJP9Qbyw><>CT)Fd6hpZU(Y^Va~6jTRL=D?28OU)Uu6Wwr_u<@A=56> zZWZ^$!F7-@SV?lL>tsTwvmYhoJ(_ER$5{Ed;qZ~oaPsu0GiIkMcDW&#tK&E}hl@{V zPv(3T&`8uX+&M-PAA}Rk-t!dccwCLj+1=5~$4_sPm-6n2-~-SL#gO>M$Fr0N+VIOq z!Q{EBVZc1m84K8e8A}PR{wQ2@eug_$5@ureXlN5fkN{N-Fa$tN7y(=SBrKFI4cWHP9z0-@3J z7z_*lvSuH%Dp`^kb6vVUT5Ezqy15xEvb;d04(ZKBeMJ3-^^qtrhjVN+p~(K#8D#bd z!xTyC&IClN%8{BQwn~ojPTCdokkyA1CX^Sg4BdOAM(QB?AHG~4yM+OtcR*pJepGWe zEH@#|qRyPypK4O`as!NKv+{C#LNys#d8;Y)!c+$bS1>7Abd=_|te_t2{JD4q@2T(D zOI9E=vW_q;8PZs}8qL$8!D2A9?1&HJGnT);4=7e>VaLPNCr;$MuFbqWSf7g2r&wi} zUtQ<|;l_DaQJ+@M#MdW^@2+ITaI)b!3NzTWXkNJF%MIaoRtX$0H+C0i&hQv~n`ywY zXgBxcI#oi(Wgpk%T3+7mzNWxYohUQy@`239q&nBZnm{cDgSbE}g$5}<7@%NJhuH&v zUD09vCM#cVz)`3EENHLo!@8pL6P`iChn^X8YS@9~d}xj)e+7p5pfE!*JvxdfT&Sr$) zaHrnEP?)lS149VQ;O5*!2SDoB;dvSnmyt0rD%U^Ip|doBdD!yND)$TGWvov{MLh|m zmDh38wb^uvJ5T~AHI=qab+V!;a!{LvIX_?N=Unj(;dy$GT&#rZqw@bco%OXg4KGi{ zQExLWA}fZ|0U%y;UBc>petn*gHgg?$Mymui#s<(yStFN3-j27J#jqO9pUw9qQxe}p zgG2WN8A;U6>_TWsy$d`U)r`kb02e6m@~FFA|0?84TNdpS0lbFY_dmMtzEd44J*AtY zRY1~s33(&z zFs&XFDD7lM2#%dc5BDse7V&3hav14;by+?UsHQ`FI7=k|l2|UoZSC*HdBGTm#zB~w zY4AkDGT&KwJ*W^p*~x&4jr@!BeLP~s)NvWdL%p|%*r3Tabzv%9l|I23ZQ+7o{8;lY z$kjRDp#6sRq=E-h+J?wORpRDOgF5)4ghy)7ammvgo2MuX*L%q$?1Wy8A&Gg=t9g$7 z(5ojm6xaC6`(5#S6t)88!Llt!W;gig3d-K(GeRjj$8<3#5yf4-6Rr+Cu{)G#U+zS5 z9DqsCz^h{qmxB{s0S8u@-M6DhqbR2?)986QNPGL8wsRg}Swmz27!O{oL><%N=P57G z3#k)FX2HW)B#LUvC$To0bqQIqa+-4FSlVa5Hm^s^h~c&22Dn%*i9*i!C9MY?#MJOv zD37eg=k9vIjeBn*6#b6%x0)N?1bF*X%~ug@fRS^`fc(hnT?+tIbfLVWP5eiL5>K3L z&70v#3?61PD^F88V)%p$Age!j1mmBH@x$_GOP$SVQEo-`DEk6BblCwE<**Y*Kv7AJ zr70q4+9}}~!U7{U1jYivv4C%r(M$*NwuEs@ZJ4Rg?ri?!h>E+Z+M}%%U3ix(|2cboXdFdl5-4v+^Hsdr1tu zd?Sp6dPAUv0ft=ClXvmERssM9j>FS5Lg-Ka5;7nGm{sFxJ`# zhg%q-HtecRc3n1@J|xRLmxT843XhfR@L4Dp5s&j$2^Vli5e^ma+2nx-Rg}QUI z@;V}$u|Oi450u4YbKHC$&u7S0LE5cbPh^iAc;%V>9b)CwkcQhU4#YGk(NC(09Ep#m!ZeI;d+c2ol5gLhA%e` zSEnn{#WBn&uu(q9Wg;GXxfLg|v9V*}CmvfNt_8ybV%R;OF`w-eM1FDjzyVRk$%yfSfNIF)u#fr$2`q-i+3PPvz|1+i@abB6L^R6nmRY@P6`cst_4#X z?OU(Vp*FfvUVx#bB#{So%P+#zy5$X{j36{-2C+W4(y_Bs%0ffJ9al(XSOe{0{)1Bp z1q?joJ{81U7Q29JHF|CNON0~o(zzL{Z%t^U0iC)Y%72n1dS9dpbprM~OUn3IgMI z8dE@+x=jx10n;jB-4#I>S>T%u8n!9vl~4u8FTWI)-&l zRw=>2_#W1zPcG;gYh2!>Ll@&rQURDrtQ3!*B*g&y8DBQDHJu1`R^&9I9JkzXu4HCA zQB>D5g%_r!!20^103AA#)o;ILwEP3uAshn&VXVstnDUn?DKFPHm?VmX`NzlXOU>J5 zqH657L_CEClGIST6l4n3V7Hckq?-*PiFnHm_;6M~k(W=mE2H%VJO!5MJ2)$V6(4gJ z2`+`zs8ItCG*B;R?XegB_yJy!V*%im_{wl{z^!%pBcV}Dr?z2u)kkgFX2P$@`sIgF zZsWG{NGu?;*Ux9>p10xPm}{kNRF8VQE^*Mc{NN~BZN0E`elUG1MsR`Zqro!I2M(<7 zL~u$VZFwC^4C8x`dZsn2E0eH`ew_Osenc3^k-++QV&J<$c1#0(HX!baC}uiZB10|{ zIP3i3-3ivUHu+kZyD@RifS6!gpgU9L0D$x~bOGx!=yeW5y!Po#$n(*ZU4}^nQ_&Se zdt|+hv2@FSYV3BbfS{@ZszU2#B(D2uxPk60*Mi}-5x-sE`!zBGzw#Hwfhm*NUQ=QYEerXM=tO_0 zR4DRK4^37>0lG*KgILUWx8^JcC=nSBY*o4dTvmQ{La@d1?cFUDQUdZ+$yiu1y@gHG zi>qZAAu{H$gsybu@y8e9%BruV>LW#amSW3OOydm<+Mum&1@R2?>^amoBDvqH|9?OWUpPs{QhZ7R#1QaoW!0;{BH| zO(y)!aI<7>Gh_m081gzGI$rNOuf=2N3CTy+0UMQy}D=u(A5z7ng@p zWnJ_qolA6~a!)Iz_mUVw;1=*b5I1YVBt*+;J#kVZ-Hz3-HuB^>*uaH~Q>I1-u?uTAlA|%(?0yIqsh$2TJ0#2MTalhOgl*BOIUo@Z07sx-;73N8)Muz{H1@VGn_Y8&&VkrZ{N0n?{X!UbEw5T#jw1YqU>LJ`PT5i+_DSU~os0w8!u z_Gh6MnI`tn($viRjz|EO0^Zx{H3wKYc;J9nAKNOU=@whcnTWKLqu!IwmSU7*NXwZ> zJAd&yhca|X_E0voPzTv51nKEim8Mv5;2WZHFu?hZ>S;_bf6OxiZX3v+CR+i*&|Cpc zppaJBjUN6$P#%vokfw23?~%)Z!ekLT;Dw^j}*;_TlXDXpL_TmQ#;U307A{uV2zUOYHPXHgi1EKF=y3(sq%3MUf%fNL3YQJV z)A(uO8g0bb9A}`1c=U4n9kK(Nv9Y)xTE8h=)$m;Kx?l>BZ#v`e8|^FqYjFy-E7mpW zi~_S$KZb{E0japnvsjb(DpxT4cprya#$_ld5n?ePT|V0DgJhdB`-k$>bb9m=*)!4;fh%8G z7eU~_vv^W)y>ox$yu*$4J!8w{fpq9&U49_kBeQ3i z<|(yP-|#7kToOI7F&jWmI?Ka>xTcN)r>fAqs)ZxQ)~2DVvSjsFEk4n)jy9#G2`QSh_r~LQ^QGnL^eilQ$awSF||M4rnCArV24dc zdMXT?1L&jpa@M$$YGgd|7WA5DTkFy7{EluX=p577l~{mHHmjxyB{$ei06wpnnls3H z5uBbPJ{-t}SwcD^nqSdhJxM`(e&5v(n5u z#ZQ0v8BX{r%0_m8QG-FwQpZho#hiY3e`CMs=sO@36-th6P2FB;w{&%>|4U=zKz%2$!zo`pP8jldEoWQ(nh%zi5j;3rS6glJJH56dTDiQmp* z=L~xqFt+HAgLiisa6|zO{as=Z(Q#$BbeT zXW59+*5WF^)DHg@VW`RD1I6i7uE<;{&cNS^+JR_w*AhvtUb3Da45@YeEYj*5sTOKo zja2ySR`Ejw4mMlG6ksVq0T@`{0WdDS;ITw=pS2vaHL&&mDpHGy9g@zFDLg>7ix`(C zKFCttUR;?h$gJl=B>#Qihh~s8bd&nVR~P4gwd_G#-E?~SzL7rT2m$o4P1*6)DsUC7 zJf4k}S@kept3^aPtJ&{Ct4ZINSB*DiuNt?k>CzGf!6WWz1@9R$)y9Zmpb)A5JztcuWwioep}LSy1GE4hIknp=2Yjnmx)f$^6Mv~fLUs5yFh$bdS#HNzEx8tV zRh+O*b`az7()w*}e+g5e-{$)quh9sv$r(XFmo5-J|Dg&ZIBD{4Gks*t>KfX0~niuFt+ji3g3QJOZhb^Yrgs7)`b58Q6t-H-5c!u) za7Z`NG6pc4jJ|2Y!x8j^@FKXE{i71u_?F9_y z{mHB>0?K-eq1EBpS+k^fPC=^r$&|)-sQKBqpg9)ibnCcjR*E|(jI-l7(g#eSJLjSI z)7_oiHilQ^Ax!IEfFNm|pz4F^o0m^FswfLY$itaCQA0cgg&s#-2&s6%G+?12n6x>L zyueaf7=wcA3Sr<%jCA$TAovIwqbq zTqYSYiPUGpu-1>vo+P_2cZ^tRC~4=ZUi{`U(CT^6>Kad+(y)!n`w!vWh;zuk_Wdbx z8&tlV35Rt&WJP~PSif-2qL~v^5UixIb>Ad+^Mj;7M)agnl;pwOtuaT%3QtxcpNujP z>|{l<)|gh@18=~*Z`ADlIf^mc(icBIn^pVE`U6Eq>oZ$h`vXn=WBLnP8^bc04g%Db z&k9sEU9BL-k@+B^^-^iwsR0W6RnxNcaCsWQEK47N)kC1#d8!RBOy`!#?fu z8ecpLkNa9?gV22?i5qpOaz+DHAyKz#7;61RJnTezDno|CVlSx7TkUl`;J-lcwXwv* zW%A_u#hHyHnQa!<2fwD`qWJZZ3$EEirPIk(Ykg>w(VtQ|ueBQ^1* z{N2SMKa4|49Ou=jwr|h5Xw92R!5Qy^&@EEPV~Dy*GnwQgs^DtWt^xAEBApt;nq{Z* z;r#=#0%p65+NJF4X(QMZ=Zoyq`g>Y%lC)n8g*a*N5kDQvr=V8TZ19;Jw5E<~OPrp? zxLK5Aq+RQLa&-8c86q7|Vv-Q8^0HBt%H_#&pnGcw8_yabm5+2P2~=IGPhcdnO`|>g zY#v_BJPL^IE#}Z-4iOA$W9|bLHr97v7t$Kf@O5E(1y&@94$wpk6)p&rOQ8`1cd|IC zmwB3^-cShtDu{a*hJ3ug#v&9k7bZqV`F~tngm&Gixn!yRf2X-vH`WdEG$) zKHXhQIY%nWYQj}>jaoRdK^RqvkEdA!4)ppOFzt5Y1wfK(T5=)6I7zjL^>uDuKX!Y) z=blJyiy_D?G0rmWR-=l3+9CoY1G7#B4R{vu4@@w4sJ)fRIgVC?-)1NXnLuQkta5=8 zj*OXUw1GHy7wtG+@j<9bnM>&9-v?qPO&XR`miHiUtCA>PNF!Nw^oy%K_rr_Ju=MIZ z55NnC#+oMGE*}$^hez@Bu#^cWTV3n|o`8LvxmSKAfttoar?qFyXELSp5F!y*!PWpH zoo|Z#*gZ3DG5t~bz7)^swlsGz`B z{h9gQ*{7qQ7`{Q_hNnFB>6COugUZr4n5Y?nm3?M%^qr`Wg1R`_K75I z`90H4CU+&?8X$&SMFe~#MqL2n%Z&`|R10I~giyj08(9R>qQiht#nofT#yqjS9iMoh4bVU zz(%-Kg|Qmyk7%~nmakxWV@b8B3kfEKVLP3%Y0~UsSx(<6NI=#W@6?L`$2iFk7DA8* z1bOrq(@LA=B3d|ruRPr-F!}^;lG;))Fhb=3o8|qiRx|s0ve9Zl(RM{H{E&3^kjtx` z+Vx=Tc=_;d|Dhq#pjo_5z?wx_&1a%CZ@3>Td)Fi2F*nSyvPkvWsrn7Iofy3yPFE6i z)UuDDLwX$G0IYtjT3J0bO{90S!8wV__)7-A4{!nkCk}wi>~Px+G!j7Dr_`^-L^&ig zDu`(m$i*r3(cA0aT-cVJnR&T1QxjsmUG0~YyvrOhvf*NX5xhIJU4MyluHNBr1#*Q< zQV60$e5zSnn>TMw*VI?+^{k?Yep#=K&P2N^mx<6)yJUlj_O7(Oj|$!^hwbHT>~d4Z zgF)ayn;|bUV+J^(;V{!fS?px*QGMmJ`rM0~T`<&(#RSV0?fy5re_hl4U3UMqc7K=M z?}lPbv!Di?E-6Cb8Z_Oo5cQRA3k8?SaM7EkPZ+*7HG00fEm95LHbwsCXfIFza2<%C z>-eU8mFA0TYaV`P9~6QkXVr9VfhS_3T7*@5?c_TGevNf{Bgz9kd0G zn1^$`z)d9zKE1#(^vRK!Le|qZ3gnEpeoS#q=g=VAzZY8HV!(F8V8i`6h zZkR_oU>`gW_)It^7Y9-wLTPx!P;Y&}U?&o-g4~L4=Q8|);MI`Ph8Zok*cYh=FrS!l!tGwDDS2q<}Gpw?oJs8htvWdmgMS#zg-N^~qsFp-) zFd9^47P)Zt;`rEmeyhIbXF1-5K9*Ud+qJh$;v%en@MG|SCbRlrm8SHsypb$(v+t5;-ND0gTUf(>rzazn?JUeubVRbw5lzG>GO? zwY5LhB65^I!`{XMJUSd)MCrHcSotufllkQb!<(c;Vrxq?j~{T~+ptavwn503Pl6pK zEfqwN8t@GBKsIAk)B~N zK8IaIgM-hbhSS*Z(-MJ&ZoeC+4OM|wwj9_+%Ut2G4gU*p{b*})DtS-_k#z)n)=yIF za@h`-JR>XzKe@D-5&m#BFW76YQ5n>eQcX=bmbGat6ZqBffFbsA5YrBO5nCHmyzB&n zjU3I<-(j{aRse>bHo#rqG&`+hoiVImdKy;oP?HMjJ;Bi6Pi!`SARH&m{lLJJGMS7m zG(8}Z3|~iyN{ROeMA0#_0x$y`D$B8#==Y<51oC*+ezvu=9l6-pz)TmAyqx)jmou!Q z{5TARg5lu^4WFpY^dvdV3C4$<>W85FC-NeKF{uLMh;0Fmci@$QFu|e>!Cz!AsCBHb zyh5LXJTGimJzib3wEBwkwdl@++keNt6AS_ohJGcVr)M#0;@8}oj;)oHvS42*W3=HK z!GEETHG4d@gJ+4|ZLA6LpbQjADT5ynFoW0IFlJ(wRTfIF5jgQNFDrC45mRLVp??H}0mjQ~dN zOC3tJun(SE(&sQ99N5YE8mH93YqNevJz2e9*rK3#edDL3)Y-~KSqB6;e?*x9{L{!_ z{7gll#Atol{W>)2M|7x$rSRRb`|>Qhf3>A)I-hMtU41wN0CAnLWvsi>P<9c1SMN&j zXqIgf6OZ+R1{=^}z=tQZ^ClQQ$bP1`TWtbBms7!6o}Q>c*uw7j#?}itME0) zzLr2Y7OT>Jv<=0ZyacBSls>sWGx_dgD@?%Vywv4Sv#JdxC*VXxs;)bxrkQkl4rHR| zXA}IIVjyOh{$nVRLgQ`34Ud!2hvC}*UxF0#`jPeew01sdtuV%1X;l+?Rkc_gS|=!a z&{~4P?0g`yUA+_c#h{e;rj@+&uqXY;iA?oUM=l5IizFy9Co^e)mj?PAw0GixXv;cp0mZd9TfPMP-4aJMOVZKl1hpJz|EVt{OQKMU^T#`>KL?Kw`xc3lY zU8rDKMofUKQw@p*s+Ik$*w~~2z^&Ja@$$Jzul0V=r9WhU6*w86Pq@gN7aO_EMFmt~ zE*lyS*QvXdf^G(_!}0;^IxeUv&^Hv%hHk!g8yJE7Kt~Ux1_x{WO|dxgbyOgj_U=~s zdQ45;n6OM|8o+`e&MN9x;|U~?HQf;ALC7pLthyEi6P-ox3>7tcO6P!Vmb_P7xnQQ& z6A{8$jI`c0B^dlSw~a03qMaPR?bu5@q=#kYVNz0gu<=`aTP7HJ>Tpx* zaDi7A1b#9qrmcyDR3gR7jC&67j51t9DFJ`TwpmUC3cB6*feCd;SK(X@q;{7^D z@WhP1rjAh%-)>sk2p?`9d@4FzwI5xyOHXq`mJ(1e1EcqkNf+$AMYeYDEAkP0Pf8Jb zj{!V9Dm!q##e;4Ak=8~UgbijM&*=z}B0S+(;h%()n2F=8BIfej-@NLA5yetb|KwBe zcuk41gY-q*it^cXHE`qq(SwzHOE0rmt?;mA}g%gyPd1I700)$E;Z z;{>M!j_snp`%|yKAU^-rH?R62pIgygpL~~B_LW>9ISFhi4WhvlQ8=L$c$Hvk(b5x< zHSNikhajcBmj)n_0je)eu~G;oOf=BUYMd=1d&xF^#mK?*~b2u zW7xe8UT?PR(QB*QRzBOHym7ODCamqQa58~0%;X=j+8LgA^4M1QS2^dm@B z3@IcHVM6#hJ>~gKi%@)UM5snF*mKea2Eriax#dd6D*|S9;qJaz&?RLoZX<{!{o^FL zR#xOlVah!fUV}CXkQB>2cxJ+QuAT-$(pq$gnlVF;i^(ULuNsWUXawpJ99_NL_w_xR`Gk+Zy}uWl_-Nes&7B-su=H5vi>KX zJXOpW7oN&wpb~cKALZLUY&(f(3bo4b4ry~%02~&x^)*gcoC6`$J=MyyLbi!|n|NLf z0?I5u8|uT_@*ut}kf_n-Dnv>u8~niqM4Fvu0+gL0fsi~v9B5i1Jh&0L&n6^y#exse zCiKr<#Xuo>0az}S^2po-Gbvw(SEzgyx`AxrAb-m8Am@?1NbJgy0a-mi?eZ;rSp;ni z`$h+|0Stj2g-tEfb6D`8g?UEep4H$owV~KiDqc~}jVNHWk7yN!_pEMrreUxg-2tPv z15^_q!SEnpi#~NBpRtO%Y=Afb792;)5b49wgZwF6kv%_uQpBgW>i2&bcHFQ`K3&gi zzFbb?mTe_oP^&{2lplhlwh2WIu}=>HGEd(Fd?Y)d!SGfW$D&QwX(_e*lLP{g>Ka;5 z?#spa!(}0G7*+SG9Arw2E{%pt*kWe`vQ|9MxR^=qe575CPG9xC=;Wr#`7F$ zMZreGW!)d!z{03j*oT;F@wc!Eg`?X2u^Mlny0*F^h1BF)x&kC(%ZRN)FB;CX2 zk$bIaP)cY(_{3AoWAmDQ!2nilTU#;Sm$e+ z%QY4$|E|{(i5D=huiY_w`PsPa1FO9In(2Ij6u6fJNuMzyYpTYL!-@z(5~yrv(2nS){Ppf5x&Tn#0vb?f3m1SsB_VA!4~d3A9?FNUn)X z<~*hqgI-N+;^ys!;?B%)>QJycXGcoXkF(ATzNkiyU2#QuLTDk6hGUm9`8!7Cwr5jP0uh zDIai2jqY~`$)+`N;AyP+0sxIbq&r)FlY^k`&hfCgsU{*fX$_n5pn5So?;}ohH|HXn zRgxKUpRu+Z4L*+1Vzx2>%6F9b_`H?et(nJ^EOGvk5P<%5_n+`7q?_+-Ken=Y~2? zmY4B4j{5{|=a5N6S)^(pI57k~vqsH*keD1QY`9@c%LG6wr%NN{V^MWu%7<5>D|hR2 zdvtS@LuQ#$=4}OlrM#V}Oi?Q3G9D(mL~GsZ>i?y;x5}^PeKw0vFvDoZ?201sZ6`+D z)%)M=LjuGI2uW&bod^!H4}<_&;!I5;?}4qO+X;@xn??SX0C7q!zqS5UK@28SVP-12 zHbJgrG&%g5^=0sA)JR6d4L;%xuw1SIhN=YBzIb~S&^N)>^|*dqbHzUW3=G3QCUB2R zuFk2a%iy}3(;5sguDU5}2z^!`_tZBR-$xlYw+p>w{h&z|!-K670(l{}cCGQ6Jf)Do zUqyq_O;_Cb$@gCRZ#Q3gcbv*(AI75(cR%AxPt4XSeo=1o43x1Sdpj1TWp}dc`4L(3YemIjl zTgZ6qoA}1k6{EVFOrfWjZ)tI&DF86eC6-~7&UKSKnl6SzlKaKgV*0YSF2M0DNly;; zz&_i2WVV{!qc7FU=qj+XO}BAbDzhM%@|R*ogC0XFExH5wve2ulnk0iuXa(t}6lv5|VD4p^*Z$hW}E1%s2$d1LF?1LrCU zVJc?ZroOpxh0{%Bx-Hwp6v7%f#1B^g>R|Ju9!A$uYRO_3g`-VqjMPhFdhMR}MvIy}imj>>9XshR57usm#y z#45QSLa=B(Dl5kw=5xm#vOv+CHO?E3J46vV5_F8x8~@izv)LnrXTnyjWL1F2**fC1 z%FvKkH_X*OB1nNNu2-*8%3KIPtgvZuTZAJ_IBSW8?&by#jo=(^bde{Z{+p(pQt(*) zK8Rj;xEd{=@q_BE`k{{$@T zkE*E0%&kx>A=}u4^{H&Jt$+LWZuz==xmG(c*ObY~!PulBLH8Bj^ziE73~08OR22AJ zIDWbKIE>Y_Ded|f`F7PF;w)R3qlEQD!nBc^jZOeb0yd8&C8M~OxoZsrkAUN1tQud~ zW)4RkNMew)&`iC`?Ul-kHn^qA^n*sLRiV4uwWTqSrvcXV?X`J#8MqQMSbLQc7$9g( zmyC2@{qejwAZ1~hnV8G(I3O$jsr?lu^T>6m-oS zZ5yy~AGUAJc2epV`l~@M+F*hyPx#4g6PUwzbd`PxR`+!r{X^_y=-;f+WCd=RWChaD9-(7;4 z-M5igk_s))R^8i(G|l|*rkr19`9{j&Ps_;ER2|;BlWJgPu5=RU%v8vnTY_^eZEqx& zx&1^YqJ<`ijdb37idYsUwnF=tnQpd0B1F($Io7M*@xdsPGN+>oux0IC@nq0~=}>cI zfHi<--w${oiM8rIH>EZrAJSO8UPTk~(` z-^g#tZ|1-M$iJT7lz%P%D*wKc-7Z=l_;}A^&{-xqNs2 z+59s+{}=M*emehDer>)h|L6Rl@=xa1&G5wfVXEYw~mQv-4NyugcHLUzxume|dgpen$SX zeg3^PpUF=@?IoxF!{7hii(mXdPkGUg@{{@Rg(q!)!Snz2c_-SV_tCp;TfdzDKPUXn z|KRUmKNny==fD4zub%y^|NFoFJ@fcyJmcw4`_n)9E@yr&&RsBA6? zTB=Q_{O|>5{Gi7@Tkbege>pRk#z>8;i_=JmQH)%Q&rOF~!0|0vbqr`6abt;v)QDM2 zi-0{f#pKo*G2V{#Im1mxYP>&jxC!s$frcLj4uhJvYl7PoQ1H;EQ2)Z!Y8LhA&wpAz zm1JO@5L^t0?in8u!=d?`wabkM`b8-iatJQJ zXOhsOZp)Enlz(xvRLqPvhbVSDu3)Ub9BmL)F7-cF`s@XcThg0))k_CR*g@;0CKmKE zR@hU$Gp;|15mt;FQM{U<>w2!^b94bZ;^i0vB(7%;R4khysL71LP7s`C+Xk^}kpHB__qLm^-mwQ}O z3-+|n)EJ*>*Vk%v1a7a5u0SI5hI(vTwtcAu&^$X?5hL}_0#YCrXss=u8?ai(6s>kU3>IX0={S)>27mQ>=R?wH^4o+u zuly0*OY3vr7T7`(LR=A2E%Wg@*Y9x(;I6F;>g0?P^hgyIaScF#d=8-{ejBVkZ?4!O ziE0LlscDUJb zyuy#72!Ct<(xLM=b$T!NjcoumpYkj|O*bd@&Wx&~l{4aUn!RiBQd-FfzR!9u^9A3k z9(w^Zj-;D__j_!^?Zkmywp-7@;F|K@QY|)ZT0_DK&Qv?{`f*i;+` z2({{0tf)t<7w2b69W~$aC~97()nT2W*&e3c+*X7+b+(qj#;!kb zQ+3v*$gKk}H3$x%92kKCGsV+jK}3abbqRCN${0az;5@NY0BdAhAB6NcxB6OR9U+Dp z4crl9A?sZ~ix?_!nzkrMVWgU)!dku_(yqtV`=k2tZS_}wg#ihKB$RQ=LOcJT>eKLO zu`nH7u~)tOFh)k}-7!W@{M{YAoBUqiN!_j+3MFeFMCb^F5Tn~?Mi&=Z$WF?^CLpmuJHHcrS64I&ok z>6P^K4wCXxz1}jgQZTNgb2{+y$VPEfw#7J_@%kb(5@cQys8oRq#K6T{Go#d)oOr8n z!Rkw|4&4HTZjS@zTf~wPqGnF3w^$GJLcdcgU}++zi>VPf34y3(4R zTh_wpY`h;%H#tj$dyD`VEvQ=m_Im{0)H@g+OQ7~9g;0g$!#0KKh1eUT=gq+E5N^bb zVY(I=l{Isj((w_V?}QpHM5cbZ1Ba$SH*yl(5bfUY_)3lxR1>t2p{Dz6Ookv&-*j8% z;T=*j_AW8?K1{5lcr=OhKk9;{Od}}0_nY{-+NZ`}hd*SlvUHmErNGqlTjepyX);%} zXVj!s=-#j5V++Me+mxqo(bdS}ntGES#aCQ5Rc5_kHba?xaIX(sK1C^Q_kJ<^8UX+t zony~`Nz4=ldIEY1DWVuaOPbR$?Ed zK{~|&n-CPO@_Kkq*85?+U7I>8;H@}87_v@feh_7t=Hd6l610&@+#MyF;aUqNLfj2Y z&erw)roE=F`}p88j-7LqIqq zy}qF^qc;cBlf-j~76|?6l=3zJ%v;VKjthA2Ku0JQ(~PeE%mn9 zp%v7kPd>T$;W+;j#35%EgT_v4i=z* zdu)!Wz<65tq`LEmhzfy8EoAnOdWY=tYfGsAcvBX)nq{9!uy+X zua4F?FwS(Y6oLU2e+$*$!Et?A`2|@5`83O)GL>-@nCnI(=_oMFizzxcg0Mj?hzMBs zO^Vs9#jY;9E`>=r2|cr+Wl*1dyVQryFQ-;Lc>`Y6LqL2Anp`kh(Hocr2n*QiB4|Xr6`7C zL^cMEFotkkHlxGhNav`0AYz1?Qja~a-jkike?&PPCGQyOySt>bk^1{8)4PDqkppFn zgwiGkgb*AvM!J6$v>J3k9}*plW)YGzbPxDGc?bNC7TFm@E-e<90SmDx98;xII9cw5 z12H#3IC)d-AoZL$><_F%3pQ-!wlCs{CpPDvo8Gz^0iw3Yi&F2*YW!8J5wRITfv2 zMIA`86%B~iAA4P1U-kBwi0!O(Uug~3hbDLBYz;y(ZwwBoAy9K6-<~%tA&Y>JI7~+9 zxyhJ43b8i|PAEL-DlCG5!MdbY79HlOmFbpRAvsENx|kD9-qXwc1xqgW7gE__yFd7B zD48@YNnmUzk`QBVLW7VbM8efHHaGB;bjbEOC=krG#9BjYa9ynBmg5ru^pC@t(ydo9 z=W9vG5yjSFG#VikMiyrM#Bk>tK5r{6Vt0sV31irM1g_&TR z8)56~X>uL7+mzOKz|%(prjDs(y87`r6@z~)TA3Ye4(;glI(Wd=0qb?3V3bRmapLL|3({1#z{U4aWB1SnULk7vgsL6Cw*1h`W^- zC2FRXs_MvxyOBYSJap+WR;up|mSbl4Zhv;LL=XkhPBDgQw<*Uga0<%uCcZ*G6=ukg zn!5G3U_Ehc$p{?NxiQX8Fg2~Y$C;oNb{Vf;PH!AXw|=#t=j@;8e3R?b6W8NuNl7*` z=r(NCkzj-C6F`^7ZOAF3xDC7YL6lxXW6q$ZVVwNTcZ0@vOOhKDTr`ABvxa^4FxDv& ze7&T1Q;>Fh8;9l4cUJfK%i3P3cpe_Hjj@1wBIVZ_Galwp!j^gFIgE*7*!P@v6B?b! zGiXJ+lPgWK55la%;1z_1ugUjpdcsWx>6|toMPddsdXDvzMRnVNW52QixFV^y>#sM* zFxpW*)BtPOznpsrOuKMdLp}hm`BdSa_%0EP^{=vHR;YW1Vuv*7y9O$cqM~)1vE600 za8HEC$MHtK57TTC4be{*5K+>K7|Qhirnlw156e>fe^e_2kB52mbL?^+XvE*%n*2I1 zHT#ehb~P&h>3&gni}YSQ1VD}7u%>c68H|(=V|Wl^d9T0V!QK9%INsUZ-{vnuXpd9$%D0Bt zZpotv4UCOW$%)APwCe9DR@&r`#h)sP!+Uf9wlHyUr=BJ*w(3U;7cde=ksjQ}S2!Lc zD-UkcQou}b`+k;*?PAG@<{;0I7C8sZs)luWNcNC$!;1pZQI1iG0o`DS|LImc%n>T( z^Lt;T#86N*Ug~TB*Bc5dBOO%|!hZpA35RJYL^oK@?h#)U2>`G56NjSjt2k18p z9FI)-*6}{^f1<{Rge?av)K7{hRYv~_WnKIEvxT2U$;y+GvE$hH@*qju;p%` zTrw*mHt~I^HV>^~2|CVTjYSRE2W+;FT7i}rfeg6+T0y4lLUTb10bdu7f1#)E#0F<% zEz|Y^_rM0jDdDGSMT{MB=p(PfVdxh5Idy;!C(^vZhR6ohu5W&$^I*I?meG!u~SN01|J6@=~_k}2haVS~gG8h6bV)DpMG=ys>j@k{zj~pC&4$%Ij z+_U#XZi`hwYoh!CPK;H^V-Yp$eLfmUz6r>}RuHiDOBKX)uBh?kND#@_absry#@c9d zl&gES`Utx4UI&}-)ZvH-CA1flR1%tw*4X%ox?-E3o7bkc?{(QW+ZC?iDS|IGScT&x zx)f%YT8e%I{@lR!34HobD~cy72l|tQ2xeF^*O+;6!yaN3lCbK~IK#Pe9a#5fl-lNaIO<8wXRr%rP)v z{@!x`L9p623)(oIIpD>PO{Z!Z!@+(^z~(xaO_<#72@CdY2a z_z)L30p${&zf4(XL}SPk(2&tt@3V}kUElps@ODk_Gja2#bn`DU)@gdJTOPQxJ9||W zyDr|u&}9J_2E9)=g~Q2)62MT?dw{)K+J>E3?o-XDfm*hIZ9IVYmc3m~9l(n>)KJnk zT*YGlJS+z8%&zVIQ#|bZ?I+`s1*uO_Rn{|@eXiUm;w2M++zC8lQ6i?oSzN+pnlV1X zspvCtF_!Mgfh{%oEHqY^WP`blB`M9+vC*A5yLAcndIh(y9|jPGb|1)t*Vx4DOZ`qSDab+d0!FQ zM}76M08m@1Co7Tqh@CJ87ANwsNqLs|*ow&4v*R}&0dX=C$?&pjNs=G*cZc$0?*R;E zM~Dw5S7C8!r0Ta?4wz`pxb~ZN{co|`V2v^QQ=sRT7{y>oT^th%zgtoG+N)q zD)lGcO!C>fzXcD&jBR}+WYx@2R`KDMsA%8MNgdU$e-uSc9F@e{+{&f{!($VNQmT9| z87iM_m1E_uQ;%xgZ5b?CQBALagDSZC8J zyj3`4NFo;eo}a+gF}y<%zI%%HfvxNcU>yxP;I`pkk;a@r#Bn|{w*B3!hNcOlo1LcM zk@`j;gt78%aPSlXsigy>mlewM;dihFerUYM1c6#-7UC!WMal>$;7Zy(h909}9Fl#2 z8^V-7AZc38KkU|0upaDC;Fx&Z6%4B7kC1fEY%+OFly63NXvoevUsNqvQ{WlTdUBpc zRoUEqJor!&8EKsWbb%)&ahIx;_oxsx!d|%y$($K@ido!PksL<6jYVa0;mKOzO^6GE zD#!=q;sGpwB_d)a?t>P5fgaIyCxIzg-8kmLv%0H;k9S@8S%(~eZ?6lYl@h{D=QjPs z3ApH4cpe#3Joo|zGzZcLjW=XJ%Lalq@X?S}G^}IDN_fMf`+PnSTwt`mzQds_RjlXQ zaTfFq459tVU^iB73uFU{rpqS}FPD{n#bsE>qE{&+@o2y*Mb9YaC`*x)%9(*(;w6>wtc>*Gak%p3SBwK%Lk6fE)Fw!B4;)_?DEB#F;5Gp12dU zB6|&%#8dg}Al7<8tuMj)&^v8Nr+etf>SseXd=Hwd3e8?uJnr~z*d};olAjsdD`_;4 zX4ga5#*r_Ju1Kq7sC2WQSBaUvvjfqJV;2~f7?Wx3_}qyG3%C9rTX{LQ_-MU{R-R9V z5`EBv^ILg4v;|Q zExgfj&9amIRI3L}N2thAfSlkGC}gL4_GWBa82?u~y^jGp4WLjMLzP7($ji^QdRI4Z z;-N|n_ECEC(Fgm6{S>XVp;DYV(s$1 z3a43{1}Dzp#Ao=u#JS6lFZ)f#9UG>S#1Nfbq^!s5n|5dQ_pxiR8JHDB25KftM>2iL z$bGYo*IMbIa@eaUstGm?Fs3l4L6LX?PKE=7j(|JhOwPEk5d!iVZ2=>#G7?p-wz?3 zrsR9EynAJoX_mob1b*>gCEp(<>22A2UtC6%*%e%hcUT7eRn?C<2M-4=I`at)fZ>8T z>Y^YjFl{Idn$W4CHcHvuOkBuqHrDS15=1e%EF0IsH9+{=IZJtGv_98K)!z5|EW}9~ z+#ADAeNR&|A^_6hM9$;=;_`S`#rl8hRdlm_Bjm<=prx!0UTytqJMvihpKgmlc`it>fC zUXFLthw^faXX?`|N~7}RBd&u=3CJx!9-FspDe?Mrl}4;w)&+Z2SUW&Szr0{GGCF>bbHsK`!1C9e$flaO^9&*wHGS0%Q6+j9>&M(-b^d_qjUlaS$>Tarm=62}I@%cFzs#B(rs^W^Kb03m7!p^y-Iua7RUrum><*cV*_PeGSJ z8(JTt%YWT0l(}!S7dCJS_Z$(?F<{~qBXYT(;eRitds**-DA#mjh%>g|AckempI>I~ z-4_ClU&l*zn;^~TvN*3;4gedu!;wTWUr7Z}sSn=6YB@#O4?y2za-{hr5QN`ZXOc}O zKp0KfC7hJK^Xv?jI)UiuiJA!Hk8Y&L&TG8DSO}2*I|gp}9eU@cVtgBJJAQS!${3Qz z8QNr`h94z0AR)yaaK%J^ubHi5sIvu)G$62s2Q+(*od!gq05FcG+gb1I*}B4^NFn{$ z!Y=yPRMtp#y3h>c)lpxAzl~|YyGBuJ7|g4pkP8sNu3p94uy+0-N#?+KKN%`qw~zMD ziZ2>uNE4mxpxZ(Xeq|%T6PJ=fJyf9stBPpn7nwUy*s-$*8Ir=a$?xE7;fWbV&_uj8 z7Cr{z=1E@JiT)IfPj}5=a$S}W4)p9{2=Xv?^dS%iBS&!oOD;B23{PHGKbA&|({Sdv zNEwFqft%L7M6PWd3hm%5)YYSDcTGWt1f3EbhTG{54)iqK&PmmQE@hJ`q_y+uCy@yB zz)P=X&f164lADoWt2S!y_U730=nrwpzM)A}&Yk1IM_R^%KUha24s~xHN}!y8O=bkJ zx5Rqz(9Ke@d?M&n0t`As+JkFs=dC7=CAJ%7055PFvd2JRx z>H{{8$F3q1ua#XA6XU!!v8NiCfK{(V043$H;Q~VC zcJK65PDU8)KR_PuvfgPAtm7pH=6APy|KMY->6kdMfZHK6j`qQe&xWq_ z_m;%pGc1^N8E&TSi=w?DS4fg@&(UoD?0l+H~FyQ}~6}?YQSx_y2PC zE&z5_<)Qz6oHJ);_L;B)5rc`c=QP3q38Xa&0!sEYgdm9cz*nEPwzU~*O+@tmZy*Ci zidHN2Rk2hs!A2`(Wiett)lJhuHH;dg#WfKiwGz*>H!o0K@X(>e@e4*Yi?S%gXrf zX`PsH8UbTeJN)(31?6SJ-TH<4lTdOL2|KfW)lv1A2gPQdLJJ+=lAZv`1XQa;(%~ELW z)A<-oDjPoCw_`OZDg?Lb)zf^{nH#0_)jfZz&jW229r_sRql}KC@X}y=KV{54jOW52 z4gBzOIDCqqC9L@wH>(zwfBEDe`Q?)jZ;&sk{N2Ek4WGoTjs=9S?9<-xiBKnPL>Ev7yzD z35+H&aUCVb%qxf}{rFro1i!H}-FIlw$z0G()=Q91Dsx)1u|4|bG>m>R>Mx8Ul9>n2P<&HCq z%E!wL5awKVbD!}o@%7>&X~VJ^)zbS{0S~gR$bDh-t^f=iS6-s%o1t7V|h#H0i>XkdxJ_IF99VxKM3+ru@3vo z3!iV{WTY%fa3n<3z@HyRy=qZc5022`dG~9KcZewq@CP|@zky3%2m2g8&QA|#EZtW; zU*53Pa;}Aw2thU679B&nk@o7Jjci2ydG{H7wA~f z*-~+@eaDg#+Iej_jMYQv=`%GuP-EqBnX>1H=yXZV;^>O6>LS&58Qnww3cBW5IMugA zOOC9K=~?~1HPy}R!>jp8J8(Gm#%x)pC%mfjib824=>ZTYf;T)H^NG58mo&s;5Q`QQ zb{>*U+>nBNcbIZg|G6q3sDPrU+WVkrQ|V<>!}%qwwqC^=$!4#DJ)PxMj9f&w0Wxc~ zthpDP{U?j^j6$bC7t&&Y#TQJ?%3G#m!y5~Dy%x^qD->ugmdTQN9{orO26~rh_~>`k zZycwN*UzP*%4thOcX4!tR~Twb^9mEHYb3BWQU4t_h1OKN7|AL(@qHZUf(r-*iV;IC zf#UqC*B*Q!&L?o9R^zfJwq-C#yjqGMI;=(xvz`f+WoxnrxE9Q%3iLf+ItFMM& zYQnx8>OjU=y0=5jj?5RA)%O*8mf=F1QjU#_wcuGVW+FIXk@Xkzeoh^V5O(=+rsI2|>yORXdi`yn&){M6XYaA%MD;7Q;(# z&^t(|?=)czS1f_!?{{$OYY@J4stvlB` zn;hS!1)pnJi;{ygO^%Lnw{L`k>W@<5haPzsXrfP z*&|c8JBqm9OXB$;-aWEpwnsp{?SVbXrgyfqw{|xXc=y)s<|E@c0+Xe<-vqox06~zd zz$IKcA;tsFL!yNr!EHd#x_mc?_1_MLKOuxMbYk`lMPDAfuLjNyM z;ZevFz9zG@RbvOnflJ1!=|{t(#U%*5N6x|Je=Bq`_2#g!Mc^EVG#!A$jiVOd!@wVk zSv(Z0gpRfV3+bc)?)Ny>RNj)J@C=)thyeH4ON-YH0Zf20${wOg_0x?(d3_0;!)xaj z>3B{Sqi#pZ32c=b9eXn-4W2ynli&w~!?$Nd3ehy@N0TH95ycBBIg)3^SReO1w)8kF zMdX;E+f2;}_yU9j3}(zN0ouYORtA){dA%%aU5n(M{fM4IzMOJhhNtJdoVmHl^-*p z!`NT_*Ms4SyzdyrQayaS#3*v2EQTy@+GzJNug7iD@y`y1b5RHRnuf;<=h*N+uDc12 z_V9EQaM>e0h@s+o^JB|DgYHRqCKhJBLg4j=kapA?aoERpHw;5Ie3&<6Mqm7a78%!C zuXbRPpzmz>(C+m?fjIQmS8IK>YC#E`4cB;sl^r+Ces7>2YYJ`It4WUca1kaO9%F&f zgh_>5Bu(wXha(!Z^D~3t(dl6)zI^f^o{V?+6Q9u${0!?qY|GP;$%I6K2#X{FaaTDn zAgm9Cri%p%ffD}A7G$(Fz%%gn)A)7630>lXwgUNj@adCt1hd|C9yd|mG;X(|!eo$T z%fZS0lv&2z+@}mz1-#TM=^VukG@ekJXe$s>e{L`&ak4}(mS-J#`5`p5GCmwr6%P-m zrg~g&_caBg5dfE(j^OneL&Uy;mSn1MZOPcw&lAQ6QRFnehgIJg@*~Wi3%|4=jM1Df zYbjsEzCjIAsyGZyI3Y-aO|7EImcXsZ3bXapRznl9Me^SzG>sj^r-7P(SGJy}*EhMy z4eSstiEM)RNHyE*JIW#Us#5unkRO4M`jO)`ISQ;XI5lHgk05Y8skA*cd^T(DwD6R>C_HM`(+ zfb|varg$Cg5s28y#dsaj3Y~cwRror1NxUxkIyplM)L(-i2(+Ao(~ef`Z%Y2ps@48o zyXNy<^&4>>VNo2;Vim7&;pAX3Q#lWem~U3xH_hscN(hfuq{SGh{CCU)e@j6ma3lx7 zSK9C&2_#mj&GZNqu5Xz=RyC_++BB=sX_r=ZCvoh3czz;ZI@8alxd9$4&CPHezyq2{0R7r2i*tzLN_99t1YELd zx9d1oBhnXheGi-N-^?7!n+I>7%^UWAl9wF%h}^@P;aqHFZcd&{&5QvNtnDW`s*V@d zBkYJ1Yw+m0*xIBfv{q}YG-LWvs6AX~ip`-$8cnEach<5EatD}Z@Io>GW&KrTK;3xM z!rga>Q_{zsF0RQ&L6hkw+;Yt{6};(f-jVrpQN6^7i(v zaV2%|+RQ<=j;A%Nuhpr9t@I}v6Z{fW2A1At27h@KO`gu3@6I62E*P5tH(zx$xmE^( zxqzP}L}b}lVQlC&js}7{IZup9?95xob(i@>d1wKIVqXmggM)^!E&P-pCOlQ=<0KT+ zuNp$t@mD7f5d0eH9B?md(oq!&=6oFf8joe7DpUwbL)oQDG_>znu>|3zqvJBH8ECDg zG7|ZNR-pE6eNvlSYhlMh2G2PC4!q{|n+haqlzLeK`A~!rd|Sz*LEwn7s#6Fj8&ub2 z)oQnpj6K%ux8B7i`0nhDpS1dKpafzpa#==83e`j*!{1UACc!`H;O(XP=9@~bq zGvowCARRkIi~a;8ejC}a9Dq1CHLt#vm;K%OuKaQmrE>;r3G{qC2{P56ydI9AIieD9 zDgG%!xeZgcJgJ=YOf8y+;Ugot7!;SMbdZKw?QRBJ3_3e_@QWY#MLdIXzGU1ppyM|` z`D}fLgZn0`(PaIHZ2F`Nlc$!!uM4gbi-fYobUP*Iw8Nd_V_*l5E`gH+%6U4;!Mh%I zme@@F2UGEQ77wFn`@RbbIeKUrJ+7V}C&QhRZ}beBx#AKx0n!w9wriru3~&Ix`R{RS zXrCp7ZEKof(2y5{N|o0xGF#Cj;7&o|(8KReR=-_F&Cal&5HzEM{=?HK^J4Q7_62RL z2l8zf=B)vNqIEUZdi1E`kWu87l!6^g#CMy)DC&Fr)e#&CBF4M=MuoGI4cJPLtp0il zanKVej=sbGXKlDZ&0SHDe5s>?q#@AV9vuwC21o)_jsfyR|BVUMc95t|kq8vRSIrPW z*hoet?c(2Z(xPe*4>)m~cA0+UWLoM|p#z4Fu~)@1Q`@1f`VsYChj1wPvgGxKY)cfA zQD$^NT@>Fcy$5LtRaQ&x&S;47hC9^XOeZ6|K~yZw3RVz(Rb3n-;^8&dMk14}{vz`> zz<^sMnaJs+gs5abJ)wm55QmP%&+QoX8010>9vNFG0efZJgp`Eo#WEK}m({lsOaa8hii}2b(YmX4c*WuJX7@@x?}6N!(QbJ_1B83x=v0)v%w1H z>gOft3Ci0!jtZhy#;yaN>kj0&if&NQ=wTXf4}P)SF@hS$onQpw@f$g;ZVY}7_}Y&- zSy4KIPPw)%`A;9~rcUl;DysQIkO?4jkEwEHZwLRWB-5iKn~2;6L`8RLn&QB0{by6D ziWhQNBtwk{ach!s%<*T9P)o){7m5Qi0$FQiV)jbO37 zikz#Tc|Xgt@IgAiE)@zX4}+E+R@H%3Ma8MS@Hm(7CK8h)fNYsEg_i=jKNo`~h*sB= z-_rH^W0MbQg5Tbir(e^cWc8mzEgZ4ypH=l+ONrR?LIY^XhzjEDr-IX?Tq@wfnf8_= z>zJLC<^e64&OzBs*jbPcx4cl^{coofb2Heu#)CD`P`tND!G^dN4pAQnYmC-;7M4cz z=9?iEe3-T0Y4{bb{OO%6<$X1uPGv~ntpoA7` zA<6A0B8d;*;8l|rUdQ=kt)5l@o?;X3OljV~Chlj>;o;z%9Ue|z=ly1R&XmP5`Pcf*mp+;~ zf^&-zQo1isD4WqR1Y&d5g)%k_iI9Rn=PAo=)fE$tNM)eJg??YhUx|YuDwsX7lI3a9 zbTT+AoTZ}_#dI7OmUOo>yA5R=P?S@&VQSUp=3YiX%$BYJ;(`(d&frgidV>nP7P#-! z9s@ReT^n$Av}_=vHP2(UQFTg5H2|Bkgj-c02y~_XCG94sKbJ#(@TPEj*x4NJC+?iw zUq@0bhmH=LM^bRU#t?UxcSCNSV)UwBpe#X2Y2gHx`ZuOfO*VpI`xLC7vB8C_d@IEw zN_BMd0nssieHNgsqTB4cD_u^Gdj>4l=7=QA5OQf=IvhV~00-9*Bxjf~qL zzsy%8&pw?&0FVKY;#MIA3r9&cOyIz`ZU*3vuH^_g1vefH1W`NFzJ)_0Re7(3IflZj zcypNo8t}-r5U(lbBfe?)=3n2BZ$cjgwplBrA0#r7{9)m4-!dvVH4Uc?w=szst=1hi z-*_b@>Ng{MQuPxCG}>shaw22m1686K{bk!gA{@|jjKHp6(9FkS(XU-ZV$>f&Q=BR1 zv)NedJHI=8bd2uY*>``GJFw6~M@^8Alr&eoCwHejTo0E9$7{m%nqhc2(Lgx@kFoL4 z&1pcxQx8}^(#PGhdg|6%aDiM#}N_@rBf71KkX)`Shc0~RVy>Q?z82U z+_Lu06O9@MbMLVY$@hE7=dRcJ|zJV?hPTz>0l#V2R;(lE6~gGDWprejMIVR z$sy+pz$N*dyF#o>H_>kzO*8fWIF*c>!4Hvfcv%khCw314PY_f`@B}t ziO~w(VkL8cc7Jr6lz{=hTuoYGO7N=!bF4l&)L`Upx`Vmiy` z<;!~yG%t}e^#@tMQ5-Cyqx*Y}y1G0U78?xKTdYg0evCX@MKuIq53uDjxH<9(!(ail4E_<1euzUOAeHGMy0!DJzt}4i@n_`HH z4#)7+@;Ti+@;1#jJ9;ZHg|-o62Sw*BfBOCaG|2k{-Fq`RYOBY)_oR2`zsXus-n-Wb z)lW_heMKkRJ~?1I`y7tE&JlGzfM{^E#k~4xzsz^{u#-hF|8^Ci;l1RnX2r4FU4@eL zy-&UT%3j!G?_Fl_UNtt0?>(43m3 z?%iFx_wh1sKXB*geo&qZb0X8~9q&I_qKa9`Gk`yz&9_{7=Kpx)w;%nFkCCeR@-8a+ z>TP?a`Q3-!zIXZCv-YY(XIp-7dcLQe325Jvr?BiW$?Hl#>;q_elw`Iczrk?xG@4xhY z`?fs#NngGC&;R06kKMa(%R4{+hi^FMldEpy^2HbZ;F!JnGtc7k-|Ch8?*^ZC7&~k4 zsNY>rqBJzUeK(AHH*`-{GcG>4aUat$CW4^$_BG`VH;8G(LUF@B{^Nmqi~oQ<-_G%Y zMXnXeyRI$(A79H)~`nTyV0Yt6T zaMa_;L9lNYag%9cmb)mGbwjcb+-%wP*}r(^>3{Q;$L!nkjq6W(=~ut<%=hi(F)uFr z!P}np_YeK>WA|5a>twQuhY)hh*Usdov+;?Q@al7T+-njV)o$Oiql<=O{*4Dh}O zpf7yl?MGjH`%?w<`~c+l&jJw2M2F*Q%V$oz=6zrP-kaaMZ_5YY_Kx?y;ajs3;Ql9F zzxag9UrE;myvg_7uy=2DG?bu{c`O;$wDCU|! z&R=lXx6h@`EoZ#qIe#*D<(q`$qAk~~xajte`t-72|3-P_UwDeLi+E=otNkG+sD#$CSfC-(^wEWT>L{Jw{y%eSj8Wu5Jv zL50C*A?5`05mzCx4<0;g2P=cGKUmV+=ITASbyeSUTTJbxiW$fo;fIHi%cR&h3Q3k| zH27<_<&7VD(WjEid}5hu*Q{y{@y_KQdU^ZP0H zh4N#sefHK5TkaXJ8ohemxqs#5tAfnF!sTAR>K)?jdz(Hqp7_Eh9O~s}rQtWx7C;o^ z7OTSKs^xO*R?z$RGf6hzTUJNwh3AuPBmS(yC-O-)LrjJ@EP0gkbs3?fNd8rvE@h?d zn^Em4JV_sO-P*t0V1CfjFj8InMpmhRx|#<=mapGXa52Y1HovGO{%OXFM-#wciiY03 znu0(GDC$E)4;CKKtzvVsyHJ@jh??eBjhFI6MVJG$k|;j{gAn~a@Bk~rJ#zt5pKr~1 zu=?WUp9w3)Wsh}~#1ga}9LMUdT5J5r3iE&(u+wz;X?CDVbncxgwbcuo_<1^yQRlkD zm=9C!fF9q+cZ`BjlcEXiOh4tom}pQO;oWPT3+bG6QHUOU5LSzZ8I!oGej1Nk8i;~{ z0Q~?nDsi&muIaXO$J)XRVC3Lt7!I>G7HI&0m}d=0m;-K7P*5z~f`*2GNyBqqEWuC= zeQMhp^dE{w@5?|q*3&s?XnYuJZAc}5BY+T6$Dd7&q0MS;e-zfgd+dKoX6XFO@_IfD z(sn@MqP;sXUD$tM;KAJXQ3O%JWB?v_h(GkNt+vYsx#5s@nHg=f7R|=j`MF*7Re4kz zxTue35IuDfrda4*#L0H3;;2slF0X)|Nf7ZTc=L?aiu!pR{&4&U^faPv?y@Th>7_{b zU%9!-lRiyKyFxPn(w-~!+Su;;W1RCH$omS}vS)LiffuzZ>fDh1(^wVXh%b(Fj{K07 zI=(~782^lmz zP9(41HBt1E7nYSKoUn;6tc+8}=si6>vL(NdA(>hIg~Iz>qTWnqJKYt^}K&j>^N8$3P8Kssf~FdAhB4I=hzu(>Nkx{Angp?}|ls zuvBKXUX5{W6D$@q1CwfX1sR&CNrXt_!9Fk4UZ;zr-R~#k8u`_2{Z3hU@Ui&eh>KvYj`D^qGDtIh>bK(rl8`)lv;G32 z*o!oW<8suS&CAUJd0JL+scCKdud&R>$~P<_aX#ROaG0h@lNi;t_1{fGDb}ce5xnO0 zwGnk%5HDd?P`k-n7mN8>$3l~oT>niM4&N2?-DVL0ld=+yQ4CHnN8h2lArn;34b*_U zJ;=pH&eSR&SeQwAry1!abX+KR7S$|Gj>Q&MGe@2`@Kiz-^$8*f9|9mU7bdzFG#<>S ze$#aI=`x>;b;0zi$#FLo1pa_kD&GnN=Ipcj?g^uQrs}_Et#u$YLuSYh9H(!Y9tSp< zUePfTZ<$`FKwxx|VNNs6HUg!AKOtgf1bRJJv?R<}o*RA#3-S`?5(GnYvP?LVyY>qy zp%=r!La7p!M&Vap<;J=6T;Uc@)?ngOS4eQ_LPYg{;_6g*BzEnkfk96H=ooZK3t2l^ z|IxG)Hl$jR6eNK^lX?{fyiKGQpuqpf_}K zv3%BV7!$*=VnW;T6xElO80`f7oc^XBv1*vm-wbw$GWxoo9WK!u2HfscPwLdFC@a?P zMn~c^+^xn`-Occ?G2o#o&O`3*H_$AtvFdaAu{Ng?zEYY|61*dwt}arH!U2-9pp;Rk zSqs|N^}2P%6N>uO@>b9c!zx$_OMDSMMODM468-nD#+Ui6pg2ce#?~#;3u1=(x zoo7hfdrm;_xeyT9hjOjKJS{w1B&4oSe*nWv)O7JSLY@uss-q83<2)L;L! zl?2CpORhe-**2LpF$6M`;8pS-%Bf0FBJ>N$Y(0T<_DPa+2iK#Di+RhSuf$PFgIvKJ z;+JsGc;akZnN&wU)5gi`7c&wBfvG%!v4~5s$Gn08;sW*?e(Ea;$IR*@H}8$BYd-s>%{S_EM89SYt=;u&+uOgbn4L}j&Mm*}|E~Vo1F2~CnM|wpe#q~w~vOa|HwzB%wt})^{qfG}c)OadCEhZ@!+v=YgX~D{6Few?q z)tB&xO%XfT2(gpP$xGwTH<#|*`KW9iB?po#ocQ#NaQ>{iJ`ecSP05r0UoUD)&pL(09#>(3U%B)=8Vjal5wZ^##Jsr#$@bCuM?XPq?;BW+w;Y&^I zjHi+_mBz+Aev{WT&1k-7o%Bq;r&lofxpuKPju@)-15kj8OGf(`1Ljv-r1xPR}BF70OZ+hdIQJcKqzzZ_7eqwZ$e^-L)d z;S}EFU~XzM-@(j{5X^9|s$}Gf$hGYc4DTbrmTFoE+o&oB_94^=fDHr*I++D0z=eT< zIvYDl(NiMlFtH>)j>0N^8<~^^nCuA2E%jsN0i-|^#Pg~{0?RtQPgV8*#Rq)S>CInG zzZk&8a|0(|O|pXJC-v`2QzZn%o@1z)I#wZ_mqL-CzpX0Q!BxPU|ud=S8^$a1l6Q$j3n6)dJa;G3VW4|;+c4BZG$C-i006KM+CetF^ zQmsJ~KVJP_9)U>3X8CG^8fHg&E3sw6>R|fN0q{D}UO|Kz07<@`I#6HNGv1y@br-xv zM`?-&Fq3w%NlIdFqV$+V;h@SRL%L;jOfis*a}1QKCiavqSF;LM`wLD*fY!Z4hZ2NZjEubT`Vy8Vi$1cd}xdJ{OQd z$DrLo(&l)the*E>WpS~02hm|4o=kkJzNa`?Di>kt;LPe@51*T?Zr4-wNSMUBz&M0-Si5#d2gARzqWkjLA6%6YVF-0$VpYvhpPHj0X!Sw()bU8ARUpc5d0yXYyd2kp5#jXeY_EX`tn}XZP${31=jcp*3sfgLL48cu zl09qeV+MdckaBt^OZ!vwmoP`cmO=JZyS5?LKv{J$LiFwr;u-aZS^PAlJNGP1OIoaP zT)Z7#8fN|koj5e?Oau}ZfCh2I&*>Q(2TOD|%$K4%DU-%FWDia=C$DdgcrLz&W!%)4 z>!j<~^{V|nyzh5pu2#LgtmdCu z5JS~|GRBpNEyqiO(`sM`Kln5r2b?PK$!6z~$Bqt$F^{ca!*r&v%Sdz-bbp1xeRVpOjWwzmSBoLIrkS~Og z=Eyhv(2!E~)qF{pHE9R>&n5<=<57gkc+5fCz2du{K&XO;h5DwDg27O@#`g^H5GLDT zp_Js#Nx|B*h;9@<<0h?xwQv0mEa^gH3yg%vQOQZRzCXUCaG zR6YtHatlsb9-6x7OFb2=q$S0-@m&lrbA<1C%lB;VNO%T)>&+q)!V2nFF2bEilC?}d zpgmV3_k}EFqN06Bd51UsGAS5Z3p&qR2C@GA%3!MY-Y-qEk4)xRe=RRJ0|6b2=?2GQ zGF(3u=QYb&b>0tf?M@Pd2%09rjmtq(cG2S=j^PYmWtB$$*XXzpnGI_ANU|IAG^;*R zR%e1lxG&2v_!?+UGD-S_8V2N+X5)K5D(gOhio!nAuL7mLz@FFz{$r&ROebcVU*b;C zpqtbWU7} zLrd$pqWUKN$mi#nG(h+VdD=ly*5}KF!jbjZjIQKo<7w6h8EOw_>T(G|+y#PkMT!k7 zBeabl=$E6I3Q4W5s`ur2zZ+}tW>v9xDC?rdh=6j{zd$W#2l8ohb;herX}rDOqzytZ z9g2SY8iI#uVIzwdO$qnp`b?%`)qahVJ58XVQ$iW( zyt-GOnCP5^Sh18CjyM?NtRZR^-AGzfKN=?F)Gh&773>?mNk#w%4j#m3tHhY!_t*-T ztO+MNVGQq%>{;Py?4InWW_U1d;4EXl@L!rQvL1B*j=lEX3xg5Rv2>sWb36S|l&4i- zq)y5V-b~m*I_J=^h7%N~PRkBTBXQN%5ty2iJfyBr!-ER(o{X}XD?Nb8;SouhXi=>35IfZmx5U!4H@yrdMuf%&Y_#~&vv;V~m}HRP&Pv3aI_+pF^S zov&hqAq+;l+`7g`u`UdR?ahyV03P!p*<~8Jet;u|k9sE%-+Kk7Mt;?N{zL|*7e|y8 zP(*vhE4a~g26nFAhC<9$jN&^mA^E&!w;=#?*^5g?H6%W3z_QGAp1jF<_>Q?1X_)h+ zQ|n-(kg&(-N#tm%D7Pp^%%Mc$|9TcO@B|%ZY+J+rmRC+xk6;{9H)L8dAJEzS#@WFn z5d-(#4H`X;K8@X}c7gt~LdaX1;#ePVK`>-l{{RLP`z+!i7EyXw;XWLrEJlz@AXCik zLtUUU^$2G7V&IH1q*16i{5_(`{?SngIDz(JPC`l&z^AEKd9_XI0>Ki1QaZu)%{-N3;lq8g*3vHpY?gCteT;tg0vS>zDO6@Ra%0+!)Kt@ZJr{+VQK^76ek|LYzQit7$XZp4J*W&lADxB_(*xs* zLb;>(hyi3=1(ad1In!u>Uh}tX{{sasj_|r2O!}#7D9`tDp zDQyeD^!9~z(j}qjn5|>$(Sh(}!5v8D*W}6hm>TmV4u3?G@oM$y89Iu!u8O38tE%ci z5hFzX2{B3iS6n22RZoc@(Kazu?SW6YZC57N87HzhXTBNR4dV5#I>@tB>SP=kW7pSlF}_ zg`R?W$7jfWdk?1ZnP^*7kLgH!=#ucn{M_X@vLhEw%(SE`GSC>M5xFkX5#Apd=2g@4+Von2q`jqPD^Zar{yU^l9vbD1xqbWRUqZmgqA3T`7xXGW%j!`?xyJx6^ zkl!e@7!(;3B@~xEIfksso5JYIka~IbBBY%hZ(E#KO5@?bC~RwjT6AbMtV=Vs>_57t zp)LLPSnUDan3uZy+6k?y+Xpf(a6YZ&aPNHt2RD)8+E{KFQjm{z6$*H}{MF@~A<9yDOiSM`Y~>nd3CSCOi`Ckuprx0J!>E zpaBus%9ejKla^QWyu#6&+wmcOz(W}vT(8`KtMPuYE-8s{x{@LVbB;nh(e;_`!5M_=$?ZV zTtHqz*8{VY^Vh}!a5QrUmmROL_Xe^#OGARyWT??fX@Ed#V=|Hb%8}zyM}HLdaT}*H zhnJOQj+la^x}qO}K2Y)Wr$GoU_FNw1MnjtqMPb@9F%hGwwlrPE)Y*-MW-Uxv2~L!Y z&e8PE4Y??p+xz42me|G_LU&y=P$Yv9o;8y^Fs=+A*T!ng3l zQrK!gmorg>Jqfb>glzSx+4E?HtLD_~MX4mg?k)_3uHUbIAvsmRSK8yc3F z`BAzR^B;1~ANb=>oMG5gJk{}CghUzgi^~A72I|k>)A#y)o#%z4Q`SM|)nhvWzm_#H z5ePqHiU{y@;S`;zk| zQh>u6AsB4QVyS4CW5JO)X93*Lxj;Dql08IEp7XfhPxJ9W=o^Tpv_e^_byNT*j02+Qo~ zJP2}}#l&gReh&2p&g3OvTW8wWI2ryF>pVHA>|~w;Z97Rcwi0SNjw<;knL3UQk^_ES zaRC|+0*EtZvenPTSb^&TmQsJDH_KOcz=Q!h2o@K0D>BqTYjdvW_?+XSR4&v$?d$N8 zc7&G5oH7~%+hNUgpH;lzRqQ!5QDkc6MyYQgzn{e>R_>zM{Bn30yj^wg{^E^W`;(cbs!o~let#7m$YIWVIEI}gss zEAhm%+JwMVn$LeGtIwckMSFC_#AvS(3FA<7FRLiYv^c*Bx5|d>e5Xkl{(C@&htQv% zaUMoqT~~&a1+IiHi3D7;vl*PN9&yfA+W7ilp?&R(&fVEeo{ivt{?0frB_~_MqWd)9EgajuygrAsk2&p-6zNa(H)~Lpu?RAiN*Z+3^}PJLNE6Ni(_X}}Rq0DXtu^2(!0I9gTzb7@;xiDKa#m?erT7Q&Q4xU)%~NKhm< zp<9eIC+4KWMZTX)eZQZ3!FH7P%&pP^ho{9fxTL-3#=?~#p5reTKg?!?e$tbA#0iWM z39Gnqins?%2)c4(jvFp0iVlXI68j$Ph=$Oyq^-(#LX(c^jlFPjw>hK_i+dLH=$|tA z=fA^0`T4Va>&}Q-Y+v==tbW6k#{EM>AOopm1~c*x%)UOQehu2ryYg&IsfT`Pdgb;N z!@)$B=Xt+3S(Ld!q9Mo$@A0bsIjV!%9lD{~YkO?-FIce*@+eXyP&{|)6=d7;BP6tR z=S62&rrJ^k2Q?%v>_Yo zhIUyOg8caX#empV;B~2t|QZ6`)!g*e56{84yi7a(@CJrDjx$N z+#ommIagrIK;Q;1;-#@h^!6gHe%*s`G{`1`O1_C_MaN&ij)VM)$`7kh& z%f3+A*pu8$q-`E z)KSfWY*deMKNRia9XM&>i?$ z9ens{88OH>f&g10#pemPM64usIBStCxeCvm)K%<_6R6k4%6yE_3 z_TU~c!G9el5*l=4(j2r@`$^=yjr|XCh0j;jPe#GYId-iIt{gWIWMlx9b80|fDXf@y zv1W8@a?i&&bFIRfZ%LgLmf*O9;PM-$TFV*}OjnUuxMld__c z!zn9KL82@VE(o7}P?li`|8JCq;qyQgBtD~`kX{mK9nk>R;Y1_y{`*7|Zo~f$(a_EV z5)IGs{>cvxCmP6cO#Mr+^GpZE(p*uxb#tBAQTEBa`3}O_Fdn<9&UAzqG1*yb3Yuf^ z8hB_(wB!|GWHpx&JPKmCjMEFol75(Vn7Hk+Fclg)cyJ(F$=l=jZ}QS#85Ii(Ip%AA z$VT18l#VJ2OY2$CxHds2q@U}qV7mu zjIdHjXHCo(gTRE6U*T8P`8S!=s0}Pq&>+>N#RT90ra9@@YD1u4`eiyGWFKJVE8_0}v^uhkJ8`*%BQe&BSPq zR$RnM5-Xm}aVQILv*|S`T%6gHeNK0 z!jT(30*@T*etkS!JA%^C8Z`+(EFL);$!sLk*9#RN)`<1l2+Io5S*NYLO7QGZ4Fm*G z#a1_0*!o6S8T!?Qhnr*aY>hGMg8wlk+JBSl;?(|K29PG<+D!PULk0+|1xs<;8EP*? zsfNL&&`nTFSa{vuhCzSDDm^gRl}B+pd|WdA?e{;F)i2L|As>nLS|f@GK1r=l0G9o9AVqr3CF5om7_19+*aT*S2R%Ul-%<*!$w^fPJgn{7~ zX1$Ij+&~{ES}lD+$6>q(^w>)?DT@Q$i3^sR`_PG+Io_j%$2BQN)c6WVflp|iarz`P z${v8z)B)E9A}}ebtHd?YLl8<`d^z^X(l#PHo(d!q9MR_*QwAqy7~>mS$%Vd1{S`ap zX?g)r@_G*BSZVm@s0#gIj@c;HgDO6?&eSK0F%%0;N~s#)M|4x|bYv{# z^9Y{}j0r1oD_Dv4!X57%faFbuPi+OYT;>$_qUl{$kuyk4MI+2%>QNVQemn=Ati)B< zavmL1Yql%}x<7x`Q>l?XeV^*%F5mKmZIi>pWFb`YF3I*Dzd)QfLQl5PoRGh-H?@tDpULvPwOpE zbt)MfUha-OQI@YCvs4)bHN)3Bt2wH*a5W(6o_c+Q}G(IRZz0j1Dc}Dq;L>h7oX1Go(HFjNw+~?V+Bq zky#_=a73DS3B0N5@AOEG6ntsC(#`h;y={8u%g!i?n*-RkkH{qelaa-tCQ)l>`e9w5 zksIJeW)s!)Scde6;jndGJp$5{v-mtb_(*O{rBGqo+>V`+GX~$v+aqDud?K}g`W5cLCl}f0hU2yhYBI29h5!ngJl?^P8c^L9Sl+_@LN%SKTM@kF>pVGuKS^?!%5|Q zND`5eG6E=^!5~p0j*&%575fft6qo%>Rv#^ka(AygaAvSB18lI8#k`rvE}7pwpEuc> zS+~go3$%pvi9ySPl!_-fINB!z1*K}D`WBiO8Lnn$T67zQ-d!xeG&7es)vj4+!hYxF zX4;}Q{oJ8|@*@@7d+8=x8_v4llYY|q3|_?KP39-&RVNmv+JdvWy4og<0GdPurcFag z>+!i=Ty7stbx^X*p?V2$KslP8hpGvQRe#L_s3{CP^7TTOaSLtIE2Nn8>fk_13knJ4 zoAa#-B|Q+5${JBq9Ow$P?A~L|iun_tMTa8Pfd`jA4jw2I2dk0d8}*UF5)t$Pox;9P zb$wT*rZ6TTahmFmDI?(^$-yhjWwBX(l}9=2g=WVa7Ip-1za0~b$EP{5U_7TQM+MgT zEOvSK6u{($+3MXk|C~=*SR6qcCgo^9!{0u6{j^+UE;vYFL>saS<@G{AT>1{J7_`7X zMb*SkT4JY0z9SfF$Ff8*Yp4Q5ZN?AtXXEyBrHlIarqzv%Xc7@l;pk5XGX*b9nGF<} zyPr?~KLJmCJDuxh!wK~rgJcX5;?B{4luFYS>$TJMf1p^}EP(W(Wox^TJ4EEup^-im zGn%^0;SiIO%hRn5$kIfcsLt}^Zi3`NJ_Bqr%`Mw#$8Q*d3BMZ-uXM5Lo2};xr->lU`3!@JqYw< zY23%dZhQhAjMMAL)6-41sG?V$+PT{a3$*gsr%afXGtme@nhC$^Dqd6b`k<2axW?aK z6q8+)3-8zsyljIF>l%6(5vITd2PN1fXpv&i9uZB{Zbaq5kmDd$2b?PyT>Y2$p)K!l z<7T{o0qn{O#oA<|`ZlH`_>eRJMS z8QCZkWl|W~Xpw{j0JZuh1&k_QH<9$DlhKnLHA~jPQ*GEg)O;1MgM4a-gFRM%lEb$1 zj%_p7=^3CQ9n2F`#eQu1 zlmhH*Qr3$0y0;(4w8cjdq`~BJ1<*{Ed0FN%y7tRPUHbO^|9JN;wwPDF;c(a=PUM3j zNgFN1i&MH&9pdK8lnS8K@EY{(Ts2YOMLAe*5| zW&jyD{%ji17Vl+6Wbv)#ITRe8YaPHm5!J-yp#4sYW>6&ZMb>?BYsxV~i_@IibMIN$ zB4mNy5sOeVu6D@qa%61+q@CbSuv*P|PnE?q@M_AdX|FI_i+08<+#y99$27x^3eT+W z&WB|H#Vn9Ugy>S2Pz@2nGzI7ctKyG6&<-wbr*IW-C$E~13jja#m`Ir(E@WJJsYWG%3Mrm^$Y03qjY>>G#&ps2p4#}fR8?8k%# zLWyEL4;9i|WvlZ^nLzbj>>kiO(A@1xyO$62I@qK$B_6(>hgi8|3No#%NKG#nJ*h9tnKu>~ z^iSC=a-f*}roX%oo#$zQGC~FO4St z(Z2Qff{&OR7{oihW0XOZWU%y_4(PFgvxq`Ap2b&7ucJbE&I3FrTQS&JUKfS++jSHi z&PlqAOyocEeWFjLe2PGN9%U^MexZa!MCZ-S-KE${<#V}zSH)o^;nzGIDZ%IXFwQY^ zU>F8g3J!f9)mwp{c3NCuFvSfFNF;*7m`EYgtOpS{!~1rG`N~k-Z_vtJPZ7$XI0p^= zw1fTu2JKEoJ%tkn?gxGBb{F~|@xDEtkEQ!15Q1t3O8^XlYSg#TFWwch4iih}#3(0+ zQ1x$vu?P86%szD&of9t2O%!&+u_pb_FL!>G_ETi*!52-l2{#Y)HxWAGYv7n4v17$d zhH6#z;FuHr!9dwT12faG{%0tR<8BI!<@F1P&+vdTw%mo zoyOg;0ogb$!{+iF5>rI%K2eJPZ+ArWkVnkdn7zc{ElnDm=U5~UkRJm&p^o5wTEOrb zh&xkO8G7ETk=FD6?i_gBQINg1A*Pt_8Ec+HO~@=AazXH$u29b_K?Gb&cR6CnR`5|_p=ZP z;*M%kDqJ{7c+{_FZW!zOI)CvEL7_(bZ8QNo$2jtHH@^)pd+kr4kg#6XzRqg+U5!R$ z(pVtkU%gmJHxiUACG0z<9{zwa{jwk?0>fI!JUou0iY-^4(q`wwjo_OcSX@6-_FU9I zom8nqbCvhg^)Jz#_EQlAc1up=oYNG4oFLR6#PJ!noT^leG%K%AAJQTe+3=o^wb0R^ zUECYoUsuZ5HBLV#>ML<7VO}~rAw#5^+-3}itV}n{!$CpOay+jmVu$4GTNtoa`NqX5 z%&8cP$&VT)mKH)LlQ)exZMDD{=U5&FTTED1Kz^A+_6~bPDm1!@S)4c1_&K&G{Yy^q zU-GbGb8s;vagtnQMV^9>Wr>sZ`zxlWFcbuU&J3uUKs>_+urwk=UI!Ytpe1Bqu&Nkh z=D!50FQ0*7=+0d;n}KP@cPm`c52D1VKdYyuJ$<3Q6pvmduN<_6lenv1=9#L;JwO92 z$F@c*jo;IJYK)Fk6LChB#zwnw85Wl6Kxf_A-Wz`Vup;`wn`H**rh@tS893 zgdmecRdR2-xC}zs`Em$1+XG$Y%i+?!8c_~x5drwX4jwv=ETaSXbOV24;au@4L@--) zk?B}du;4k}_Zx|Zbb;9M<)_59J`a?3bzpnN9+a;TLrq_@_6|(SVD|LR9-g;sAYcX^ z;Q3g|iHaQ+@QV_V*<(b(6x*nRWe1Lsn-GuRCetB{qBPd&Sx#h3Wd~_S=^CWSAY>^X z_WlpCqq}Bt>+YPX+Ix;#)}5*P!m5c(u*X`$E4DV6W3(*4k5-o#F_4(NT;1Xm>@-db;JjI?5-$@)J@_mPqgB49`rn( zl(B=S>nk;+Nr^?;+YXj=>@K|nchu^BnhyOa5N);4{?GG#v;>2%S?8~>>5uwhe$hNi z*)p4`&7z`(9n4B?4nIxWFN6%r4gnWo(p}Ybr2~$!0l0h_aJ=&?nxR?fD~AvabgAIF z2<-?H3bets7G|@c%h{f` zWJk{Tq}h02CRE={&6IqC43dUymeG0Bouzq{bZy}(g z@Ve3Tb7{~W$L(i7O4436TiCx z-6WY{v%UkLM#6hG%cv0bLVH{=Y^XoZo*Z4{-U(xq+}?tbnoOTOP9zAc8B;b7N5>Z- z+Rta9IJWESpRKA3h&CU`5$53;RUwE}~w97HSeQ2DP~c&^yki{A5iF>JD>T{ zegrL6hQeWgq^ESfx_*2|EcN9he81P^HpxslJ=@13LBaf!BB7l6CAfvql$h8pMF1{h zSsntiSudKXf0vEx`c2j{ze;(Fx-82@ID7c6@Cnm`IKNb19^ch}MSCof#51cTCY(vi z6?7u?$wrt5^(*^f^{{`~N7Thbogqk%L;vcV@^ESR24(awrYYsv(nvhY;t|b_rl3U@ zhkPogW354MX$L@6BXa7CTeVrr)T2HN>Tp#sJ@^M;WY^&hcw zt@=)$FH7;4n0O#?SpSrMie$MY>a5?*LI+jQrUQw)BX%#~9-s$A4>z%(#lU*LdH5?7{R!`b)_aaSw)QgIfdG71%(!q~v5+$L1kHgx!Un5(j26Nh#I+TO_w8vtyQt zAV-K;YF{yI5xD^W3r{x!qdqC@w2HEfA*lS)U=|yxi|#9`)gS|i#fLO^d_&xmtfW-V$)W2Gt1~S{1uHMSu|AcW)pA+mqD#%(_$6 zJv=R9Jc#T#{CQAXYBz13E87Dp-FgZi11(gys(uLzl~mIe4<`^kLk+u%&ZqiqL5ThU zCvz{$^DGfD#>jZj5v!}tI6jG5xfyb^XX$RPzLLAB&g=)~AApdn3)E6>sSo7s?1D(U zy}Gh49=f~g)(Ma3!~=ve`{2ZS>EnYpWEa{MnFhIqveD}HEcDm*sdqUIOKg;5=2XPBTniA=XqvX;5&Tbywobb$@&0MqosX-cZ7pfmj>AgI0&+LgR zZBxG0dkLAZZsu+_sLFm#5oV9EJCzds^BxFDa=?;-&mO9>VeL=ciM4?_^bqTHCNG(FQ5FpiYo)2ppR>tsQ>h^+?ApFE(U7%A_()D@iL1GrXE_6J7Qe}C)f~Z)fl^CFM;<*cQjPQ z&+~D&2REkkj8n{KXz8R#5#wlT-c7h?A!{DK$B@v3BBlc(@`&cRAgw*4%`nXFG+iuVD%09uW3D#?-e*@e4$+h zBH)Y$Gt=x$HZ!DB;4Lj$<-jEM9+PlHfX|%q)u6o`f7-O+!SV^y^)c`hGK^=AMl%R~ zrq-C=$LwOXV*BXFq{mgVjL3=5qppXsOJ80{rMrQEiy47TY$Oa^GA9JR;!!YdLZhuq zVXR3d^o(7bqwgsrd2?j_>OQQ)mS))_33JPuRWJg7DcLLyQDOnX55*j5^d2T|AKHwJ zZ@@TW#E)Vq);!Qlg-9 z@PtiCH5}Np*s#xRjvAYlc8oQSl^x54J4rI@5`R)xX3EH*wDJYI+YKUzf09eutC=@& z`HqV@R&Y(u)#ld$vk7|>36_%RakML@MF^V>dqx{VD0CzHBP0N5T00(Ax$%he#EQ|$ zaq=ie%AcW+J2b~NCx^uNuQ;vb3kg=uoPC^g(gPp_8_(-;5ezb4EyolEuYjxFj=FL~?hil{H?U6zkbhU)JKpPp1st%J)6KS8lQ2IWE|k z0@`w(=51_|M(6W13Qw%+c68E6Q$(JFWnf~%px6p9F3)iTFQb8|$_B8lgoUq1Mg1P& z2LbOg)smm=8Gn-1WJ3ULd(9@ni_hX{cot`m9Jvp#{YzZ_(RwMn*bky>c~1}&ah9g_!q0Y&L2+xtiNMeJOoFZ zlik@V9Fzjg4f;`9n?MyTLU+1Qd3b`-AyX1IX%jr|Be_gkHP6m@zGBDLk;=3&IeR47 zj&XPFk=d}gkPXaqWpmjK(}_=%*~acgO5<&r%}Q|@>3}C}jHGDGSo+LX!qRvG4W$#o z0PwIvUEV*yXlB%+v?%_(kRfy*IVeX2Ed~cQ#SC8bq^)zaiZ1aniytaGQw;|Pgo$y4 zYcV(WXWdLrn|#q7zayuOqT+o8jM8}~|oLGynP1q4_jp2Ad)c2#7x_xxR_1cko3R83R;O(Q; zHhqkfllbQ5nEGk(i`C)*WYaFfgQSG50|TmoQs1_6!gTl0aP)DjSi~GGwTk~P*b&= zq$fxt(ARC;==!iQFGsgzbWOPS__;Cc0 zd5egklq@m1oN%$)$@e_EHonEVf{3+(5$lFvcw6EbJ~|(NoO4%p$rr0G-e3RLV4T~B z?3@dtR=QP6S82ByA_05bKBp^E`Z5pN!tbzw}@cKXQnH*i9*h32?435{i-sz??*$zUbTFXSNn0r_}j z%V~lrWPCD*bD+nAM{vFVA%&I4y5dB$^7M>-!ChoKjEaWfL;5@?nibHYOmZR^hJBrA z-wiVc)e{nzkxPk=WGiAFG8>)(uiS$bl+)h#VL@_Onj?9CV9UC;K`G*zoIqnKEPYe- z!VTGpZ6w~wJ+_2Z$iT2%43oCHqDW>uPGPsR$Nq=-VchIP%7v$wMu$)rkxjI3dqr_Z zc1*CmK3Lm5i%(KzwH)ieIPsy?QBUm`$cx+E4;fh`6{3pq&}s=wuwBYFe48-dAt^`0 z<;!?E$IGN#ipaxC({k4S;2_5XZlf$65LP6~uzqgTUB5$@dr9+`0|*Fih(Vwz&&Bsd z`UTqY@W83lobVwR&to7WeDE5gLg&gOVOqw`UR0H0l5P7?Sz`l#ZLs2;Os0~){* ziXl|S0ByW@G_~EaXTGgX4MDB?f*4=IK&%H9i+Wj%OFm&HmN?WU+^q+SuO*JfXj!6D zb5N>WHrKxGMD92uHzsmF?Oh@`e-paQ32E@#?-_l@aNGZ0{Y6MR^xNuR`gzr@ ze%O}p5oM%RGnyrSR>NZ=J)Ba&qiTf&6^dSSbAhL5u$v1EAOosdSsrHuLRO72)EIN| zAA|0C4N`kWQ%NhjamW9V3`0ko##yo;-e(qNSPBV+H6F&8Lo8tr;mAi$vZqe}QigJv zJUVI3Z3X@)rkA;#dZPigPLo1DvJs)^@K6s^(tkHV(Ruq@QgXqZY0ne}BU7EKJ@$d} zl~*2{#PUi`p&pd3{P7$WslK~zzy9y?TC4_8V+c@!EU{m{#~Mf4pG|gy9?OB!uv-no z{-P&zpbXVP&oZd9?-ByDbHK4M3V$wsO2RTw!l-5sSN!yqP(FiLpI$-1=Ht5XgGHt(@SsSI z&=O{Hx17zqB#QyF8Y8ehed`*ah*8IUP^Lt#8(fvF;FzE^o=yV#y(^&1(}6mx_jYA^ z_z7CRFv-H_k_|*SjugaCeG7~X8;)}Za5wx=9}e#`>c$^ngoe`O$wTffMZ}6YwttEA zJ$bkNhw&$!b{G!E{tufhXfRMbr_kZ`zhQNNP;Ma4VLPS47R4^HUkJmt9ulvyPfESI;ryrdGk>|HAD}^v^%A7h?u# z$N!3=$om7L(^E+h_~Q#Jri*+qAT6btDW#_UI8mo2CwmkAZxUM{7Z{u17G_(WC zghG2WjIlO^-B=~Fg(*Xud3^&pO`?2AF!wa2r&Oc2j+#OkX+H4^26F?k5_|y(vwJ7L zq@{weB^Jr0T#Z6pK>U*2A zV>~!B{j5trjiC}*GB)tMcX@7kR%_v&6rKvYg!kAUL~0Xvr}7`X{YW6y*$g=kaM6Q* zJ<0q5z(MnWD0>$$%g(YucU|_b+Eu%%YgJ#;m+DThz0yf4q?2xvw&_VS*sCSo9WH_> z56n1o#7CaTSk>c9x0xK&KsP3Y2tgub1T|vj95ASfCJG`d(m^g!Q4xjsRPxetS*zyk@bw zC+E_lzcK&($g2Bu=7nq1iQoyKetey{?`#~fih7}Ch3ojU9IKGysPZkj22|GmG1;06 zoURJjKQYSU^i2{sVl0zWLiu?;D;%eU@*++!xONfL=T|4B8=57V|Hg==h^d70ez%~8 z&e)2*%;)HT#2jRu zxi!a+xP66@O=k5x@8Zrzz&Y!gBV#}HOuZ3a$EA)T%#lU?yVUk%DhVl@>FPZ|0T9s) z3rp*Cqc+r?jyJ8s3@)(Pd4x^8Uvod{#+;5MMXt^F2m`wB)@Dn+sf!GS+D3mo?+!Xh za8teI796D=GY3Y2lAG$yuMQs`mX7D{&VUGX#d@mVXYH?v2#QK@0Zaj9xVsmN+%v-v zz`vY(VJ9fc9L#RvDij^3jnVIZ*nr)S5pk9VrmFwW0tIFb5@xlfxc*e=HIvW_v!BS? zFpMLZAj`}2>9FYH9AjP_Bs&M#QJ|Ah%JG5L0Eb_RwZTQQws^Knb~+46`493LDT{k0 z9TBrHzZ(RO_IqjTH4CYNad+sb9g9j;&!1|x!O`mt)!i%+y{=6fE#5{*B%5~lJ#eq> zuePrc(E?p0k+AHcVy?g+GLQterk*c;jMsC#_Mr*&H7SYbq^*$C!y8--=Cuso!V4Kf zhH%NjIVA`{(vw&W(N_KT-PJ!8qul551)*tRwW4Ue((|Uh*6`;9(gZ6s^Fl}S?Z#E! zo{n94YF@)nBTYNin~E9QCx!jeLr7>|Rzf3KE{%*fZ^#eI>g|2z77r=}yWc(=dALzc ztGla7kttDw-ukr9!sCf;-x`9e*WL@aLoz$+9(T;t{R<+LacQ$oyznmK&tZ!4Y`Hqe z|5(NuxsLkjUP@dY@tsyot&K8Tt_#P*70!w8B*O(7#R0N z>FSrDibSj6Ad8G3V(~b)BCB4FXo5bX?PykIAe7!v<64}l61k;jFw!3>(7ouNHDH%9 zb|UOt1{J}|FvDmZY(bO6VZei>nyY8Mf=tMIfJnmrcg1K@Ivn66qMr6CYRfK&lr-;? zI2_$Y!kY@d?ilm{Z14$u>ZXuwjmOP0dU5DrFz~=O8VMGFw_v{*hvvWu@-}T&5wg-( zQ7EcE3@hP8Cu7nq%y#Kcq6Qe(Gogu$iCt<;nKxe?4ssSl_Z#WwO^L|lDB>({Kkp%0 zMZ5Dx#?9%mVBS-Yt853Wnta$yOd0=)84a1=IdkU2{ox)e$K=&Jj0XC4_15XpLI+5|DnZMMvGT%yD;Sasmv6)mqQjErMGDE~ShH~nX+b0{ zyu))7Si?OdANg(5aPq946^iSWp&&UhI}k4nC0a3bzv7xw=v8Dvuh1+(AgCn+%1$qz zsZNciz|S5iWE=BZMjz#kdeh4KX51(u_wQPg0nyAHq%vOl@F2pGC!DSvdmTo+*3H{ViY(!$7kTFb9TllD^a~VG3YSZ6da-ENp>`+ zPc}8hliq`BBll^e>x0$BH8?(XhE=Bzv9d9-mo9Nx3Z;g+*!!$MuR0(k)7${+;XvbZ0rmjD3Rd38{L zRfp--C8-Nq6EV&KG4|p$HT@)5q4x&yF2hm;HKxSx7J#Me1L3iPeRmP{jt22`H(;kHa)AM#9fg>!ESj;jidFX=hzx4XK*F@|_@IHIlyLmE5yX;5Cp zYT8=NG8TIbQoYQ5)RluawgVinr2JX%?d4 zC_fjzW9Aqzo=eP;L8Bo})fk5vwtBctE1zY43ds_~g7<9I_iM1n*xr?=;$MUjfG!^H_b zYAD19PIV{M5d*q9^ijPme!}WuZ`H%Ip*?wH6i=6QaS*);>V8^!!Evs z#X=vr!%@gqs&^-qkYH%PW;QS8!{be+*@B@e!THRvz!Ubrxfzn^PfD7U=D6#j6=?=U zoI-!4ysM`;fX>ye1cp{%I53cer}6%17)}o3LIYBL7$?XKmFZ)|8l`3Js+xZ3fkYU1 z^Jt;#%>L^sLs#=Oi53w7+wk5h>o>KhV|fAh=ae$DypKsJ)8S9AUce7SD6^wDc2Eta zy5!$Q!o7+8G)Jjnx1Opx`%)i`*U;w`ck?LIQ?#WgKgLKuoC*R#+%T z)&?u^R@4lRUqz)>rsA~Gp`>2bYqMjRvw8LVMOrg(23VhiXAxG>i6BOjxQ``AHMH^gwe4$ zqJ~Wgz}3*3KyGjm2bj4VksMwYkr}=E1pP97m;@cN%#59M=rSS9^@nk^|3ARRGbC1e(AIjwkWRv+d$efrGLBt;EZ^h{C7Y@ z11XLRZaOBPBKKp&WZ!Leb243BgwhVGvncTckLAd(XVA0GJtbxs1+;XGrNlm)$> zPQqTtupSIQt5+z2DfvU%AAPyLs;Trj){pS%ck)^RC{Y9-4QB$JNduxwrU-31N$N2^ z0zABFw3$E{Kl*YvHdWZ|&Q7hLy1ooxp#`Hc}S@0i$Hby+{+H2%`u^2MIV` zq6Fx+0zA1%KQ#>y&;gJ$VZ<;fur1op&4X4Ev%v?5 z@Fph6c;c1zwP#|(*LX;-DIUw}k~SAZ`iVvNhQDf*lEu&_WEEL2hFJYW@FhHTlW+U| z#+banxB5pAR<;;F_r%XV-Z4~-^4odX!adSPLJz*CdHk7d^^siywY>leS@&-8LAVv} zOWkkjW=&_%uqvv2B46!RGp0&62O{NkIDC8Yi z3L~0sV}Ytm1TV|VOpZJR9o$>@?md#~ye~L;L-XP9=jl`{ipfuhZ4laslWuyd z)U-X`d&WS#9Qgxha%D%91{PlLdK5K3@F%?aMG(JJ*h!2k8|91$fO;YoDNJ+C4DZf_ zPpRqCPMbo$&=ezN6|(9r)1iPt^7tlJgMV=KPPl*|HGHhc6$m?}6tsoF!@)Z>+>DAM z2n?+sYBKYx^WiT@*e<4Jdz~I(Q&LbyE(=Od-~sx=OA_hrO+o1(M2|{MJA;dqip$%F z6skpA+tM}24!+~W@JAaThvZR=^~9*`d=3tL9fRlR^(=^TX?YcNhR1ivb~ugTxJFCK zko7nN68GTJ{sAWq^a{=kggu7~Bv{Yh_Ir_mTu12poPWAe{&toIb$~(JNx{BJ-%XD= zP`{-H0^j!}+j02M(tp@dW&7c11m|KuiQ=Lyt%*`{LZGd4qlY|qtLAB4TV;EdU8sPe zi0MU)A4x1D(a#afe_+muBP(042X;Sih% zf%Z3SIHrUxlS3u>QYgf9^dUG5-f8=w?K7!a#tsaTVYq$10W2yGGc!B_$-G7uF@pP( zg{_Wj0^j{8*v#KNH~AufWb?@TPE%pAHypktPg||Ix-71)vW3%71HXv}v3kG7Y(?Q- zU`ayEby&i4o%TX}lptcKIrPGd!tjxy@gieR=%qpvF9m8DBLF4T{OMd>JO_i#!Wv#T zQRCfl&d8ljp_QOqzd|upv`^QhFE~Tj7UE`jDqK$#`Xa={@MTOfWs1>Kkdb3)3%x>o zqpWIB5d$d~vn()6aKRzGeK@W;N(u@+E8~CvA* zR}q~%0(I=7dVhbu#74oIXM0p(l-YnYs8@+jlX zSmE4e?*%*I!_Xj67cWuE0GqnYL-`Kz3Kf(Qv)w%g9{vryJ%MQj91?h_*70hny!2V! z?P-R*X`gC@p`*BQj@j{OmtpU9!QFly^Bca#&GzLH!9`x_s!mBBWxEH#L=L!aTWroC zTv!aOrXB{1(SFC?SD0Zm8Ia=fpYFRvugei@a#0?^1f8pX3NhMV%)|PdCR}emD4VeW zi*+m^7#zSpu|kBWqf6&nwm&RWPmzfd&0NW;qN5JqO+s!e2c9s>iD888DA2w!**9g| zID4iyTL48;GopjMdWor|!IJ6k7UzKot#iPL!O8*}9DftD@sVWN#E&P9zsq(Z@G_Qq z08jQ=jQR7J@3*fGXr)jJBRPbcC@FKODaLtNZDspfojC!~nBh~3f~vFJVC}qop~l1n z)Omn9drDBVJ48@J2-4e^0IT9YzS({HHi&`D1-BZC;=*K>;7o3YBh2FAZlC%4?qG0M z9{BeYb|L=-Ko6TPT}YE_#Xa!OCJy{>W1*!tJPa+B_8xY*p!HzH47|Hy3FkOHcEX7m z-!pBaY`;EcklLW9U>uVsaL(wkiT8hsjJ~cGxOPs7>CyC${OakOkDSfe{a3S0PJ-GS z*bMvzMW8BjBw%dB|Hm3Q%<3#>X?OkUtnKeBsCM6V5StDG>@0#3g#=kSVaCHMn`^uw+XF#uXb`2=VP zrt1*^P$Z0mvy-^Q?iJtULQQGpYBl`q<^$@yhMn3(WVJ&{!>e$5J|b3bYS!cuCRDidwTNYEF?w-1tf<*M*3tYPI}-6ead-h zNyZCLgz*-K=^U@MYQ9D--*GK7VyjPvtFaf(=;?THx-}9Fs7NV30R#Ly6dneECj?@` zA1S+gjB5><9L$1mu##)TSDFlGgy7i449W9UajL5d(r>Bjs7{XG?POaY<#Tkh9dT~7 zcTVcLitz_CclCSihfxzBdJK?p*Z=|6q@t`{F1ReB|G}M1Ev$;r_@h91fB16?#kLgB zK%f!NkQ2+z<6~J|WYZQiO-NaTP}P|d>8g^;U}PNjiQB4b;)Vl;bOF;ap!l2qelv~}pL z$8r#!5}{itI8LyxU`201lR@aPrI>1x1a!)?@f5)d+BC!P#Ms8cOF7#9~1t!6v zZKqfPPi&9cY_8K7q8pv^ddbhtaHl4*fE4sTuGD#g8uLp5ps-2Ii111T69^2UVRUxi zIXa>-&8JK^Rh zsam=;8WQcA^b)H+hQ>CaK{K-JFxs}!LmQS+z;J(KnBzY+q;+1=OrfgmXEk|uZ^Kr? z&}d33^O2!Ah3HlTnbSumN|~c3XDvi;5SMsO^_rsDBB$7L3CSf(^_I)B%bWAa1W4$G zK!ybCUeacU-e$q{!j$bBa_~im>3sbBc%&r;FqV$gx7{<^=psJVznbJh!30*LTearp z&BDb{Q4CEhPjG*u6S;wb3{K))+#}HUK$=D8={Zkl7M@L313=F*$}#*R8ai(`N#&k*;4&{)aaMOnprN;Sv?yL6-I)prbV}O4=QJDu~LEBu$nFp z>!l;vzw;F^V(sGQ82sii%VIR)@JDODMk;eN#}q{gU}8@i>Sqk|5RG&SuGg=S$Cm78 zl$uRk=PtSxK$}fD!3*_yv>0IIR&e;uU>y&j)xs~zNGn4vj~Dm}rEd#hu!c;WhxEuS zxD5P9h!7oCR*?1|_t6|%cXt}r+-sb5d8K+6dh0?r#dpez>1UeP2Fc}xHk;@(Mpfy# z;cd~9OrTZ8jPF7VXw!jt1UKlm+pKFoY1!_nH&uIM3fLm!*0_#WWfQo<7Qr26u#_#a z2*ASHrqw6*)L!mZSsyV9x*&F$;+$HEjC(jV&f36~e)S8O0TJ7rVl}3czF8aws*wW| zik--v9+GE?4{Vk#Te6ry6iBE2udzgG(;%_C3eh{SmsLlGQj2oc5p6#e(txMx0WeAm z3*2~ZJEYja#_AV=W$c|az;Q6)B^)|IQgJ!gQTTmiG@N<5*!&& z|68wx?05pVu6}_5293iyfAdRO^?+M61nyR)>DGFOl1KW=t5@*1K%vr@qUb~QZORY# z5DkChlH&3tuRoftHX9Mx;`-=9fX)~6M%E!jbjrw=4&ct@<6E)_5c~jai@loQAu@ZH zI$qXBs!{j?DF%o#a_Q(IpB>BULA|S!)poJhiaaaLPGuXGQ8*R@T=Pi@sO$ZqS7nwI-FH*~5roNb~ql*Cwv4kLn(2n}Nf$Z5!i6uUk zc@B!^Rjdb(dD>QASYOP)fdM*owRS3a(gHjQa#&EfEW}-JHkZhp~rxf_F2{b>4fe$zmm zsu$Su$Y{p4dVaLSs-%ndT49u-OG$N_XDGIWT44U8r+aN3P;4?1*B5Day86>_EOd=N zcy~V9V$;l;T?aIef0ANQYPProp9x)G!WZ0vi?+J0e)`Jja;G5XVFyAvOqT@;J!E<` zub_;{ryP-Pp&Dn00D`%!oBa9iKZ`~*i_fnR5)1XV>H)M{_C>Tm`FeBA7+kl3Bzmdm z3Hp>1?L9e`s6KK8h$T+Dq*Zshp`+#s)h=$(>=mfN%>{ZaEiTk@ipu#&%Kp*OZa#+O z@r{?8;Wx1qf*9i8lB&vXF%gcG4D&lDgIq5Hr|K<~EK-e;wQsC!}&~aSAyOtI&0>M3Z(}e|M@(P z%DD%MqDK_E!t1kkRz>t#QAQuG%`ow zBRaLbyH{f-l*<{FOU*n2XlSO9I_+XLn`;WpBMbIZ4ue_Fjd#|r@oJzs=DZT(CBg9) z!In#~ww{qRn?MB@EnDRj;v;p^&R`2h#xi@Bo z;`HV`R(mS=ppzo$tAM{JUiej7>o%~^#QlA6IEEX0T3ALL{bOc9k4yCV;?Yv)uB~?n zoWR_yMlDF{cH3i?sM{M%RNLH^Y*S+~*Nut}o^n{(x=F&x**^50&U1#S1NDkb_vR9z z6|{>J0>+F7zIUnqMnLeoWaH7w@9Ad!Ld>WuW2C5LY!&<$ zj9M1^J5>5&SyeG`4&!}tABAH8;Dq;Uy&>o~8JU^U-M156u;m)mrs_D;Laz*c4rUNq;287@ zyK_Nrr9K$tIA*MxpH%^Va8?;yIBbhNd{l2Z@$9B_$6@Y*>`BF=3a5 zRdV_XRDe5-j|$_1#lCQzExu-iBithl^(1qAuS7hX%<;XhV#lvQ&+)&yQTH1oQ4(gn z687qL1_CrYzCoqa;2X2@jje!fJ1Y8!mD`+#%GL|H$28SxPS=arv|#YC+4o>mqxG1s z*=%+=!8yrOj%p55GENsfSdj6sBYqcttz%-++&+a3;-pNg;TcedvH`c9e-$!?(PtN&AQOU z@(!t{%-sA6c)SBIk=RxBecTFDwio+IcGbIGnvljJ+mI<7VD=agPm@lhJoK42+Mp^ec+zae(znb@CzSRAf|0~k&CwAZIneF0aGzF z3F2sd;7In(j0Bce)XRW#E=)Vz851O#U`6oDDPYsoEIa=}jpvmrqvu%#lY?()QqC^n zB|9HIHSGM35`zwBgS+kQgIopy%wzhEm;OfzRYDa6&$*VPqobY(0XAm4a+q zU* zQ>tH#rB`=^a+9(@RbLP<4#?I_WV52n*m(>?kS1cud=3&=%7HnX##1n-gZhdF=1o_<7RaO ztij071}l2_>j7RGZCZ)o(qjSS^F|?)a9Z)t}3^q2> zo8@X)BJm+O4C zG!&3ZLnPiDGyiJSOfs^YXUET&)}X!=g4iB{w5Lv($<8f=4%0S>k!*bgv(YOG4 zDagCGx(zpB@z1CJE~HGyrRV`VGB3oD`Aq(nxHC7x9(7{=2ZFtT&rDdoThx2;TlgaP zpI|>8S$rdX>m?82QBp(IJsFx_E}(d=x{(7L(5@JMPJ%!-UzhBvo*xe1e?@UY@{pb_ z)`c|j+(!uREvbRgc9DT~vF*_&ktS}RVQ65ud7EY$6{ar6Zc;~J$rV0!V$>Ig^LC;p z6&!$(`Fb%NZL-bv?$>r>K#>Nw2NeBfZIsOuaMB{zc3LqW732(@lW}|@3-|19RlrL} zBX6xaV|RDXSVEIgB{_WH%woQtU+=QvrA=tRdZ0Grt_ghIjh4LW+R%WR`dbXeQtk4v zW1yqZU<)9QGCR~ID1S>h&F!b9s~{g6h|sf4L3UA+ryn?V6=t}xC$+mjedv?sqSa~m z5QLlDydR-RF6?XwQFX2Gjh?dhoe@27o!!*oa^M-QURz8mo^BRso5hQ1S`MfZkcao$ z9-JbY{T>76bT`f1_@J76L)B7>m^3lDeR=JV`WWrcQD~@ll5YH1f-965!4KAp+M$c= z4r|!!1DvG?3#@SeiFsjBqI)iAC?7OZ9bM=pT9$RD?vl#42;!pMZJmPfn zfyJ2iXafkUWWvA9J2>XTKaXj`JlWKd8MuSfY_KHP!6oj`t=&S|R{tMX?+dFT>Yd2V z9UT7-`{Qh3SEnm;+YCK-PCo(zC@-ZKy zc=ZOLK{AOoRQ#!qjE@Ra834P19sgpe^gAL56*Y0!`zN?}JwiKDrEmlegaSxBiOVa^ zapATpea_YwQtOk!sM>{2udKNUEa=9YEQ8&Sh8xR~^MD>x-5Z5&PK&G(WoDalTH=-CQ*=LoWp|^0uhhN3- z5R=#~VUJeGamLFg{{;6m58R;aReHbe>#{>EO0NMuur#8FdLi&PsR=A#mTF7s>j`*u z-(zJu*I42!Py#b@A5PE;cq1xd^Z4Oq$p)7JJQXp<{N;lU8d>R&*w+{oX$jlG~_xOZR%M9fVx#NY4r&FT7LTz6&$_s27v#6^=ca&7e|z~M=l#(@!U z1r-wzmr205Zy@4_&IAFr_rIpl{D6zEI43t0dlcRpp5gdlTX4NN-eGif$=e&!Fiwn$ zuYxHZ>XKd+n6j-pTw{y!cMI#L?!teDxVBoPPW6k~e+V`&5_iV#S8E>4#w0?UPpjFj zAlmJ$iHxEW-x3nhqG&aQL9~NJYRS}3~o z3woFv4rhw>p0Cs!T_E2lNrnfoo3L$U$VrQyZ1ya-%{`lhyHrwgmoERS|oyO4Iy4VE}W{pE)U_jCE!S(S{@>X~WLVr@w5neVOCsrU< zq$oDeaNjV-iYIHW~-<<-4v1o3k!ulYabR%&YO-Drt&4s_n zEEAX=$qQ6~+PmKDY|x%5dA6W!$e>|Mg4~3djcDb@of2NGBDFTAb2}0uiAEw%EYp1J zEXXpFvuKmcZ6Y7-cKR@EeG8w)+8NnQJAYMnlhEOf=$LH6+q`er2ieLF3R=JI%M6XI zH0aqZ1mLN8#hfU2UHvmV<@8|9bv(mTH|yN-{Ok(SFffT)tuTNvtarn>Ou{3H;6(5Z z6tOkr=OKg_v9>w58i>FmKi7KPYB!*6KH5+oX54t(@R=oHI~Dl|T?#C%c7hhUQ-G|O zWyZ$t3-6usHIj|UDz7*DZK(HxHEY5);wYA>62Z(MJmL>Tl$NKFR6L_XGz`2`o#D(6 zn3IW%Xkvjn0q2i&@cuye`D@+hJB2UiMaZ9xEZTXs2Z@algLu^n?rDyqgQuMyl69o| zRR_84X0-z#_!F5_~g@ z7tetS?oEi`6y;$}hlv&45GzV7_g`L7vLDTsV=7nVU!^Bak~ z6A`YVDsEw1xTjd*nGA0pW(h*!>yj7RVwLss4b^Ebvkg9*0x0ks*D zKw`I}v(&KV_^&{c^eXQhNG;$3Y(Kip^ZR8|`FIIAimcwgF4FXbJfbIsnYPOQ=Tn$T zIfl!=Ep!s6j33?Ftv2lp*=y#YagI4jXc!O04bX{+d}E)2wO`GPT>};5CM`in+8mMl z5+@R=0V<-vu!a@h4|0Up!(>76T8gX{~< zA4IBYCJ7b34Vu`-W_jyOP}e5-hZSr@8`n_#XdK}FDkISIBnsOzqt^LlcPSeMp5*8a_~kWY07V*%U6Nqk3KX?G zO#s7FWb_Mf8iElak~D{d#V_Y}An9RX-4IoirlV>S4~NHWq4StEkL9)o9& zqeZnCYR6oi-y+<{^NL%6%FZUKzZS3^Ei*}8GwOVCy{zVo=bkZ>m*d7(4ZTPmV_Ec+ zk$OfR;m?srs{#%Gru>IWK={_oV2I`0X`VJySpqP?qv8WpxhlImPovWzhu5vO((2tT z%wPVMu*diI4%1*bFT|@sHtqYi;E26M7T$UBY;PQK=mo=|ybig0qQMs4!ypZnE^r~Kb;Gf%+yF$B z@|!2Ugn-dr70J#F3N{)?f;HgdY_lXQWti5|pwXo^&Uyfh9F`%~E~yrY8JA@*HJV~4^ zw}hA0fGf`l1H4auB+LmG7~#H+rZ#s#h`DH^QI1TpSftH&!QM~9H6q-@_4OksC#)N} zgJUaGDy>Mw#w@D?+}%sp>zYXDviMbmcW1((OA~!*75R~&F50N|#yprkQg#o3R$+iu zuf=k>V=PBOB?SP2pMyQO4>{l)m}3 zWPa(O2!!U#xd5rgODS!x14`nV6lB-4j->0_jm1-RD=jbwclkP4_Z zs;Na(Z5%^>(kPsnW8XzX?|nj)Emkir&KgXKf~rLuV~f0;dGc~tAXF$uMSf0^vU61V zRLk^5@cnwOk8`wHz$a$s*jl#((RqaQMA%5Fk&%N~=Blz7%Y_^xS~EC*BMlk*+Q=Ir z#>ky|5L5NCEb6NTeYlyFH<0+_kd}!|Y@+2lSw+ie&LqJw#7FaMsh~0>8by}1qizW= zY5Gf&#y%(bXn2WGBU4^Quk7%V^#Lyrj&bW^xI|KjwMNn|^Du3mw8{&~ML~M6k6OsC|ooLKwaxUz!4Br%Rz!Q*?%+D4EXkOz6Yod<1Z1 zy{)}ES3k+dS|mj~N=CZ$vACBwZC-AHNA63MJ;;uwBs{pZX0k=lp6wR?KtUyY-R-*g-6xiLpDy1TKJZW zR0~tNLolp*7j*=_hpmpxF0a0xp;_NU+~dt1b^$kQP|!#Y%GyuMCK$<(z0i^#&6EoE z7$@z%5{fB#iYv?|IpGtj##G$D`}gUD(&4`ao@^sEXWuQVqNiI%7^EWXuZUwo?w2*#H^#0U9O?Hh?J!{JL=6Mo`L;z@{5zzA%tHKYPF8fE3- z0wC8OWu;R}6ysT3Nn8k!@P4X5&myv}fRckkGMgth_uf1($tK_dM`1Fb$c_>niVLZr zW{(@3BA91c&Z-OKBagV}HuQEv@>gYq6f8}_jtr3b|7HA3S7jU)5Gn?bbD~vyz6lqU z$~Y;|cJ-v_cFe3tEa`!_H&fcbT@OFOJBg!rg2l~;K3dF zq6l;r^qk!jqpo|A2*5*M&UHX!@w_&#|JZa3SSUU~8`a19e8)Y4iQUF&qC0f~JphzA zYT>f%0Rpkq>RT@ErM9eRqCAF;ivcDRsHfXh&aWX>se%oZssHvqd_6+HG_8Hd5j&Fo{i#e#=>%k z0tRZ1oJ(qz6b@=Sh#cW3oPcevlqEh`+>tZFpZyD6>vy0|gl!lP+|oU8#s}VIh9(8_ zxR1PN+b$X1l^8YCJ_un)J+GH)2-Zy7FcNs=Uob=vVs>7Vl8YzJ{s3O{2B?{;0qksNW~$yb*Pu z$ePd~H2r@97SQ+RpJ14IXh*lh9Xj%#>*NV@-B0S%JQTddGpQyseEgLZm)YssPqBk3 zbh7x;LJIt+2?U!o=OY0$v{nZGb}LA6_7Q;=M8?(m0r?RIP~AZGA?SqX*wh8g;oc$> zi{^$aNEi9A22(tb`HQAWhhYX2Z0HPybJm2eugj$9-iTO$YTuPR=-{L zYI=%|twb&kuo_XykM8zH2>q+9ViXx3wlfURHoza!hAl{fZ3uP+Ytg@g$O&yUk#2)_ zr-lc+o`$Ap0&47$@7#4vqxzVM|Io`CMv9O1$!n=^H<@OpTfILCIYpB4xIyiBo1lUj z%fZ;DSp;$?scXm1i*<&Tw~>QU1rkZ;+CV?^yvW6s>i4H%cJT}Yjs*@6fx>ZJ!_kw> zXvRf}m9me?`T&EPdpfOL^|a=|MLXWLW~Eu=ZnzZb^LQ?oh2~Z5LK;u3D_ z#Ho_JaI@e%z0ylH-sw;B5-Z%VK9K6_KthOucmlZ}Qlbi?A8*TI;bgEv*#ctv&NTDwURaf6%{bpavdjeRU-wZ>{ z+An^b2jQ_&JlzC(4n$A<$+5;zFG3G&A{~5X#HU(Avd|fTXRFoi!i{b*ystV-%yoG} z3*l!B{?xC2&m#~6j&u#|^jO)vu?yT|Y{8Ea8<|wTx~V&=?FMJ_xfaPa#~fjNWSF8HIZD8jqQNPQZ5VBQzaCI^ zMq4W4GHhj7xN$YA1f#~hqwrV~)T9Tq>LE_$vJ@j{g_=XNaCP4BosT_U0;+1^rK&=F zc$-)ug+=OF!%2iQ;`3fvJ^?Qn{;XjoM1b}}Fn(f3lU_wlLPidJv=FQ+oybE78vrPXPM1I5n?=YYNxwN0j{E5-YUq%66W;+q{0~={fyfv|uLl6a7N{mMr2u2ZG zFF+y~QGgZoGIxeul`pbroO zo*E?NJj&3{t@~ll646U(gn4$lYKxm0-k#85O(sy4oqT`fOin-|ZtGWE2s+#mOr1 zQ>C7{Vm>T+!W`mD9RCPMpsX@2cDHBk)%teCX1dXTf^K=RcnKeL`7Jc|+BfCx&36-P zB?9^aIM6>`&P5}#SLr;}Ig1{XTyJX8bdpS$>thM%?PXf2vtsJAc=Pb8?F%ca(V+hL zafs_@H?)sFMj(z}4saD!$uQCFw@5U^iT*RBWpX86gz9IC0yZnl?M}kcf|D^%#^PN0 zb)1WIz>re#yoY!CDwgkm5ma0A>#en$CO3Z7nhuO! zDRU?0e&}9v?VmqFL$vaJ>;oY|UWOQY7fD$t6VWR=*H3FtCOl@EjN{9M!<_+Dz)^Pb z>CjjEH~)~C)rJT#-H!;`ag0BI!b|Gpp-l(m2L5Em~aMgn)tk1kc;n(R(2Kl+<-hse(s zo*F`)FH519pw5GKQ5^@^h_NR~gFMW$_A`$&#ia0un`$SA%iO4?y50k#+u+Y|#(}eS zen|lXB~Gk!fgUof*A78?OW5c4352ZOI38>Z$)^E3T#RV`!iJbv9Nd%ke9l(i!CUHY zv=>!h(G&g=;$w+uA5`H1ov#HCbSQOB3*vS45yH=~GAOEgWkdR4J;m=?Wg7&k9Y%GV z@mR~2wD6R8{Kvbv40eUNm0o{ccur=t*__O+q+N6{I&wDEymF*1WH`rw6-|)60um5S zs#*aeUtd2?lRK!4gv`Fkr4X6oscUG3Um#j6Ji}H>V*~3lfVWuAr|(L(Ka*E40(YZR zvvG6`9Yll*CL|_!__FwpIHvdgyzxI#zPMQ^L~ZJib1qW-5rKs5**?PU7RL|WOq14l zq`3J7OYvyB1Bc`2uehM_8y9^OvDb+`eqIk&M-r4p-wIR-wjjocqp+xTOoQjq<%V^%+F&^8im#HVVX z+FaC5)A{FkXdRbf5vs6D`=kT_+*f-c1#G~IR_g-HE$ z5+VM;Z$M9x{PZfY+dB1iU$)eh1}=s#@6!0;Z^9#EAb5Gz0TOQkcAn;3sL<#sRan!C zOAl`Js&A`v_(gh_3kRxaa%;J`L#D>6sYmjmR_Sx;qP60N-_&`hd)0qaZA8f|$uUWf za?BM|Z?loZ$zVLTpZkr}vKZ0D;!2t#BMJxMkaf$di*dAl*VysRj5?n$Xl6dGW5WAZ zR-Xn6fjICCt{320@D;fe(}-f7bO@S!8tIJ~-~mv$yHljm7Q^q<2~4*DNoJC`pZI|l z2kB+y;ey87&M#iHIbQRagmS!5Ige*!PEG%LfCnAXX@QG=606DOvATBVo_61dcEs5T~ zH`;M3_IajmKbN{JEroohUTx33l!Wp2{i(Z;eF_-HkN4*A`2YcHJ05xs-wyx2JSye)+Q)*k-kMKzp{O%#3*@|j-+EgSo6$!5)&+)+u)du; zLArjlIS)>syg?Kcmhhe%DLghHeyM2ZvC`S5|V=$-C)WHT(>3cT4RC3aPDSXgT; zD;+?pdiow#fZH&%{N9_Wfb2kU!J|Jk<-N_|Rn5!`66`!4ipzU!3J1U|8q8Gw&Aw>q z9=Rb%!8{jdAUah9-lvp4Lh7ET4?C!%*nM2z1Foem9n)H`j4b!Ps_6wn;~t9QYe&w& zqOF0?x}41@IS(-J4d>aQndUOTQ4_z}h2w2pO4WnZk&`VERZ8J$C>?*W1@cM#b>^`s z4x}z8RN!FB00HADSAzu0He__TZsuqqAh67uf|?Y9D%Qg>Q3+| zHP1~N1hlMbJOcm>K_b(;GeUdA&lkn?>B1#D4Etco%HV;3CEz5~sRB1%!TpUUfdYb9 z5Fgf{+XhRFWxy~1PkEu4scsYZ2zm8O-mMF08*-fUkN&du5HSQq-ZlhNT^=A{#Se~K zW#z5Hy8ot|&_7-cSkzVz6xB^H@;Q2P|4{YkNNQiG0s3eAF&b`eUa8(bNNlwmRC{Qp zdX0zWAdnr^;2Gs|`i@MhX#;J5%w(`B20i#DrzS(A1{(WYY?w2Yu;Gbou*%hk2BFn5 zSJotlOdRB(aVw0AgyB@(;!kgbm;(c;sX8(Wk?UnMCB`LCE{4A%nb+)*3kb2~mNa1@ z<%6-{iD!z(MmpTSj!nCW=%+WDGw6SOr)nL2tPhzSapZd+v3!v6&J+17+Lyg@zN=_X%sw>Iq zk_~Bt=kpexj=}TTWZu61&wAC8P0=(C#j9KeA`v7h;0NS(orxRuGw zra^RwUYdBClg+EQC>gjn4n|nk4|{B^iebhkiZvn_0R5X@K2Izb83|g$nP;?p&2v8- zlNOSki!&gJk!gcSIGAMAeDka|kWD^2>)uV^JX4pvPF&_>!&W(p*dQbvKHu_Y{*>(V z`9O#0<8uUk8IMA-?VZ02972PSmjhc5$ht`iTzw8K@JG`FEI8^*uPtGC*F`}FaOgVj zzrAaKB93_d8x-Nfj`=K4p>i~RA9}~Q7x51F7NZ(*tQ^BciH7VWh0HT9ieYRC*r$ga?NHmxYnJTnJ&X3%{#JL*^=tAPhiuMh2~=mG8NqIoQ>pTNBSBDC)JUhpf-ML~%)WK_XXms* z5s;DWr6RrKU5;S56G8`5I;M{h#{coIUY8eeS*MQINhsLD zo}?-vl$_G0>rC|13MU6uK2tLBM>ZsD7Sj!*Y_|;*^(SxN9=w3FLxxvKC($ z1TPj4pejZXCI%wIemN+ng?5*{2!OH7oKb~YV;$@hF|JW4({Pl?c(tGpA2x0Wd~B2 zKEN0ZW*>qS76}&QtGFVBN01&MQKxhveA;a{@Fx+;4OZ_S+!(*SbK|K~2Q#t7)vMv^e#Otd3o^%ra87JzrAC&qW49lMc*h|PqXL`JED+tvn7>g>#>~rUP>Nn_Tb4*411Qt0<=<~RmcpH-<6W3=sR`45_ zs{c;~6iq@#$e&<@SSi7Y02}NL;Pbe1WI_{`MAPyvr{^?iGhSI$TM{s^ck;zh-x(aS zO|jCvtEA|_`oEUdTLvIt*$svuggfGbU%{xv7C?}Xb!6D7LT*~-%D-47&VXc3LP%J7 zC;TL2I8i*cN!)JvNx8u}Pe4(i3dV|AIern%d7`=2u2s#*9{{AdT5oSJ$(ERu3o_B z!pi89GAKoVJuF>c!CZAe><9J`47^4mEAa0pBJyH-v^){3BHHCQJQrREPCu);kTj&g z_4q+!uAGSnc`y+zfZ%O`ip=&XkH|>;V2m+PP*~2#!CjG9*1q>|oo;ATrIg~q415sR zV$26RyOFOF7b1uuhC@Tq9cD*KMiB944T`LKLwI=s1!e`jr^Nbbde!SAc)ZA3g|SFA zem45cEPK^EVG3diC}8~Qa7K`+m@+1&v&WnK>29*O zgxm6rIcI(d7_^_yPgZY?EUrV|odN%rnI=9X7|~c-!-(LD9V6mSFd}h>iQU8p+wWc; ztK>-YqYM~yd{!MG5l9$B;S6iP*nt&dUal`Z3rWhxB0FNVffc`qL3bK1VbcIEtHf8( z7eAX8mr*df1FxJ*#F{!*$I@#?LFE`#De(&eR1KrxO(FJ=~&KQJ1_jWYv8TaM#J*t3&~>!==^%W zUjZ*cC@@*=3qiuclY9k$FX0*9LRRp5KN>)b@>ks+HX8UArUEhor1#u5PBh$?)AlOq z#&9KG1C@iIL9FHCqhb;8!Y&g72^0~)jyHU{dLF<4!F-Y_<&b=UfU)hvBgz0Fy5KT8 zJ?TLVfkhT96kkuB#Aq>yvdZ}qfSFoBtMyhOuS$pp>r`QQj+i_0ayU6E%3uZ{KTJUCj{(b#AI(?Dl3OzXVx~c#MC`#OAeM+4gEnA+@PkK+ z3+J?f1BeGftO5M;%-Fkj{8YWm z{DUr=ftu>$r*s*D>JXu`$6dfw*&|rJC#d_bV(f3SI@9goXe~OU-IOb>`}U_#LKS3& zm=wYjhw3;_y);~USK&g4OmHOPDn+v~cpF#{+_~8#W7{Ndqr|Y|>9TClTnv7Umi%6f z*r7YJ4bq1?FB>KJlZm3wq(h<(84fi)pl6LT<&jU7?SKDE7_9X#F*1WenZ5sRY7qXly0Vxj3ex}?%Ixs z_;gcbdtVe42xD*^Q_=(hFhWL|KG$RGSpo_uDuMY&mU*hKPP#&C{LEKHsH9IwN_C0+MGaJO~^6 z@6{J5*$_b>l{Zq5M*~a}f`$7CnrjlfN0$r*&_is1v;GWRnv*HeD1wNh&D=KCIs*mA zq(obsM+kL;!1k>Au@-4mOwE}L3&Mt9v+K||l&D0NG?n5_rApGn82LwIuu|eigC4_5y7k8P(Xg5=iG5Z5gn{~6PpOSTAEw6Xz zZO7bq5|Oh?g=dha!ZhuHK7=ILmroODaW&!V`)F9hi7t5e*>Jw@-6YD2!}WQg*y2X4 zD}~zRC6D1|A18g|pQE?5#~)(X|Hg?}?y2b7D%-dI)tDy8dxf$b9Tj=}@H7Y=T8;=K z#8oC`d$k#LV{04%*=s<;0gy{bu0{;o8m4*OtP0dL5KpvW+V#lsi0N2SUKxNfC7?3< zNffCIuyN{m@cH*mhKBuw&{=J^ttI`o;Z_ZA>Fx>Kn~?z5V8O|VgVUt}h>cfgV4+%wj+Kt&Nb@Qm`?BgLmXh`*O$y*oV0ts1Zrp zTQC|t&Bi5j=N6vw#Z@iU`e`W>gqJA>z@0@kECxf{&&Cah28Jd>s1c(GRAHL%XXeI9 zMhNPKRWPYzVS)1nLn9IZJ7Ww*y*1)v&azX?q)A8>X4S-c1yur9LCpx0?wceduGXWB zqX38DAl?dfx+P6&>8LfNMd#Z;H^vSQ%u-@^R>SjR~427cz6pBtt*`uy$b^`b3L>>6=+^kf} zLQkcLdaN{$vq3=^JQi!r3e$*Pu8}@ahSCyt;4KbNZ=t0v6q@TRCh*n)k_MOG`t|{K z(tKUH#M2y~v%_JTI=ar#%34pn($~$@Y0U9#uu51{4~<0Jg}MU`y%KSq;|(Vr>|}qe zVs*5!ee8z-2X!>S99}yfLI)oVKR4AIzng(pcK~DVz$rGQ8+|WfoqB08U7C+eifo2# zSY9^~`;EJ?nO5GJN4zHh{x!W;JAZHzYjo;wR3K?f>Ilr&b&dRGF`ZA zkX|OYNW)P}WS=D?)B_*iuF=-0FLrzuRk{-N?p{pjt;~ks^k6mh4E7X`F&L+b_=y0t zr-A}tGkhYdbtpl&=_px16d<_<9bCwaJPKnhVtq5{AAJg>!zu*>n=yov40qc2#L&4)jW=o-;7 zwQXc)n0)a*yNyhG=ak4Wui?U-=8Pa?B0-11mhwG`xay543Q$ECAnWscPYf`BKJU)5 z62`6=z#sngn0s*y4GXpk2tY6LCNxwQ{rG4;qRujuPIf)go*5HsXU|+yd=FYUK=CY8 zER)@r>DUSP5gsmm28=~7L&tmNZVo9SQqS+8Yi!~IWXwVXceXw+ssG3V%z%mu)TEY& zCr!%Mq7_#{oM4d}q}lj#aGPkGwIWP9RL^h(Bc6rj1rVqrbQpA4&@H>s@ zn8<>9uA3SGle*0Ue1xy7yiPLj>+lWK1=rixeAb8uLnzdSb(z{K>JMH;@r5JmXETL0 zHnJfiT(2wjCMhjKFSY@t67FPv#iaFkw1m@A_ce^0@CBp5O`YOZoMEyD-q-+^(n+&1 zMX>1l8p3f7RJfZ#PJ}q;!5PFP##)-Nh}>8!VM8~@4fUop$^|+MY}`N_t|)VTv=4^B zP9Px*ZR}hbH65x6sydefXX_?4h0wR~8NE{0#X>t9o*S_}d)AD`T(Q<_kL!$+kMO)| zbyMQK05Tlt6!5ZZl)G&z9Dt`A)+Tn3=XLFvkkLWb+K7;MI1SexjQ)aP=>+*XLo{zP zos4N{VDk8kzFaec4SXRUT>fo3auH&PX6$_sH~cT_T+~u>A8^iaFGE#rf4@Tlh=VIG z>G=s94KAP9PSQh-OxAf|E!u8!Vu=~*JLgD4=Pr7XFOCzcmyho~ zf6}qT{L{XJQvKzwqBvY%m>hDtX@D(rL3qGo@TY_Anzrg2r*YGVDuM-0yB4?!uP73t z`oYqDEJ^zGT=4qhd8Lbb1j@Ji4RpjbJ8>wh(}yj`=KDH@q+6dX3@&v%tV)_j3M-$O z<(fsoFeD6kUbKNXNlykqVzlvI;_k3*xdVbT2~WT`)hQwPmOIDCWN2w-OlXWL-AM9e z;S$S0xDi~>X{KkCedK1B43wVbBc_gM3%j`94cH&bb#bwGfw7vQFX;YiqJXnlq=foD zRc~3A=q$V^)FRP(4kDOJkPLI|U$I|ZD43hpu2UMLdg6oR<8wob-}?OeydbsC8i(u? zrbLEBV>wM=jY^LF9S~3m~;as^$z>hLIm~ zj`^|tp}c6bFuBx6TM|`@Zd2M`9_=`t)Q*@tlR&g?nn2JSX=@wsPYQqQ&WTIiZLTp+ zT`W)%YV$vsTS1@v4i)!Y%&cBGUUwBaDB-R`C0osFjJ)SO(r>4SG#!Q8svic;c8zwL zV-Xxz4Ft?^sGxEh zPHGUhFvU4zAO}o)S|(qiD;a=eri(HGXEG9GEC#=V*oA%M2jb+t;S`A--f5J~?O(hL zVNME0+B?b`8{dXV*3kS!#r>`u+#@e`{g=dk!Zl2TnXsaq8TWw!#8@kx6K{GZ-sw9r7Llu zZ>r&86VBBbEu;Zqfa6HY>Edv4m~|}afBM;=D^rhGis)7B5|?^u13TVUSCp(Ca?n_$ z_TM~*{g8N60Lwn2NEzd?bE-rTpJnKfjiG0dFeCp4;Qy7g3prp?6G{gITOY6{lYs$n z517Y@{gaTXL@VPRxB=~aX?;7eVyIOWsAykhfR_%0$vp*WGZ#dLY`G^Zq$Mf>Z*VVMjsEu)eJ0xiuG_#G7#Fx#+oBs)s(d36WBOra;wEc%p^ zu(S1>7!PcJ%I4Lh)U@*I4OI9IjSIcnaqwvMcHaSXG(CrUmxT5>?dAEAf9%MCA)vu| zg(&j7{Ty=g;RTC>gva|Kbs+%MEg)2VvEQH(3r%w2d^t=>1~=zE=qj8w-l{&| zJ=p1Fim54aAsH0ohNl2yj0HDcsC45#48yB>gVXR>2IL15NZ=9Er4h1pp^5v**eP!| zf17n=QPn%Pt*C}EuI>#wF~r;lk_1Ja{lJvOc5n)Z7>HvwNcBR;X!d*EAAWnJJIRh9 zIJ8WLmwX;D*>sS346Ch9UMn)FHPb`@Q;Rt^`t{hrRTnRGtXK%B)qdho2~Q7dpnI2& z%-mERiESb+d1G~cBu}YHgB2Ld@Y&N&qzq+@%{2}ttZ>fYQ;3Fpdq^(u!}>HsS^sk|l{G`Bl;){I=g;j89~ z9qGi6J7n3cFtYI(^AEtql$VvHUB%0*UXYUj`1fLXLUCXGVJ;p;?J?!0Yp}J+}XTJa% zg#2ERGN|x$<#{@XAd%IficoZ~qwe1QM)20cJ=#-?gCh@JI$W^*sL>^9iN2ihwqJ&q_iGDH1b9&YxeY+fIR6fSWCiay1_{VC%U28Xx}eyw&*z7XmEMU zYQ5>ZaXm3i2bHAy#>oOuBpg*c!M!C;OJ&phu~J=i*L*7~z}jl9Es{O1Td0@~i-nd_ zMM`IT_k}TI%-?SNUPE`-Xf601SWdUcnnj(H`*Fr{y2+RciW`^Mcw(L{L z0h2>ZYdXe;5*^HiRz1YCC>lO7YLA66j3tU-BpbaL2COcI5op^PgqULJ-4H@3s5T6W ztZDF)GwIm;W8qN>3WI0gAGZjX)5OflM1*OC107AMI81}sO^g%i0$iv0C!Nq1 zk401<9UkswNXaC8@VQ@#9?nWbNgtebMSKkhZHBEk&0I9RfSzAF?`8K8k35I1JCkmj z4cE~^6q{sb;fCl&36V)yVZUSgv}~_6A6|b+=z46O0OuojK-7b9O`C-4RIJte*aHGT z7CW6Yv(yihS{p&ti(Mn=%8{tXUJJ|TMlL-5vWaqDN*O4_CZZeH9kS{ zTk^1yx24J_+k^SmoQG0JFndJiC;Rr?+D{Vb3G#7bhY_2?N|JMgKfEhNGT3@!!G|83 zjO_lK`9R%PfS|_)w;4299P7<>=8ARbGND8wxVW#Mrn{knI{ft_WH-#yo>(v>=0Xx% z#p;GK%QIfc@gj)4H6mNTKBDp@fa!B!^f4=k@lMZ=}G_ zsntA6{1iZv{=0QqT`g~*oGUNmoc36iKKcnC81(_VScNjY%ZdJ^+H-lSXS)~Y>;^jd?zo8-r z5J)Hew7I^S{icMy(tM<(yOyHSe$?se%TxI5BAPW&rjuFe^w^%*l?md2ukJ)o5?E}wqk@7& z-LHPTXn*7jWefm{wn7>qTgrJ^8s(HB*=`&W2HXkHCO+#>`_+e8i0I2|Pd&r7gX#mA zVg|j@A{c)3h0((;JHq8mmj*>VPpjpb<>Hh1;uMBE*QpwVcKI9(8a^L(yDU7&fn#?k zY@3DOhb0Y|FmHKB?BT!fZu%#!rsW1lm56}k?HX6@a(^+7-;ts8E0*JrMMB|oQ6 z{-3Diu|XdRj~a#y_{Z>i(NgBuA+3rCtg-S6l`}c9+OK30Fb8oIG7K_nvTGU4po=oY zVvUG(Z?5wEe~GcfRpJfBk~8orP?IlT&Yrh4N*O1(4!Ipl99(4V2GVhW+!(--(*ni% zP+Ba!zk`5q(*2mLJp;X>{b%Yj#zBC2^^pNcQ!oXyODQ**ED@C6>dFLRCyO13S!>ZJ z=M<=i-Nur+e_DNgiq%y(%TYBRT|5L%FtzA0LekvCuT))G4|P#}Q}k?J>zCEwRBwq$6p@P1703Rl^nPf(c!GmAObWv$(&$i zR8H1g??@Exg|e=bQB3slP)nH=wMOX#4~+L{iUy)(|L6l-(FJrzN3jS}1H#R0Op|wJ zV+I-}s`>5(^IO5Uh;R9$^hZUoD^vFK`U-EYZ~RBQ#-(c8Wp3KvV1X>+Ylk1RL}<$U zX#J2lj~5zOGLDzjX#4iACm{Q^EXqJJ8MRqciW)kGsDQ=|6`IM~;Y>V}`~_3P>q6j* zv?u^5GI~Pf(7{o`@Z-D*svhD4wdMdHs1a~mj9iEUnRXPd2A*3E@5zfY*{W(Pa?$k9 z<{m}ukl7TM=gY~QL5>_x{xEJIPNg1V1Nhhh*Al0`7zI^A3zsohXBw zj^wYX`={?w*$E+bcmBMXGGo1)WywPqlPBoX>vn|gnfMYm`>Z>5l2nzCV24*eZ(lJhUa2+6KmXt$#itlx%s?>qjZ-~L9KEapV z<_0x`&+VBUUa>8C9x*n{@aDC*Qh@`f=l_v*;_Y9j04hRy^atu}t9u$sOh1%ZL0O%n z^i_2zebtkczRH1B!=EZxxKJ?>e=M8~74(lO3$ze--2$lC0r;w!I#RKHAE5B%6~LB) zQDotA8(@PT>T;;^BvD+eO4z?o->>gY^Z1M6#pxq+zKDx7y+~U`Xz-`SgGUCh==$yI z6LbwMCq79qKkX|nGoYZhpXgcc?qMkwLxP~Uu%{JntlJe#*(k0>xsKygQS z5qOc(8zTc&EP^wPn?M7NCV-KK>l&e2Ff$9=Rk?$4BK2yc%=o)kU91L9?xe#qAqwIC z#5ViY#UL~*9+W@9H6+@#^=vXDU^H6EA&pZa#*g>fzeGY;KOnMJKjucz{W=kf;hjpe z7{q(9_w@hYs}(mjeQO88$T1 z=GC9`gwV&P6_56&kA0qipveh(KyH^JVSVGW>JC^q>J8D2C{Dp+Ev@N@sy?NV z;Ttt}hr=Jw*;`H|4J~O>p$JEbxa>P4yv;Y#e{ZGwEu}5}Jj+F3%LPDX0HYGL$b?&a z=4{%H!dF#kGznTT38H881-`}gmCj^gjiF^a&>YH$w?v06FT|FVBDAC78}e{B#iG?Y z1PCbe7YId0Q2jRiNBD$67Kacpu>-(_;tmW*R0&oK%YG4L*}rL|HO~UBBMu+3p`xRn zXmHu7iy=T>JPIKu6-^4F)uJJQHy-8G-|~TXgK<f!Uq4Aq;azw=Ob{#D z{pLqN3cuN_fnEAJ{GWM>WCDKzDg}*Apw7;0q283C@G%R)ZZIGeKEM~@(4bcT;Q64i z)fw0$8lSCXBrYf}&`1QcriaN5g0FfLnt9PaUYr;~IW8ltag--_9#r)B*Pm>lCDsP3 z#y40W)dtoN+G;VZQvx5BmH3HYlm!M6wDsGcc#YPZY%A%wVfa?S(}=Sl_M&_gyLEu1OGk)=#w^+31qOmwPySNTMER!9QG8cV}) zr>;C+$J!D)*3>EB$uWoa58o1S;B-p8n=o0Yr&l&X3g+w94>l%+P@e$n8_=&o-(aZM zrwV^M*x;TNT4Ma0>)hZ!-%zEi&rqAByS;{5xOQtg=<^FnwWW{Sh=@4!DfDu{nq zKD;v64j8(gMfG!Xo6}G!&mx)-H%z}hAZA|Fz4I;MFBD}#QJVV}=JmtA262DO zaQL2SGEcys$KVqN9fRr~h>;MNmb+LVwAcQ`2YL6UeEEWM=s)mfTv|2^!-g!um%s=3 z_!jO_{MYbbyj^pdS9bEjMO^TRmk3zlKitE`-~v6BRSYCmS;Xdj10tJFi4c4H|145{Nd27=p=+yaZJAXzjzc*jg_qJ6eKhX$>Sw zM0^$n6;NsjDpo=9Rn&?E(faPCt+i@>#1>nhm3q{2)XM#Se`Bt_chL6SbN@J>OLVWb z<{Z!8_`QF>F~;q?FW`EEHYyM2mS%m2h2gBABPb6_R@C7(;5=GA508r#d0fzqD@YOl zFa&)uCC1rkigrril~wzTMAyItq597rFCwvl+ae35yKUP`U;^fjkuAQ1uhmQNs0D2% z1)X(1CV2)8Y6h~#luNQ16v69kX8;3WBw8Zk+EyT)p8AWEtzj6j8OE7A)v@`>SHQt3 zM4%&QKv(-*hrakEs>m_0==AS(qnWsemIaRq(5H@L~{bK|I- zV?JI=f6-}Vy7Qg0-00|*^W(H>S2NAO`f?;K(5sD7b^WNjDLb37c2#&s(}Ict^2~mx zo2~@zfL^z1(Rk#WoioBo%CuA!F20n*#sEk31E>QKi2ESL@tM?G(cl=El9*%G?EeuH z;P`5Km@U3j0Leh@@3@qRR#s{`g1-7&;2`)mP{vW$7DRJ7P8EW|vxqTKM-Q=7Zx;hO zuNKD~6ZKoLn5?=!I;uE>e^Q1N?~c*o%cLi{PDQd^G-OUjF#%^0HeyWykQQ~BXLV1P z2t|mM(jdF-#5HM1lCx=y!F6L1FMj)a)QHsFcV>f{WbiX2nPS$4h z8&|SW8(PV#>n2*SyMY`EE)QE74Jp{X<1S#E$k;dooY1-r$e38caeZTD_;aC-P+FqD z#v4dD`>fMn%7BDn_2MZwPW6y}f5a05NQ}%c-sZqau7d7yufs?`Q1lf+HM&L{tD-6=!O z<8&qKtj)qB6j2NMd_>XvHA=^~0pFTsBCkUM{BOXi!l`DH{pvN4h4P^2KZpKl2O+y{ zfUOixOx8>ET-sq)$Z*O{Y1?`)M&K+~Dx@7tD(9yxWRIM3ai*%zA}0*D@||w^NKNtP zAqfj^$opTKD7wkDb*w^Ijaxpb#D;v&WQT z6ypHZ;8>~R_%Eg39y-uOvl>;X;bNlU)HbpuoDL1pVfC33i40(9j(H&FA$y7NO%v!5 z&{n3#i9doeMRfo|@>yLT;Md>hgDFjR>qZ_fW4)HKmRXTu1pUXI_O=_vgaP6p^==~I41;&H*0zy%P=r|^4b>lU3syJlcDu%?GEXmtqpH%h4TGY1 z13WabcS*Gim_#$LkBgt|5y;{>xiXoxJzY-IsT@|Q@5M_NR#wd|11At~+2pKI)rqwiZ`7 zF`(nh?Ak}B!$k>5Wus}1nri>s{RBH4|Gwu=L|DeSvgW|uXgypA!|)yHwyd7Mn0IN= zX{lvfE$Hp}T<1A{fU;Jn#l=?u`efBQISdk3*EwU+2)CuWWys-DPY25>zyPQuA10inEOJ2W8PW~d42;)Hp zM5Y_$FZ;&Kia@Wsm{1ext0oNu?1p(Ki>v>JoT^C&$6E+|J;RarMERn%H~jS!TuC^E z{XGzC(?8mjRI|J&K~&^!5C*z-7}vpn_`}UmhA8Amih*UV4-Yu`LooXW9=p_;zBhX7 zSASxE$=JKC0KzfeamV-nWFUXVNS+OEo&PU~RrF!??SDo3T4ou?q!ndegTA#exLuZJ2^Q?)^mS)nmxHO{xB-59eNU+cUX@PJLK1+ z4*7NQA-~?!IppWJx`+JyT8M=CX5V{g;lEp4m@|hL7w%LK>-QfFriNyK+s<~ykSGMy z-uJ`2`3EFx8Ti8kH$9c0fUFt&Rz-!Zsv4I7MlVjdA&oWpS^fcy%+Bb)bt3PHKVGfq zalmkxH72jv#AYg8RqDLt={f^#VM&HdDc$OatCF|I0SW4uX3aKwrs^gcglBWxCK@6U zYZHXfOhkGrh~H9Q#xd~Ip=)kiW#(dBa0Qi!t5{H;DoBow+zzso+c^jqh`IQkdzM<= z%rZzbllti2`#~smRToB@ z)ADn=@+KatBF>{~SFVJ@#RsDe?wx|uJRsBGkvjJu+)167xf6J6WAT$q*s{lu(%hxzuFg!{y+dEV;PYDLivVhla0P@QUi@!06!r#A)IbdUhQ&%G z9lkJ-4i_v^Q50!z{epbD=kYibkrgV)7~LEiLQ^AZ=$rgWb_diKG<7(=l9QZK^|?Ej z3^;eDxBeb?0SxM?v!ntfA1+#UFwl~oUHs9l^R!?D0*r<;Kj~&6yqeVH~;L z{AJdrJ%5a|%*g)l_dk|L%`xM1Al0aBw(M*U{vg#!oS3t@A#s+YKonMIO7FmT7tjxJ zSs*N3IN!d%U%g|B0$5Jz9ay0y612^6SKs7bD=S-p`vCP$1;2+I_J4r&!hS0~hj7XioYsGZ) zzIcHM%brpf9u>(;p2bU+q`xOYWIWyp$19&}Y>X%_Ejn-x9L76>I|})P>5EVvAy$)X zIt8=5@B`%oxN%8L)B-DzKi2o#4Khp7q$!d$*g;8l1e-I944Ut-eg99k8$VrEn z7szG5%BTi>@N6~+7_aRk!x#}cie_25lhS?}<`AgFN{4W#vdTcb;@pLc&g?&ehK&7O zk*lR;)mKF%I9$R2gaCGDbpqprbzm&TXRp66PhQGQx`bcyU|n>a0J-0IE^-qq4=A(iY?GUHLK-7$x}t0quM7&{w1cI!?pPgUzC z0K)wY8k1BkPN(q`$RRA$UVIRHRb@)Rxax+c=vM}PjMV1S)&1(C{y!dBF5BJNm3tC9 z!P#lmE&tWoZKD<2>dSA0q~l1top^J9{Mp;~bPT}x3_}0OovUGVO#G+sdTDyGVq0eN zRbFSOWZBjy{bcw*Z{Ih{PI=hx{q9jud(U0B?HeseFZOl4{Q8Bbk1S#L@F;Y$MK!l9 zs(JD+ta z*}o+Kbej+U)q(JnWnI8{7O-$5t)|OVo_9 zwPo%%w)v;lyg1FO%PQR+$G9Fk3K!>riy(B*{YH_NjHk9m=;TlcJ#Z0(?z!J6+L{SM zyT%au@tt?SxRVZoJ>}Amf8v?ze&_Bj`#}=_+xX~x<8OEF8y)e}l&YH5N6aJ9e%7C# zEgqe`e{|&aqX(R_V(lr+;+wbsUZ5oEALkmh4c!CYEh;}e5|mrqTuS1fZ(_^SLoo?a zxzGj}_+Pgn(k!nTO9om)G~D;dr9{xqw)L0a*xa{d=UlT?eq$+nKUXSX^ckb)!L!dV zkAKMnZ#Zc`uOD!Ion3#u^Rg`{b#WsPKZ6-QAdQ*BD$)p3Rok-hJ04R%_}WXK_sIRc zUVcbhX^`3VjFYvL`ZP25=y!I zd%CCbY14xjSt1SCjuJebeFDaYNaH7og;7j22MXNe_U%~D=wYr(R=&h`z3C!KT7TI$?rjw27W!3%a8zt#9a=zenoyJ!HZzrJm+J^;n@=BLGI=GNjphN*>5ni=&PHHj zo)km0hqmW~Tb_YhmkqslNKo*91p9vij?v+2s2nKI5+BYE_1((KNt8O&HogDsrRjM1 z8x5dur50(ee}7m|y`ontm%}2&uRA~vD{{SfJcY;<>uJ{E@p6jzh`)sNiOo=CU^Jw~ zjc0MsmO2A$F|%+hx3lB9K<5=21-*{TLusL>vg)pWJqct=DI=|X_^^|5#1-?7-VM@F zGZVGkR1iR0yp+})tieaIka^oxvjQxP6(1u_^9&X<^%3RghZEQ}DsCMYT!dY;F7Xax z$B+mjXco624)zb7E*MxQ(r0!~ivu(gxr40>$jxwX-QN;T`f0SGdFtP^icAQCI z6gQ+`$isG^eK>SmJj)V=dt^9-2`>VT7QJHt^0`s(xbnaY;SyMW5XzXg>#5U&PKNkO zVJ#EQKDNTOgLQ1+(V6^#p1KxT)b62kbcPf{jx272j`p>4308b9ulp-)cjCBmU!IT# zY_qM_@6uKuvu3OF`jA0R*V(usy)3tMG%aVyLDzjoYb7&wIC9PeZyeimi!cOedI%8Z z5--NrYDTYY&Et8@6KG4{%2@9QPx)*b>(B8{*!TYy??hIE)5t&VA+T&ZIHHP^8-xIl zZe2ck-s3AB*QJ4UI1Dcr-tkHS8aYH|iZ|yvCPEB>pg26_V?4nsN?-8(hY?5f)p7m) z56ZIKRS=v|5uZ>Imk)TdE9vEX4(yBbBePZm`kzqyn^hPr68~lMa{Au;vR_@fL~7p+ z8r^r__kQNF1(?FNv*-IISFNP07q4MqE%2%P;#>p2zBYY@5ASR747F;WNVBc`Zcto= zaq$b@-?Js&ho9EgUY^wAG0VAkQB(KMtAcGM+46job!I|X1|}fR{QUi6LxH0 zbIN=6-@gBpYyaabPh9(zn{VH@|CDE5d*M62f6Kf5y7S0me)g9;Kj_zweEaHauDRwD zd}V2|`NscFS^CA%KW)1C3I_4*ndh!P>v?~+h0;$r`L2D>n0cpPpH-jz(a)TEt6%TC zG<((R$9&kYGf(!vzvJuBIN}(zjuL#%_wB!)9AxOcb6k1wUr~_K!(O?ma{z*>V?zHXP_4#*vlXlXEiPRIF{X0lwh-9>rTo-uo_^ZLEcfeIj;>n$n7{Gsm4OLg=j%Rd75nP)`hEMt zyV5@nCz*7DWf**Fq4MdGDxk6(&F}>SHlVgOs=n3$G z_SHSRZN00pKQ0~3)sw*s#|>1~r*PPff1Mw{ko0$bx>Te!pO4Q`z7ML+ug4+sjr4*k zA8fy6`#>$%g|Ptf=JL;^s(a!SaDq|Iy={B<#HTQ3*f-)SZ|)I52-43;ar^cS@kSh5 zew<&E+tyyT3#Y$fY`l$WlD$jKChCnReEF7(Z>Qf}**l)Y?)^e?zQ{dWcHQpa#hYT^ zs2qc5%kOn|9TTaDV@gup^UhJ|yVsVgGSrFjj|>JdUt8st21S%bPvHs7VO$6c7MQfZ zvg~Oq@mP;RP0Qj}Z+`gw{(3PjbG?u=)wjW2?Vp?ndG#TDr2OnG{z;L3e|ID;ifu&k z9+MovVC%+FY&r?V+*}vUp99_MZ}5xrs`~5plP=gryH1F@n--qRhndW|F-~S%{l1RA zx_p1#dH)U7Z^Vxr=tMc6^zlA>*<VGu3327qTO-s3r7}Ex*q;M> z?vt^|rffM-dI38ciPP#Ibe|1ru58i`ha8EP*t?FwrEG8K=Jus2cBue-9^%q(URofz zQ46a(iC4#$pX6yJ35M{GYX}VCvpwqHI-}khT<^=Jgj3tHr(6J-*^_99*W5t)V~^Mo zW@Dx<;3~jTd_eWs0+eyTFNq?kbPA`1f2`Jb$Pnn|oi6`6IW_X;Ydk5lyaS^as4hS2 z72lhqw>R}OjZJdG35f@7ktndEDR;=+!+k%lu%my2%M|`#*vLc#s)*_x6-{u$kQNxt ze?xrF8qXhO18mMBu{O(r%?mqq&N-FPw%}}v)4(!|lG+IvV?7&b;Dwzb%L;U2wgHQS4C}wYB}j5| zrULu31_M5wjr63^G+0SS&#DndHI#HFicW({SY1u}2TCF!iAQi{z7!Y~kw4mCH1k{5 zK2=Z1rpb{trt=R!)D6LgI)FkLH}Y~aN`pa!x!xYsP3#Vr5et4B2ZmHa%AMQ{Ghfgs&6jVvbN*u0(`ac0f|OmkQ&@_6~+GCbz+{LUzDb&NAW zA@J~xPv0~eR3C$}K++uec=Kq6U+tb5_6c%8-|ld9;Mlr}BZlB#s}0e_eu;`uW*>y7 zht=3x+{v^vOfH;(?UR}G1ozdr7`dZyrfhpZMHft&gg?}vDV01V!)Om*Ij1VkVFh*= z!z;bOwz@RuVp@AoJCcmI<`+h!CZ4dVAqq3ybQm86P=mml@HLZW)68zanR!S&EjLPm z<4yx&)*ui3n>~Df5QX-`EiE0YIdhYk>vUp%pmDIk0PZIzkX1yKdvG~MZ~6g)1YEGK z7#dv9wg>>f~s)Y%Vb#wS0I4-8T7fNrQWYWs8J2pTeg2hzLJmMt8s~ z_H}uc{N4d@J`PAhF!ZM3GG+tMI%MQA+cfg=h|}omWxE(0sKTNgGQjuep0b(-2=pAz z2;VYxJwKq>0PIBdDe^X0Ylh>$65rkOcHXqCJN+pn?E>1!o5!VVzAlRIiRBq^0wm&- zBn7i70?yTCoEuO3Xbb5doQ|W+oKTdiZerA| z_G|&%vd7<(?SUJC1)h4 zkfg>AICa2-5=HLy2uxle;>e?pw@HYmL#;f`fNdd*(dem!M&}U%ipr|jn}(ZR>2urJ=xm~x{VIlyq>v9rsg@HL{@K>rPWiQC||fA7Q_aQ zXe6F!7~|zEnf}eYeqH6nZL!N1IX#}>{OV=xo+-~WqQ`aYP5UtUiUCNFkex5^hxI^} zGor(J3WfR_xHIaY=eieTLQ23Xx2t$cV7(zD9&)t;G=6Nk5mY>pzjiT%L3y3@Qlxhz z0}bk>@;~;KI-;eI;vF07;?xbo1>2qTPV+ZlH&kcd{^o=o79AvsQFF93`|x-*=8ibL zaji%3!zs<-q`+)kno}pMdMXt)acGJ;t^snCuj`(XY`(3CeVQ>qeywJfEuU`J9y~xe zc;*#rC6d9eYpe`vdl5!&+&t-;t3=ok*g%ec+$5MaM;(GO$f?=lsi1x^9uAI|`vl$3 zGae!m=}Eox5=d`>@gznDJ}<(+Aeq!&c@w;>t(o5x&B+m%!tv-=*)l%_o7(d&xRFEl? z+2*`0qCU8YN)$P8LReSK5!U$Y$@pRC2{cfB19lWJ4x7lPFt_+voj$VaU$AS;1q&JW zugD_gobKUne*>mOYh9^@3O6STnp9+$J883_P!&Tl9c5rNKl=}`8jM`}N;o49EG~jhIB@&^IDCc~YPV?nxzTMzQC3Gip z!}KCkxRU}EMRUc0uzHiNnYvz+fq-=>HaOfk-EO|19f}#K4BI0BA(CK!7=Hq6YxyIt zX5eVRTI}VS`QIF*5{FEBRAm_0{gu1{BUFk70nmec&~Wwsy#MHVd%0j8K`%D1xJXco zHjVi5#hU?R^}VPT>J_B3Df=$8SR@1Gtk`S8k`HqUY7I+MHtRStgHv=bpwK6;dG|kO zX9fvTRYyS4OdHuHNu@Ou=-QbT{T~!5+Y@`CD`F)M9v`iK#*u(N)C3ER0mf7nZJE~U z*lCCaC7qF8yeuAV>&{{{!J1-eEJrGYIyenFp^eD`Y>2m>dB`abT}`nr1`2;TtN_>O z_PS4|CEFZW3|0)MlperIX2N#@M$89UZ)N~5s!-?rHW(2rLeNo3o&mpefR`6A5yM2) z*VzUQxIjz>%bUH$<3enK^cF)NuOPDwrV9s(_Pp%McI=)WX~zB#z_z4S4`?SsjW8O- zWRv#<=13dlV+DYl46t}*bR5T&Or44Tvx*!iMFA)P255F{c{M`TlP%~j96+d%DG7cd44pGM6kf zX0-FvJ%Ot4JXwI)Wl0~a^j(w;Jgfc(X9C1D)R>)q<~z!e8{p!*#a+!%?yEL4tbp+3 zdSoSs(4DGP&hNr~KS;nOzwVtT)Z?hn8_n0G-^1k9hq=y){Aehijh5WVZQiW@z{WA_ zKrIim0JSuil*X!gs%Q>19fTp4re7T9;X@58zk*WQ_WaT8SM@Ai&S_c}(=aMH+bUs) zQ!7p-P79itR~zC9-P9kQ(bUcLVNayX&=^;6Y$9k7b9YF*UI}z~z!_dXs75nttpu69 z_eYy4R+Kl(L(-vJJ%I{^qpASV)J=?wT@wE~#cdK{7)tW6opjuH(j~Z?tHm^#E2n6T zA)r#hYA+cc7NGpO`9Plx6)V^Nwq?}|!tDYy7j*%=l7$tEjFDNrxeU0t^rK*Uw4qNh zSVCfoNt1zHMj6qCIbFc&>t~5WOp5+(IeCSF?fCzAO;J8X!uhj^mV4jV)_FZ!UJk7r z2ljsC$x>30Cv$b!ZfF~9*kOzu$d)L60E27iM8`fhmxp31D%$`IE$T&e{wRTsv^ zNFXLrKR`@^b2!V?e^N3tp>f1^cg>7`wG#zR5*VDzcG?CZ+*-=&^cExYsyjM%2+O z-D5p{#~qCQ3g+iUihkiX0Zxj+{WLnv73EA(>7M^j!@@#kq9XVE7}))IwzC*d7RI~-he4#y1-_%NR{9LTAw_DT!)3|37(1gqgc-sH&fCYIN~B8OXxO<4LI8qU zVC$j)4hNwv&~`6@VSryLQmSKBR;0yQ9tlz1Q}HR-WbA?C_6Mj!VUdyJCQ>9&f44yW zVVsZ#gJi*IL+Jt|tG+a$H^*n-X6m3pg zR#+j&IRxHD|9CR&Ke~6Z%6>9qLLBt^zY%7L14mf;XSq9xJv5(l z82=adtHWwDcIa4VH&7Ln^{pn&uc5c7Ff~H}yyw6f}tGXu6SL)xAbJ!-td0!TB zSwek2dDpv2B?$-h*4c9*3gW)`5FSSO{XULNveNX0#Op6W8F+P>lvY^CO-xLi#X4H)!eUr~ojPHss?44w;xCZ5-(oB5%xo|7eRJK3f_(A`q zfKv0WiMi%+1Zfz?8{)EFhqh;8?!xA)x4(p=;2bVb_W9)AJ7;z(#rjLK0IO^%*wue1 zfRPn@%tk{4Oz;_If+`S*2eW#;-9f3^VNp0X?;{E-FDOB5FfBL;&$H%e)f*)x9M%&n zKrbG!521P~(H$jtXamY)!Y()!lGOnSp>GCBT?ELkD8Ip7EfHhlF-?WTAcn_=AV6Kr z_hdh@6)MFBqYm&bqf^;#beCqaCyq1D({@Ux(qyp{3NbLp0J#&-3q}3r+ z%^R8A8Jo1Do=~c`4C6$f{}1gP6?3r>gGX!-(ZiSQ#Ye|FLj=Q|S#per2fPAkypfh< zob0@lid?j~xQJJt2;^^OqK5Ko*zEo$RRZs&-$J`sf4*ze+TLk}pk7Q)=pU0pCac=! zGR0cB?^S{b- zg`yPCEW*rnyrqV!j}U8OY(^p2?QtB<@QXvG*lWAcp5G*3bTDF3U$O@_0}?}ie(qT* zxy}wp0k$;)p;EIQ~1o!=Hg?B_?8zI+B3tFO4{b2zP=FVklO9=SdJt*jV8SnlaP0F193CK!WcjR1}!0xmBK9|uIFvxLcox|Y!J$QTB3Yyn*`E5G#! z#fgisF+f)M*;>c4&*k((=PFXsUCzuujdrNhjM3z6OYv=mA-?!l8Rd&_w$7O1)NQ>5 zRlmPB_>bToZ&+jlA>2go*7yn1GEb7_NII^*JHgb#y9M*#&d=Zz$rfqF3z?ww!x&vo zdt@poy3at_7t4JV54F!IHM_m~cKBrsK+d`prgQvRd;bq6j_xVSb@VFu1+t_~-AC0k zuo{6U91Nbpe$GwV0|j~{&8Dn{g5~jFtVJSAaI5K)CZ6S}h?t&+lk{R%zfH5K*CGT_ z1MeE*`81ECf7DYfS5qvdwj*Mw9Q49w zTZd}P^Fxi0m{7GD9d` zuX*`&PMb0NJrLI6h!=5e{vu zjG|)>MNCveKc|2uG>No0XG91R%M>B{2+tektOa~gs`623qr#)8zE&zR6wrzmsiW2l z=a4;1n5KA2vqsS4+t~(v;@df5ZG1bQ;1S&<4hW{7mqLvk%%mQC)ntB@iWtUV2aN8> z6jlKhbsnue&J>aDHG`yEv8cF&2pm3xks-iW1y$uVk4LF`Mm&u{DsX>RXpB##pAIx7b;2&1lRg zp0(8EVWLqGdBQEC!Wes%_zETCE*qAP>oZ1?Y3YnH3cKy-MkVCf?0SqL8zy8v7tL}F z1l`J4Jy~N3kkJ0^KR!wk9ZBTRP25pxz|OF#dg*q0ulr~5%yW?VGkw|x+*ZW>Jlnag zh}~@Jx<`3s*Yr5XL3D7EoFQirP#6)z9uI6;JFw(d_D(7WcKE3?5l~z)A`I`%!K@Od z=i_;*9q3U{lscjyZe`u@bIN2r{YW}@{`GE`}Kp;6CM&9Njy z6-0Ru*R%s^hhW+4d^6GnBo4uGM@Pd><8HjIl z9g=^t*MD#_wPd~OooFY~fNCZ&!HCW0r}pp4DYjrl6T)u&8N}OqH$f};c4ml z2(FE)2hnj8S6UPjy*>#9NdVEVsG2>MhvdlC_rz}M|BkxKNEx_0%pYW`2elD~qw>P$ zt;g+T*x0DSikhQOOQsgD$qwXnH;U%X73CkC%E#T=A6&2!NEFQ~EUOrQ^B}&(+%{#$ z_5Y@WcqmN!Mdw#Va0=_0LLJ{c-E}o8E4?@W^aI|qGS$94Ox|Lvq@*S_0~`t zK}^|+?ajYOakvG=IdjA`Go9w;DOvlUm3z(cY~CLyXlI$vrcj|b%{9;EYJ2Ob!?tzq z*^9x2pPDEb4b-!+nwj96e&VgI^wLi}|un(Ss;)?A6+)&(%OZHDW?nOs_;jjMv zds}b@^==q(b_)LIKe5(yjbxy^TY1b7R$ORL#`MBd}y7EN^8*he`d^a4Zk5q z&g;-3;v0wc#mOChUvuj|c8bDoOHjapIN=2akAu|UGJ!j**aMDOPXD45U^$NL(>ycR zsuKrXeKFz;h@9r1kqKU4w??I+gVUVPh8=n$Y|(5Cob=mfzKKj_^KI9sT}uERL*3{Y zH*-rJvTH|pyje*EqyuK0L(wjcdR_xfLxu&MF8YR{_B+_7j$4e~+MZ-7!4=IBbb|({ za~V_}s2g+jhyJ?UDNag`YqM!WJ$|z`wfw^Wmg^E{Rr3C4x}nk}wH9fedRpV5kK>E? zx=6k0VF?-3UA)8eVIdvw-ZJWUY~pvvL4-7YZuND|7V=$gZ z0UdXtP$}+0iG#~H0>h%UfbQRT zoMIVG{MN$PFC)lAyTbvROFiF1$MJ_n&pbKwO5iemF{;-<4h+UQw72Ol>M;dE* zwIWLg{+DPCc-LKAEh?Zj9nwxNn!HEgPqo$FNi} z$*=c zA59Sy;Z4qA?x9(>dEnp3V+A+|lgp{n$|ViG?EfLmK53rXQbn~Em9pe-pbs7cxl0Dq zLHRjc|IAE^S+^6r+RRS%}M6D#u9-b-I@a;Jv@IvQq# zr(N{xBZv=d%lD3s*j8RrorKQAJK0g@JI~W2Z7dz-w$wDId{-)T6r~WlIRAByVZW04 z*Q<}XaeJSvzbQIazP9OLQ{-_C4==YCU^2rTb&W_uNMN>+-;tgMoRGuAT1W5s$hoNhB=?FB5U;nm5iL;NM#s-9fTr`wZ*mQlIn_Bckp6d^)C=|0xc zX*SDw$4U{O#&`~+NSpY^wsp%UE$Xo9wUN#o3AoV!m8a{&9LV(iqE3+2!@6>pBiF*c zdL2g|aqr0tE5`U^v<7!Lbj}-Xqst|#2gH8V&X>%MymZh*0x(?xfk6)>0__gb2qtv>|3iJ6WX;>>H63S>_fR_Zq{^Vp{oGs3pb!S*|YwC?I~d4=ovg#4G?dyzNKFHYhB zHD1o5oLB}x;@>%tos>Zn*HY^=$mVB3?<9k3RAf@|y2nBM`cigwLFqbXi@724_~U z^Av<7C&A$-Ll=lVI7?OU;}C0z(##AfkAC{qdp&2Y(|m+6NFIn1sz-XdV0~UPvD%CKQeqvr0WK#}VxGt`<9O9)sK_KZIWF&iAUEnqlgrU+ z!`(uY>eY~3kLFmKwmIAPDuvOaf~1bKUhJe7e>%n1=zj{R7O(&s0VjBqBIj^}oYB!j zI?xX2IyPVf=hV3lBp5(-Jllm)1SU{FajC{xxQQ3I^hrYkIUM_0q25Yo9QX{DdPRkw z>VR)STa^Hw!n}ELOF`g9$JZ@9C%?pF`lQxBFNh+(hy2dVC-cGX=K8$Z&l0ZWaF4Rd zpKX%6eJ@FP7ln;odox0igijv5P^Zbe^PDAI^?34j6+pF0~frvM(SDa0L4x_7=@J7XnfkwQH zCaE_IZL?%?C&YAh`cS=Op-mhR8P#~UR5+m~&khI3x~$p?`=$kY@Q`IPJE6xoosa1) zjU-lE`V|&xjpti(U>IZXHlK@GZ)Fg)^~*N=*9_W$Y)wDEmI^?mt_(i$==~*;_q937 z`Oun>vZDnXSXd6p4RAcbBAXjAG?(DJ%?nc1YR$MxbN5F&*q&`g6zbhR!Bw}w4`$~8 z6#T8 z2(BT197Sxm`8yYze+$D=@ZV50msIOPA_M?j0?h@pITi@z@{g)LFy)rN8t+;JPx$Lp zFxT($V~wG5IwNyU$LxMnfA*a%;rW*$L1-`Wus-u1;)o9 zj4B9tMRPkM9B>$^pB*g+WE}Za7bj#VLcDtmi9o!&v}7{{q}++uQ_Y_78{U1e*r{Zh z;ZlK>Dq^&s$wW@bk2J|2b!2$7zm6Zqo!P5!y7KENoUVMVfzLpV?Q*i|3}s^EniSRR zx=I&sk6BhPkm8qGqgB;wyQ7uO)S1HvLGDl_SOgJ}8JL9dynk~`4|^$LyzL{NGU=;yP*C}i1-JlPhq zA<>M0&j!{V|HcXV!{NAbW8zWrYPocUTZC!VOHRty@Ug;6I6CzMPs%agYxuDHLWok& z)=TiOGW&I&AqMp7qpEk8xI`V?uuh;dp)quV(R8#1!j6t;wU9{LMe=e}L4EYzy56?? zh1^$=K{lLblw6M>9#%(UZVXuSNm)+6=oyb)${3d(?p?||ND5;6$(;v67{g}$i4h=ACMu^#n4T7Ldx?W*<`dfdm`B8ksI2Tv%Ei$asI=sX*IHhTae~ci44s$~lH43+R~N;|^~GtJ z<`CzjGVxnj{UnJB|-C(vsL zMKvb@zpI8vG{|Ds&c)QWxgsa@!PwSw_L^SAddkz2AXW1a5@nE|Y34yJzxp%NU2dFX z0#yk{%p?A{93IkB9FFlLGNHAaCS5XaTF9EW#2M!lUR56<;~l6F21qB|dIc2YCLLe# zbk&G6=?#})rB#0V9Q1&D+ZS&K)w8M}6=;89?G8|qBIA%^kSL=X{Sum&d1Sxjvh`$i zjE(`he*}@jU)$v9wYsX_UvM_`xCd(2plVXZ(5}EiIY^|T)ZD|yx_~zzz)Z6`0UVYt zMNTxM1)$g6*hV;zfq*pfk04F?7R^bZsFy*TaLauAm?(k1hJniWh%IU%zZ2aDwpOVJ zTX$K>LrgCxnq`ano=|*os1QURJ=kQ^n*)C8$0S;G$-HD`I4cd%1lo|sSa*)kk0dhq zFVp-lBCAuU)`LhIoH{-ybx~sh=hYl67J%~rAT**nIm0eHeNIDaqM5F{cNp_) zrq5O+ptPSEe(9JmiHnqhdoh46&5+KLnSBt*Fs83ixE=eE)SjH%o+cZ=Dd)LXvILQ4 z1gCXa#T=h={5**|a_;~+L)hMrXZ?C*$R^_qrFX1rHz6yI&(}3ec1R$IhuLTH*p^XU zw)gL-{@T4Cz2?9RxWXuGzo?a-3w?|gV@s1PA6wR7dw%0E3vsSfuc|JatXaY8D)lTK zAP6O8C8OQBk}5&~ZIQ_{vlSsc^Ysz#hhfxl-izYYA(M{5dgC3H$1kh)#nv!bNj-T- z^}Ju6g2l57qb^izFOscII4ZFv%}|93MX%B0tuQ zslm}F3{GA()X=D$cy=MnPBo5<-VEZlJcMPK+AcDTx^vD1>k~K`LnbT|(4r#Z(;izX z8Z%B{0D{fI*c8|6zqc$V7M~zMHVm;c&sW)tj7$kjq_(==%fn2;hhRP+>q^%7EP?8& zRx5~#)0dtD0EkDxT?AIH4%0zgYR!Rw5GyhQb20HAgW||7?s`R*!+|R)g*_s6=Uyt@ zK{cm0#)UOL^M4=)okwquK!t?<24skdzNrw}FS>=*J&ohz>F!@l%>>y!og@tz+>u6| zS_*aZl47STs)t00!3y8#02wIjD@U?s z>CNOneA1ybA&)sg9YX=^E#ZRz7|)3JooUf>)MnJ+It>qzKhne}K*B&&C?d&cQ)}k} zj}cSm`Yb5O(eYz-h(a-&I3%(+bh8y)X+I1dcso@shIkq4)4-Dlc<105_#e>Al7$!R zfWfi~TxVEFqhV}tP1~%B=ELFm@Kc$e^Ld(?wc$AVaCT<@8+nmm(lxg@Ps?AUvoa@I ztS;5qaY6XDH+@~V@O5?dg7MQe@wM3NV8f3LUf@3j4-;aAy$=*1Q-GEN!p=*^C>@CJ5{*K_(m#g=Xnyp+r9&79VeF$7)?T4J*shS7Aem&B+Cc zVeuoqLyQkF;s^wmf*&{z)T~^WScIe?^J88?Rv#@|0;28;9Vzk?z6W%|k|Se-L+7$? zb$N(znkQb4WnXShJ!TPmZ}JG8N^%b$mOv-oTcXB+AY;koTzD(M7daPeMkz?!Oc2JG zlupM=2T;NBdC@FCGkIIkh%%#>G~qV^0HT)t@9HbE=QNVe+AIraYcx1kiR_Smg$@*OO{e?l?xXK?-V5F?*XlQqmnr)WI!0uX+osDIO#-HL zLOwB?W{41J)!?Rx6gO_Y26-;3K5Y5u8VybEO8k%trp#9Vj{Dpl{RDUPRiJ>ABSQnw;f8rQo%X}0yC?ja|1MNKxZ3OUl#$#htNeJRqPnXCwq+Y@%8 zey2|Sg|nxbjh!9*Jg=Tf&JNZyTs^F4K?_0(MTaP+-NU1cRxK;H_fdC2O!oG;CrmoU+U-7BLfRJ&+} ztSDMJ$^$$C@Z8wguIP>-mYq{imdqj#PfU6ujh|KFHlgeDB*G#h6!_k$i{|L()CKv= z!P$z0neL>4u06S<7-q^#1SJ@%JSewPCoaE3eK2NDLAP2JmWd4D2B#5Ri|UbkagY)7 z792pFt&f99X;1mvy2RU>!Qf7AC8elY=i91X)#FF*=T1qyxB{t$OFJbOu__>szBb2H zZSQ}uNFo7?*O0*)T_({xXiWF$8P%U4lVkxFNiu1}=?JE^r^_Sb%>-|fVab?z!ljwj z2T~#d6Zl8&Vy0C~HcMdVNHwiQ=BEq+J1|CtYO)MRJp?ov7IoK=FsD(mZH2evMe;dD z+(0leBSfqGkAidv_<{;h3d4~YUBtsu#R`i^4^F%r*y=g)t``9`D_|-Z5kIGn*gM{0 zR)f1>syF7IrB*bLI*SpZ7ol-(yQD5|ezAU;e*cfTK_||n(^1D3K)4T*6n$B)=pcn3 zJ}`94f`6f3;tZ-$lFLhVQxT5#BL`>Exd&k?bp-NctNVH>i!P3d*k?YeO_3z~LriQF zcqv;Q+!4K_S6OjUeIhWc|C2o3y_(We8G}11M%d<|g|Kpi(Nt?Q02dC}LQaG!Kb4dV zggL0GzJ^?@5PZs;Nmh}jrdxFm0$gqzl3F1OKoe|=D(Ot6Sz)$r2M|v|kklG%oOCgo zL@>(fv1(LAv|hjvCd{jdBsE{innw}Zki~VHEx~bBYOzupuDinb=9cfw(60uKqO>!P zAT#;c9L3~IR!0<6V2M?s-uBfpOHwA?ZA2;uc%34#qG5!9x+Lb2`OIjY&09&@E1YaRA zWX?l|f^^f*?(%^^)aD&n`=|Zt-zOD$CgO)prSGZE6~l(vJW~O^kJEqZLO9K)k2-y% zyhd0Es%$J=QZv8|vikofkCg!Ugd;+ns%1|Y#z*`E(&`KL0K-d3_HpJS!@3%JQjLNw z(eVa;OPcH4PH=O{=>7S`l(JiOhcM`uMgyEHQbpfo_W~<;?i3dm)Wn$>l8f`sEG zM9+a{P|4@I06$Fg2?jdtFt}D;`#LOr;Nm9vz^5r##%m$ov~v+jjVOV!g;f}sr*J(v zr3JT}R6tnS0=7v?F#tjt?O*vK*0DM^*a|+Tugd4b{QZqM3?u@_!yFJnb!$f8`#hX@ zK>yGNDuilnSA=q#uw0NC`6iUmXkmg(cK?0pqA(Y5?E$LHMLlK93<6Ll+QE zC;6*etHSj~Y*kNj`u#uc5=>618>DlkA!j4pN^#5W+Uy`yi6jJdixITD-lUZXDy~8n z=wWD9n^rO%F=5nN*9_}}PQwbuO)#nlau8;sl?20{ZvHXbiH)-gnjq7t9)v^NU>Lbc z&w{)3RiRX(7!G1#QwGaC0J~~kl^fHvS0#tEq{DXJ&{#OG*FM5gZA)%cEz!5kKZ)#PzpH+OeYz0f_7h^cI%&Om$s1vcBTVYliBbxVp<7 zEG8_GwSM#Q>mrgMh`>5t()XS4tWKU~dFJ2?j)g^B(Ry>><+1a@Xc}AyR^-_E%EsnB zuZ|3h*gl~2#Z%}CD4o~`3VN>_;k7F`dGfQRkq%HME#6OlQts4A6#4MB8oC}jxQ<&i zmtuT6S}b)(hms6wrg~S}cB4xY$a8nLaTY}lseKO4_&+?$B>7o$!h+3jgC3db_^_I% z^WIzIkVbPt(@f$ZL+^u4g)A{weYeDv8Y(XOujr<8k)Y`wDuD(rSw7Ol0iuwmOos%d zcRE6EjVF0^Ew_{Ktl4N@ik_#1YlBmGtl9!w)Psg|gy9?Y+`PTHH})Eb#>*z&8miU zEr^a(sy&2ESAuDAyTH zTtK^fJ1!g}UM}2N5!_x8_eT){M4ydq2l1W3DZ(*tPhVMGNRAhNEV8~?`IwnApqVw* zb-ZG)7T*UnX%#q$EwiFPd!l()xN0;j;X83w8|_1<1gN%G*O7=S6~I0Trr1i{0!eU* z9}9)R2PaQkZUDAE770-n`W{%4YChp7iQT4>g?3{w$y6{!1RH|6V7;3Z`B9fZpms@e zY*L;UmYV{sx)vmRlZFtCo-uwL+WQyh{>Bb$@T7aNRdqW6qa9g#C9Hp8It2YGkhtT}vv1DV0$jaBE1BKF2eZPzZ zO$Jqm*M`$@|9_~u9{OXQwWE)W#n*}pBptmcylH_&*JtOLOIRZW}vW+vM?9Top z=BH6I4eG1(Gf3n-5;Z9bS@S8xeOVo=J{|*pL4k7-nYjKwfssPMJ;FMt*U4(JnsV#4&^A zs%$;%&L~HEce8O*2L4*$3_f^^5{KKLwIf-#dgEkuTNeO|l!|K&)pBW1m67+DM)0uk zJ33?r3E+O%9xfuU2B<`ytB3J&U+gv_?GW0^4P=)oDGW5A(hK#n7Xc7@3(9?IS|3PaYFM1ZGi!k1J4@rPEp(vw+n_l*M@XB(n$GhmiDaWS~ z>*t@I1{0zh$;i3Ukw3>CK8Bvp*;6%ZzDpYJOI+Ej5l9GeM0lJJiu%fM62c<_^OSBR zHtR!Ue-w@+h5=X>Ig{!0gS77!t@wJLrFS?+ zBFV_c0&!=}$PYl9AE#;Ir#c}o8d4li%E>qU)i#8%HhZ!XgEp2ke?F=(_zQqMlgBIw z)VOf@!!me|%KgSm_ug2256;T6(j#1iZHg&XI*z?$1i(203%CMOvD}bBN7>KNivkDJ%-7-feH4r(ryga{n+kw3&Uoz?#XrnjeXUZj`VDr%lUX z4>k8+m9x@?8!Z4M%SZR`j5DV@VWEn_8KMeqlU0vUJ90l=U1%uKwuSVa?7l}${S&wEyIFq|=;5EfA(819bVdbpVG})U|T6H^8#wG4$nwT-qtxBPJ3gJC= z`dlZ2;$xD?v@YV3sD?>0*=P{zC9ds|AMxT2HYJkKn&%SMdEj3Q8RFse%}f z22OB_Gjcek6f^EgWL=vrgJqed7StD$phw71M?P=m=hMvmc_bz>F1uqf=DQnbegiEm zh6|b@PCxu!l<8f-+D!Vb@>_4En!f3aMz$tJJ+xVF1rSF8=lrPXFRz}dJ2Ak`5gi^R zCUIu&ivU?*V-zy@n?l_>`_Lq?N_6w7Q%G{?EuQj)D-XytFU#vtZ$OBw$qCJ1tPnM- z{;WH)BjK9sm>PqY*~eUQ*lPL(XgNzs}hRd~iJ}@^zr^qdtOKdFAV;tlFDzX_(*AeO=+e1^V6PAUD+GDhm zFb&VAW4kD`Mv7KnW#^W-R}zx2Ms?L@CUNg>-S<88#{@!~cGV2q36 zR~3xMuqZ1Ogm)E^lY*!gH+k-Ynif5BfxTX})INhjw%#pbX0CMTGD%)|v3>t-4lHpn zH8?71`++B$tH+{@I0V&_$uu3l|3&IYDI+#jzp47~FP-tAZ|lh7aXK%LcPxMWgRjuQ zoAV(oOvfSOJp8P(Ut57Us=EM4z9QZ)NA0GUY6m~v7!*ex1EWlxXZbx(bLtsV<_42D`Ktm!`3|3x<@8_mz;J^2v7*4%xUzX$MG(7xwQB|sYi^lXUtQl zE|xkxh~6%$*27K-UK0$KQ$UxpqR^498g2w;MU*SMDoEJr&l}dQB|EbDfbHBdUc4RlS>_|EC zP1^<=%pf9(m@s;OO26$)kXONVV&r5BB(B3v?!k2?D)5NLw#Hct(cPgP0haIwpgN=Y z(S@=kbs?Bz&dLs+MXG=duGid3p=Qx=Eg|yXc#R_RcSSAx)Ur#!izb~IVQ(3)Uzs|O z*@&2o5UX6^odle=81FsgH#Q8%K-B7q%VNI9_z0THu6i=0g@L*q3DEaOSq$@Jx}S83 zSdpn}1Eud&S`jiH^!x9Unu-t>W~PjY6lrFI)X1Y05Pxy61Bu5& z!eaGGxBiZ>9n)qPiqocMzbqN(6KH2JUGd*x2Zn%M;6G^7g)|`69gbNk(e5!3xhV}v ziqx>rK^jN2O32dEMRTIBpGv7oiWE$O*d9Z@6CbI7{9L9zQZyUj z9fK$XoR_}aJVHyx@Sch4ENEo=HeX$+%n0cK{fsV9`v)^w$Qq?-8Sux4A^)n(5wTTOW6EZuVgtyF&zUZ{2*)m&hVt{%riATCCwTdYopue_Cy2-Wd! zGYFHg2@KUQn{WyIo=1X>%z}n&BQ|Np>am|HP=_YY0ip@kU>otn55_Qx#K27^(Omns zG(%w~5UT=~_{*wgxQKqriEI z<9^d|u%Yy!RGR>K==5R{n)xn~X5(HRJ0t^Dxt79!)S#`{7kO%h&0i(9{cco!hIZOY zO4*o{h~BWMNqyOAn%~ZFh>XjFs6?xLp$yt;cfSN-%)^8+#q{REKnZp`Z=iT-ab_-Y zW<(^YIxQNqn-sPo-1oewC?B$WihD27%)I5@1Os0F8k~TS^Vn(6M>b+h)sxty!}opC ze^z}0#DlyNE$LhiVq0dYH5A_3e z|Ns48C}gAju=nTJ<*(0Qm!Ea!V@`hLIyT;xT+H#y51D=F>a{P+)4$8}%kme+zf1EM z50d#`K9>p=yM)_#z_y`u%S4iJ2Bbo4+b-b zEvc3+JAC;OD~?+ApbzHtF~@x{KmJYm8}l3T{rR=|)%mOQ*W?f6zX$l=k*~?G${&1X zeq}!Ws{EDt75Sg!AIx8pzc_z>z9-*($;G>#_s4&9(H}l{Zu@^f@4Wx(_n-cIzx%Xv zf9JP<>#0+}`5V9b)0dDP}j8&7=1`d@kYx(|Z%=vt^; zgU7M~Ff^zXSc1Hl%{9xPd6QlvObgCf8oZCvi_4h9t-AmI90Z4=!;XhQxD+HbxS{e& z4KJF+i$Wu?0qn%NXqHz*&)%00-h01>Q%PG4>u>Q;IAkM{(cso`rGd>m7E^iuJoVjy z@>j|uinK>7#3Kd_F0EiC2OY$Q;$RNT!bLYbnmw^RkMFZ}@7VHu4!1rZ3;9z$W&q*J zaJYAz(Q-5la-PXL27l*sA>$KaQxq08a0tLm76O;0)TZnzI8f_$-~qZ(@_wNA=Sc2J z#k!L~7~X>^xDLK?_eXh-T~xg&Vn8HK!pz`Q2p3J>Prp2j;SI&Pl>NK^uhW_+)CvzgT^hy4MrS>aMWpRsbD z3HUX5&!R^Rgj_S9zI*;D@WOC0jm>d#l`vPU58gHZddTxM?~XxReT#>uTj#X2$$v%% zetSOiCKiD!mp+=$yoV=4gpds0b06|JNbG=F|K$F$D9w+gSpFF2tNnnL zs2ipT@{Qa;dJEY`R@Ip^Z=^)?i4;ppb7bf*_z0O+c3^6S+>iI>3*3AB=pgSDTh?a2= z;2YLSb#5w++O;EzDnSAe_n0Z6XLwY{-NQR}&72&kVt8=Z6 z4oYt>2;URpq;GNgvYwRN-%#vq4y45$+(bt)r)UqvS(so8#rBA&qIz4nQJpmbq3V`HQ+Q$z@ z;t)%|JD%S6Ju?rmfZ3h%w)v5?<8nZ7^H8i7Cc0>vZSR9WJ7m0z3IN1v*WfKsu{44% zRDG^A;C^Es(92vXPU*S;Z8Q1K7eHuG4yEiVGjGZL{O#D}(comA4aSR>%(rnY0n|<+ z24z|XayQ)#_K!#9{%2Nvyh6RvVSxZdWIT^}p-VU4aaAhLbpzob#o)~;_YHGrSy&5P zrp6pz;b9hox6(ZOzk9$Ega&pnF zLzMP`+YOj3JmG5A6z4IzIrsOSMsClK3t-8!L{4{?Y^@8%6WauAz;J-v1?Pf)W>Q80 zRGC)Y5<0KPCGbMiBj#2rhs!{EpKdN8cR@yY)=EN*7EV#_wqE>j7>k)uJ1BNwN#Adp zUyN7^OvHKm#IXU`wS=MAM4Pb?Gk7|7&b*EZb5Vz0lj|VC>chlm`Qy7&XI>AFT$^QZ znAg$11aF4(4U%FA!EK`74TpAp2on(8_aDll^|xwKJ#sip$B!HyTWn4Ll1^7N|3Z>b zk>&WBX6s`w9mX-DeA~-6Djv)JxaPmr#T*GJ8!-?wKRULc`;i*^s@AnZH(dij4aP7g|eIX)7C1%6kJ@&h{ zJAw!Dr2|hVcd5B;<<1L6ROd21QrwoD#%cethmr0R1X9bmRIIb8@uF=U1<=Mrvx>%} zppECzxbx8e3^G;K%SwQkh`c_+{4RtE%c6t#2~asi&XD^A5zZ*J?T3%r)PAb{HT!u&?O;b#$ihWrYteC9Pwpfx*{9;9i@O8i8yby&1K}|wlQ$9CzRLstuGunJCX2;XUqY=ju6pAd? zK6PNH%>+BrMC$|_TUeMeBxYWj53U-+Af_E}PIay`S0sM6P^+EJpX7sA!HOaSj=oYp zMxqVJa_&6Nj*t%>58zu3DQaTi&XvY%^5*-PoGd&+D7&?NuegBD{I`gu8 z@F%>8NebbXa@8?j!HU2(;>$vhH2%{2R~W_&d&6K1n$aCN1k}70p|Lfg0*CVZWQF1C z4y~q-tYJTVykOg%#vI=nWGFUj92Vz5ExNutXxIj*hpYX;WFQj@@OaSOJ9 zH?s$hZHphG#Zxh6`XUd*4)}%Lm0Stpz2qS3(_=Vsbd7{dMm=zz@4PIQS{nc`+>tg% z5RiB^XF)~&srVC{^=$9sP!$TfNEXJ{F)63eybgj+Yrjaw#1Lt<*^(57GzsJZrLU%?t4U&_p{sM&n?>g6 zlz>yqVW#SgCc4$lQ(ogJ2X(IK>j?OInj0sa5xb#@Sf;BhTx4#m^#l_ZEaYm8s`&>L z!%o%60=guWGyFUqIzv8EnA_*1;Wt0{p{u1=X=CCS9vRQLro&ysHz(Qr=|5Qt?^0VR zPJZcukJ~yKYf-AL`9;vMYQPK3&eV;QW8_Im2?%sSBrqbTuSEw+ z%5crPNUeO))PapH+QNBT%xOM$H%rDEfd`mfDmpZi1QGWRimhl4(FCi`8O2q@&$U1& z0L`*goTr!yxXsSt?~7Z;lHH!SR(qELas41L<@uPd!WDQvPQ?#||Ia(`Hleaaop82} zYm+~Sf0avmlE_F+i=})Uy97e&E3Wpw60SuWD)LJjcpp6DWi%QMgRv-JvOLa+DgtJ4 zP8!e812(Xr5ge4;K_r}x{DZZnvYb(vmGP*_LYLF^fQM5u_@HGr@G-cYDa!hQ1U#_1 zt%ohSh==PXmX&jg=1ng^|0yqzyMOE18&L+lR7gcEngmET`H|FQJUWmb9moeS`QPsa zr9sBtTs$FFU;#cp+3a7NiD>gtF;@7yBJC9l)sBpFJHv`O#sFc?A6Ek9gi?g zRR=l{xdNGSlRIN;vC^36db~mQR4^rqMaG2MDRqeofbX=l4n7U|>gmU<#8B+B0`Tf! zF`;MT(=S*`k&MFoAPPwm0mVJpuEotNu6z0RpLEG6A5pBc(4`dO4xtmvd!Rzyc6)Pn zQ4-l@kg6V}Z81+NQLyk8tY5GAd;zdwSd>FyfQ|8gY^~P5iuFyB<*BS04L>y{CDw6w zv@7Of;q-=|Kp)O8oT)*bc*jwuHf2vmP?>@>+1yibul3Ri6I#gO@J+^&V1}gpAf^K( z$l^GbX`EQHWh#q^PFztsJ9wh*khI(F@Yq7j+@J@voTdoVD%rm}1oVgC8+u`GiWDzx z38(*6^VCb6sBKkb?-?qpp?`Kz)$Z6F!;J|oA_Vvp!U;|7GS`$9g9!rB+2ZV_nR80@ zFFhwFVT;??IrTg2vah3mC(49QARfr&p4$9Z=L0UOqJeYma6!KXY%_aejaJJZUA6e5 z{HU zN*}%SL0n35zK5W<`1yH01s6BA{lLIfEH2kfm#mS?-g2pNR6_iCzJVVRoSDf`7HBy2 zPaB^v$>R{Nq&ckNdJKk=ksAcy*sA^=*nJ}7TrxheK*k3W8Aq8&HHz2}hXD^sAv|?v zw=~3$#nz1gon3_S({*4jx*oi9IQ#PeLqlURgb}JJR)i%WiV_$mK|iJjod_oQjMB%Wp`})JtT;3a2!=y|NUa=q@B7!8laFXk7e3#e_S8%#a&R_0ol!-&X zhjPDQxo|0pv~&)eJ2y?z_NsTq65azX2C*lkJ#~hgwAqPZTrXGu)1Xl?c|KUu4)G8+ z#;EqhKp=?pwe5{Q;<9k@1!pQ8#eyINa|Bzn=r6|CA!1cjpXVYv(4Vv>i>Mw(vnfxu zGhk~~s!O}8SdJJNTtWjUK)?sc#s4S3_Y_JiFTf&ydq>+>V1=MX$pGgK1Q_KG&E5QJlGqxE(`o)Do{}hQ9&2z5{7C(?B z<}n_qt*Z@ej1@xzqQbqUe}BqfRz6JtRuUmD(%e$^bzn4GS*#8=&efd|KkcZQWB|Db z6%3xtj6EGCR1C!TYQqEU{}GZGk+KiSgVpX@(-j0>enk?{VHh&}s4BuL2j=brL$h<$CA zH@ACJRX%v`e_4odvxS}$$kSt8=__vZ6!$(*_##^*)dNiI#h8 z-BAP;p!v@Do+G<^K<3?*eF7RUK-t$3FW!_TI?~Mu;Tp+PkN60tp0&fF!kN zMZ!Z6kcy95Z)xkT+;gCsTuS}_0tp2X@d374AHP~(Eozg$KHJ)QD=6M;E$yY+R$Hy2 zqQyu1W3`qlh5!4;Tzj9BfbBJM_TK9;=a^%T_ZV}|x;iEiVJ3AC(E~+F6+W}GC72`hEL#WwC#UMw>ONAiMt#8sad#X*Mpyb@S$J2 zZr8P)unl8EXJa85SnPPLM@VP*r|+=%tacA6wB~N69H0zoc)TB%4o@Hu+o9}Xslubi zm)Tt2!md^qHpg<6s-NbK1oSFdkA{v;kF^zs+TVlEKa z*vXxcelP+B|7!v~Scz@NMJ4$i^FxXT%~+#Uaym1-At?VfFVV zSB>}lL5KglE~d+Z${5zG-kewe#D)>bLLO*}y5ijE>g`fAR~*c&gF(n+jS+*KYCI?0 z+2asa_lwcZ&`_(_@!ov|SnIWnEr59b_?lW!4@u^j*^>RVM&Q}tXHfm)6tMKFZ?ou< z%IVWHDs>P@7IBI5>;6QkPpIiHsG;EPxK+okH~p=*h$gkSf}G-QCeDr3X@n(0PGc1> z{D30CI776Zz(DJ-?g_Mxn}#})WVG{}@8X5FdHBg-_L^q)X$+1^gy#O6Bc6{?=`>#; zY;#k|#ed@>G(@<02^!LXgGzrU;+sp=tJ$@{DvB~z0LoE;UnCD`4v8$cF1ntTz zh$q>=yo~;|?FfO*mI&#_rzKEay zA;39U%6l=vFa-Qfb^ALtvyS4w#~?shAK0BotU!VS(P1&>SUquV6FJfDxeXDoE1EA8 zrH;KA!&DE$NQ=V`At3&dEe`H<6vQgmH)?2v&|{iZIgZLf#`rr6wHlK3?M1JZ%%ioD zL!JhFB|v}_?a#-9_Z0*%VH@uChijt&OdLj0)NAR`R~qiJ1V!2|yyT$!J`qwwV0AO* zhewXv9`b#BLb)8TFBAnO$_xFBd~L z)S0mtvjyo;5^Wq6`+fj)Kv%Kb<{A_Y+3I*JZ|-}Q$Q#1~B)^0$z-G>{%?4Jhb{PsI z+Rz>ch}jE0!F!Scq}_oTKRw6j{mDUqF~*7mb4fViPE>SH?BFO6HO^qGT{6apJ~UiB z?}xqPoGiyXHEM9pxnuYsws@2$fI(2*PU#X?yhTRgl7wK(LKy6tb`FA)VU3`rLK(8n zR-yJL_j2_>7w>5TN}3r6j9y&TDG$Zm*`2<0QN0bUG99he!z5RKJ{M^ovUi}~+}s*Y z_+587S!WHmf-f-53U;0N7Q1IIleA_On}(0|W06BE)*Ns;V14MQe(bqz9Yev8*8Ye# z80qYIenM!*ag70X%*FFoPYStib~U9T3$6hnsT*pM>isGH!-<4)Iw;jQIM=l+p zjDuQ@i#HCpF|Kt>2Zjp)+(NzWIl+ENRy~jnJaz28TWLN~N_H5f#PKrH2}oL~j{=`C z4ksqsVM{W$a8;DpV46eLyaLU&&&D~2Ufo=GSt@Vs$WeSx4aMn(h1MtI;5b6rkyDuK zBQLMlaQw+8FLUGmF3jB$20vfP+%okp$OVYU1U;+z*xeZIAf3fSmOVDa&6&iTHh3_d zc2X?!#lOQjM}Nn|NnWL8oMGiMMkz+xGx-V=1bHoRkr8Lw0%@kh{ie8Pi?SRp(33#* z(()F3qn0Kez{lbusZ1;{LFZHqDT4=f2N@Z?S2qXsX4MZmVZ$EN^LJr@a-wLF z{KRNBH2)rPstsgRs{2sPyD?{28e3O;9i0c(OrbT^m`&bebAN18^*+kFH8d3KvovELo z**0j{5hJ>Bbt7@Uiz8E~^;5mEFf$YWgdeD(nP5|_tjLRin!WvB(S$czVvtjNMT2%6 z*0mXth*`(NCQ!6!9U z{WwsBiC%p`Lu_mcKp{NzZ4@-m7}#ZEYht@R!WE+`Qdd!ZnldpcmNQaPn}SqSf2ps| z5-+=9RzWFOS)3D%-kn$9-m8jnaefG z)@zBmJh~}*2w_2pb#9Rj0Gy3H1w(O=RTN?)SJlt--gHgc(aaUi-55~J(hz`Q7X=wx z0r3oZVT--v8Wo}`)+msB^d#9X`IO>*qFqKu_rK^=BT%VMJRIwKzW(v*X8bXF>1w`S z$s06&AM6qSQyX&^8iXlH>oW(>V5lvQjkl98t*!#Zs9M%3$EA+kNW34}9q2UbMbZ(V zI>!t)rt%fWZ3*rY)rrpsi~)9|ex^&XHo`DK9J#;<>;jvkaeCQf^BJdSH}YmoIPMeMqsy;r$JS20#di|sOKV_^Z0=WBE0=WAV9qKJdK_60#3HUMh z9%GBJoS`0c3nyJ<&`!GBTsX2z0>Qj9Ol8eZL^_dU&Q%PWN5`ef+8Hrr7@T^0kKq>& zI)Rj|>4rqID&BVYRD3GrK=Y2TvJGJ-f2<4>rHxrUBfU|V*CxAY#%@Uovlu?EADZ66 zN<`2zmj5ul6&hh2Wi@+kdm&5N5G~22jS{6vE?|fx*X1Dqz(opaI9TQ}q~)dU^X9ZJouqE1F9E5X(At!nF~iro1uv983Wnb=!jE_OL^7DtPMIM zRl+`>@id?LYd}DF_0MU^E$J0R>|H4H5g#geJ4s>hZ1x|r(gtr@f8WEg0FicG?lEG;(8&CC`vK@r) z#r~nzsxU#k=B3b~DSS}9f2I}AVOs#oRsEmWcD$s2Nzj6ei@+0@=n91k4FIOn0wSLSDsiCVG zNc0LZaAFru$z5?oH9JeCjJYiSPLhu9EzC1tpfbQ93}%xy<(s*)>mD`dZSVi{9jBJJ z_#{TZ43q9_Fhrlp_KgZ)Hg66(E{B}1+5EaEp$rfk>=qCq`;;Dbb zOUifx0&!P29y0!k#*Q+MYb@hvLBzYcm*oMwA=3GZB2N+{Za@G}3b4J+=e@;}r6lQpS@jSh2x?^B)j?wP za0ON&MW|hKR5v+P1-3fZfEFaL!V?NnfVqA;B)5*0{+)PoFunWuU(BJ@qDe6@) zjH`EJ#OxmYtj(k5{juMY+^PP= zK*{Q^sZ)yIt79X5LvRYm7=HDk{LojP=PTUqRR6C_#hw)65*u8#8m~E5fl&-Y8NFY< zj0L8t*B3@IMBRrohGeeZY&qL%km_tz)-{r?5Z<&BR{vG;vtMD!un+NLS2}bWG&zvK zrxZ7q;sX)HD-P)tLNc`StxwVpS&1NjvJx}R9qeLBaRP*UdZg9OIvLxFz|;GDhd1=D z{lvRw2n}*vj~O(5MpGARyZc z(`OAX=?7l%0WN`QPR}k$JsD*%mkEe4LV>6h^KRR2wP>_Pep8sfEwI54BoxzHv6vMQf zKB$~nRL7*T{A~YcQUZDG*$JN`Ih4&>^f{t_b->8cf2pUR$bh(y@4Me3w}vhAHMBBaVFZ*4)~agZS#^7M8{ zFlrTvgKJmgVJ$G*l#^`7>d3=FhRu{Q-pl&iwa}v~Yc9nq7$})Q{zh4m{(II?G5MM( z-UK-@Ds0^`LR?CnfU+iKRep|fwM73pRX>B{6tQzqve*CHq(}eo}Mgnd>-b$?HUALBa#{JQ-O&9+_;4Ngs=5 z=F(EL?%=sWTj+pirs-;D3WtG&0MsZyrV}KT{^Rnm(OhVYSU@6gtq1J_;_4rORVJ-G z%bahiNmZgIeAe^eTwaPvR9oCM9iHgnoUjn4C%u!xXDlADn>WXvv+?xopOlXrp8IV- z!;%h5JM29pNCxcp@GX<%KOHDx zq7ZldHI5jjR#x3u%AeIsc?s|ZX}K>Vxvf4cy~F8O-zanf#esZhqw)EklTkpSQd! zrSk_%7o-5bV)&(H^X1#8qTuJJHBDF^vP@(!VYGTHv$47STsdS%mtaIN8~A)>7yx5T z_Qw)3*GN1KWRtkZB(6k$t-@Uj5S6@QE^YDgA?nA-_x35C>`2cnE;I$v&PB5}(^qn^${J)fSP z;W)@DaDwbq(>psniuQIfzReu*V0h(96!tQnJIG{D9jIPHteQB>f#GJRu}fF5ZYO-} z^nHsc+m4TR?1hNa&H}}&}yjgEXtC2Ggbt;WRHc*Sh<=U2zTYOn?Ltw9*hR$Fy6GTq*YP81f>vC2# z(aRjr*K1P#m~in8DAdhAr9_5Kg{lLPfc;Y&y?afGBRFN0PLTBCT|qL{tX)dSda#m=7ck0Wt6M(mIr6iSJzA(P zHKcekZ0EQlod`W(3@{WYB?V3L2j+B{Nsn^RJOxZm_x zWt`uZwZkYdg=mQq_!Hd`kTFJy6=!^fYg@vFV1>Z-Xk?!;Tbcx!UAH1FRV!K({`A%W zjNk~OXxZ9fY~WNJ^0-u2xRlj9)oviRg84wk1zhD`6ha*-lk?x&a$4^E8+R6#Q&)@Q~_KB}f-Km62xy~dMq2UFDF zfsc9(IWW*#o$rZ0NzAKP-@!lwF)+cpq+z*F^rm_{JvU_L`Hzj$;i|{DaT_~TGa5Me zf^_VzLI7?J}N5#*yYTk#`Unn zFeEEcmBP4b{5gF^N;7rX_NM6D7DQKlg1{vPKBol%w30;sHU(LSb8PspJ-8;NY}ZzQ z7YY5Nuy@}kimQ5UWY%M1HY=q)3(uAB+haa3qZEsbDNTrWnm`Mss9;_o}Wj<=S{+R5l=%@ix$iMp6qgxhZCA;FRb5lYwG!7lrWZPj-Boqg5# zbZn9oY;-shXtTeWnB;pl>8CW7-8Girsuq zIrxeGqR|)w3y-j+Wy;U>2@Q?MKd~ah)r1FzMX{(8kT*YcAwCy0V*GGg?~kBl1Qzgf z+6bKYT72;$`~rZ`8l^Y!nJE2ZZ1l)cu9B$D7Z~FTnlP+k!>81ws+NYa`YuNJWVpgn zBuggs4YF(Y^Bg=`D>%+M;VZy=FK>t|sLJUUu3$OSOeNxkbchQU}>^?8omQ3ZQ6!b4fACl*7oJDt{owZ3ib#+3%ZRE-rFI=HzyY5`D{ekbLzzd8P{ZPMpmhD_I znmZw1Ga|e3v@rBF9UXFOG;*p;oF5LXSe?)ALlA&_oyUhxUAV}Y#6fOjU*7LH;j60ei4!SZA7!Nd>P#3r&Q9;@yiTP z;kt!X+uFvlAlrCLUkKv1&s@lz46rC_+O+2YuWL7XvArpiW9t!aT1(rgQT}3|VC!Vn z&B!HeRXlkE0N`%J6*zwTA1wDYGgs{8>&%t$i*FmQ+`IP_$Z0L|ad*8gRio3QFE-S< z0u~Lc+1xO7T?#A_&NAA@&C`hUWxh`kNjx!MLd-ORWhN&klEy5ogrm9I-Ke|NHWbL} zlPmravf&WlfbgX9<$k$F;ZPVM8jFnqsqt(gF5-*`c2)EOw%m%?;QU9kW+8CK9*h#> z5XL8{72<@faxCs9&xNpS!}NT`ReD7U1e&)xWOyVHlNHeVXcPB`C&MlqvqhAw-9jK~ zqFs1bpJq0BF`>{Y5=+)XchE#JK$0~_HSDMrd0!5gM6xS(7SeE$JH1wt^&bxtD&F*} zTIy>RJp~nq2dS`KrrKOM?WypzV*lM`Ee+(&tbIrKrds3HUyvTu$j|Fa^cP+^4iURgE+Wp>Q{>fXdof}d}g zc&@}BZFYmh)aht*bPLDwCCcL3$3ws5GPZFECsvTt@2e+g} z&~-!_6LLm#hQjjZs~L7oXiNeTPym66P?Hgt=r|9an;teGQX%abko9-+WWzFUToM&% znx}`)QbaH+ioHZ+727oSPj798ND?RK8QFm@Nfi(CdlV`T4MhaED9`}#-8l<#@hVI5{4Lg;o zQ7Q7_+Po+Bnm>C<3eiup}cAX!L@P*^ysw zf`QlYfh^0-8xUA;ITeXK9=Uh%lx&its;Otc3q-i9K!N;HYV?^#f80;MYEu;?HDq zgI;e`2_wK)r2zC35{t|wZ{akF^^wB=#NZ77Ge3@%9W+A_Q$!ze$#$2!^b6C#-Pc-X zz^7(g!Kon+>kiu}9v@%(#3~;qpy^W4!3W$_EEW(11};FXB6_#P zWMT7om(LE`|C_kaZbM5k88?A|z#v`;uTQa!7NP+sG0G((Go6$g9)p6zLgNFl#mdJ33dW-!i8O6`^eluLcC6Q>_6TIp0Yh|Z_aLj+KQ7S%oIrb>jhxmo4rC@b z!UaBUIKa8*nd-A?(<)eBngQ!Fn-57aS$_+(B$5(0P9g_eMQMl_gca|uL=M`3g6`}l z;CVPDGUc1gRZ8f>!7=?~SNB3uf$<3h)^SL^kibZNA}dZ61cCTdUH~Ihbin$r9jb+S z%fhyVl?J%Z15mLnb41vC6X;%#;m??ZR2Evx9Hh1S=AAgj+~x0%{4F3MGR;x)4jK{_ z#xNQ5Q^Zg>>l(g0vc{e~q99i;Y=Ac?N_ZwAjZo-!+!6*BdwvmFfgD(cY_VIhYyXQ$ zrV`rMtYl={+3CO?o7tcFn$hNZb9(AI8*jzOg4CXhpVDde-;Cvv*{%@mS z4E@jioshqkO$W{$Ff=2#X`P<^aFU{jG`i%3W}svrX-bnZNOJLODnZfIs&Ia?<~#}+ zC5L`w{}|vzysXd@$Oo*58YvfOjA=SP-_9;qPHs#j{&^dD+5+hDaISqPZ1@^ZY*g21 zoKEd+-ZE2t)kN3{f(%vgw#%X;`j+T|kyFuNjD(p)NkykbINKQa-c&e2S8;<#QX~EF zYrguUl<;nH-!p!_ZQM&oUK~FnJK!TDyIO#M$Y$9-5f=2!SsMd>B~iTY(yIw_R=5ad zJ+^8zsc|DF0Htb-0cn!NQJmlgx+asrx_JhKOH2&FK?^GZvC};@_tW{>V;gWhD`MQ?hxM(d!?=wF3yc7=8RMJah#nvf z{(A}?@zVY7a+y3ptI(|_6QT+^+sde8YNDG;LUg+)Y+xa!HMI%PK_1pfM)oYo4k;d~ zF+RfMq>msl#xU;{lItWusglKDgI&j1iM4q~L_-uu#Zo`YHi||61)|WS?dI@2mo$42 zDp3`=i>BJDxQy{wS^r&C1o8l{;?uLCF^aWvEdcgFxJ!C z(dMSsE-FyU=4@BFAt@Uj|5tqd-c|YU&XA z)8j%q6_15%xWbk>&kII64T2b|t}|rFj%WJ*DSj6yJ8YdI`W#uo&L>K=n4Jeo%xvX3 zm9W4ZTjN++0!4ucqz<&UT>W)9>iLQ1_RYk%ssgBWZ zqbVc5P)BtyeT=8|+c-{9%MVi4fo+DahS2Je?E=xUjx%27l7W0qBkNS(WXNz`!7Ri) zE)=&xaOW|DWJj7;k4%-4!}O4k-r#X{jzGJZTU<=%_lT!eb3>y@YD)Jm?mw2XRX+sd zSYqNbPWO4N=47||hp%PLpK!U@*nIrcnG2^NQx;^*C-x^XXYJYJB6b(hr_FH^a4JyN zxentM!R$Z55TbMC9HwdI?*kZ>%w>1*$Q*+L%m}dM?08P?Hn*snC zm>99LM|~gb_Cv@(d=$Bw^4}9C6?+qMQFh*xTyWj z$ifJzmY_tajw2-hj+`H@lgD!%Kt$u3eg7Q{{2#Z2*;Z87xoH&5EJQPcl;mC1wyu`Q zFs08y%`u+mF^sw7hCj|pafvcBh*`>7D<;u=$#E;Qjex)36{umLiP{)_V7`6a`dW5} zKKvCJ5i(!{0T;@puT-Dk2;YOkv+B7xnIV!-iBw?#MBD4I8c~ce4!lgrl@-Q)0uBD! zWT+0`>Xw|D{n!rV<}FbK8+;X#@vzt-^EhUsK4Ubm8rgYUlX$B48FfY$k^PCi7P^C> z6Zem3nz|rW;*f=3+L4o#b#Za~6#H@^&crY}lKP;n8EJu;$e^SPEc)@55u;o? zW^0xaEDxae?pf-wSmbZq9KZly8XjAZ<~@f8c2||05v~a(o=le3gvNSNU|O|^f6F%x z6athEojCAzJ;~H<)bW271l8pA?Ee#l3NlCFnN0@l_`w{1Ucp?OX#|$E&LG$UmqS}< z3M>eOyD~E&tk$Hk0yx=9d$dM=q613%ZPf^X^9MUU`ikc9zue4G%}!QZ<_e?Fh=G8{ zg%pN8cGpk7v_AGF>^AjK#=*NZcI>YFnF@v2YrSKUVO}45YwW(XN#+PseN)7Op%SQ< zS0Bnfv^Q^1lin$u?Doz>Wx9m`^j5k0)5|I)~hQ=%L4_yO6SXyY1bDT{C=R zjCBmwB^u<->tjF6k!~^e&x+6)5h@JSH1hzH%Nw!VHfvB)gVD@tCRg7RXV*F@_f2e@UW)?B@CVK_oY6j6I>U$aYgwV4XJtA-RHPy`m8)w2f$dhVcg zbEbu2t|OpS$2NU*LujUXkfK-jL$Hd2_`8prTP*VcdAnsSq=~^D7qCl1g@QHlU-Nt-H~;ngz84w^pWp#b>;p}Y2^U@YQ7Vfs42pCa$CU_@f3DQlJIU`(=+b83c@yGL^8M&A}d$a z*K^0`qw@zxIr9)7(Ggrg{JA+~;oUCZ${@DdlZ}6xjkn21xyG=s}E{H6e7ynqL79L{{ zH@U=_3SL>DPH8#MqMEe%h;4g9Gp}ulAsaelV@)a(ycs8!_;E(MnK#$%@18p#HsDid zKMm`PoGV|?pxO^oTtj7_ivAp&VXkf=xF8-i4dRV6Mg!<31^xjj?Hf1rL7ES=&FFm2m76X+*Pyi4z@cO|M-W z`3+w5iP1XOq3chvlF8j9XG6H1h+V*@R?JaI763Mw4ce+ybNIQ^X3!o??*)keS&l*{ zzRmUkW7*g{XajXcRfte2Ql)e@K@T-Rbun@_RZp;GrxSTDLBBBG>UPVZLcxWKd17() zMc^3)lzu#0M^pr%2x1bM&0rX2f#76vy4l5+@FXF6M=MKsc6xiF%rnNQt-c~l{4}D!;bQ#yYoO! zfEDYM%mD~P@SO5DLiGslUaOvH^sQwyJ~_iMp-+PaP?`dRsbPD#)q*RU^|2RSO~gxoC| z9CUlcVt{Y8ga1`|#uv}8%!i7Y27yGKzy!48h7kNSglVErCC0+7GFJ7L z5}8uMOcd{9ZyQ$RV@F0m_0bALd{HZ9pdGrB7>!Bi@{i=j*rh5dk1_Q!rN0=;O(b1t=#b`N@*yy$G(Vz_17esiCWpn-5Q4P% z7N=@)d<^UT5 z34DzrkzIx~KKC8=GFAufz`{P~lSlZmOF8U=8?U7%mRg)uBmO8AkF?dP&K;fzHJ&>> z35L3A%v9h35t$`ibrP;ls!x2I()`5wq_^ABiDzW(|9%d5xciPUVIqUfBvemIbMSCj zK0G|pCu!%cz0ryFi9avb6!nR^RR|VoCyq`?o)uwnx5NN{7&UDX%ps4Zqd&n9VM4;Q z(1X-)`00Xlc-SSPArV=?qo|Low>}e^=K_@(5tbw1@18STs|eNAEYy1`)?Ty^=iT>Ck9TFMW*HI18njjvxpzvS&dKT?qXqj?N^? z`SQ10*#a^!i`?~qEf-VG9$ff!6a_Ud?P6n&Yvw2w#} zuLMPTqxlv!3mko}<4tfUf@cO$j}9%~^o%~)x63dYnB)YgE}$ZY>-Fk7 z%o9t_VaVE<1s-G9_r^YHf!fe#3AIHHMjwt^)kKbESq9z$$uU3%#q#v6w-V!YnR@fy z&eA;MgRNDw)(*X=%zOA8XhKXD9-kSOBAh}EuFanh++0L6M7~2+6KUbrZbEP>^=B#* zM+9%yTieMM1Q3t%#fy*Ly+kb2eHO}Q-rH5Rg@F^oTpmrwI*krSs{U=+d@=f|P%l$U z{Fz;<7LG=DQ}ke91R~y=9m#`)AeRVRpOw;GZO=^}zRsh2yRjj({~p#VmIbZaWZC>a zHUU#h4^MEB4LwXp4`{+_QTlv45|nHdScn~hsWw^)Xrely)BIo6{;++>Rwqe|KXfUe zdNAG*%Qb#FlwCH*#DJ08I0SUWLzm%`+;a!(NBjX1J&VnE_#Jf^m+~MDprMQq*!@fu z$3`~49V%r761K417swa2(Xt)2U=_xpskNcg6g=zw&2+xTU5(qhjCsbuF^U`*$BP1E zv@l<_aJdBwI6Z6hSHMdkA8@Xm8VQn9|_1WdH(@ia1l&#qPENgmy!u zW$uE3SdR4sYfrtoQyO4Hnw|W_(P1IZ|1BHQ)`Y->B#{$QNBCW$!ij{aYG^DY@({n* zZ{+Nt^!3P%RLQW0yxQy3knp$>RPg8!vFeKqZ-xL)^db$6DPUu^$A(?*q$t2B0`!ICcb`My5wXV2k;39Nt#W9 z&>c@fH!lZa8;DP9eAsVTIQTDyyn1ASiM36UGORn2Q+A> z;uVWASFk#IcbKXjubobeU5rk@Njh%Uu%3QmqBY&JD5S0|_u*J@6^E zeorfy7c^33E%v5%)?zbc;Z1EZzi7+1NkC0+@X*HSi%N3-5Od4Mi`Z+BDBKeiG!=C3m)3bhLWwKI>tcg}f*1UrS zhm}4v>#`!{4~01^)xYLLyO?P>EHbr3&t>!CYP;b~1a*juI%(ysdF`i+hNG8%J`mM% ze<%;zp-ZJvAB2RKfje9MQes6+)WV?`1GDSp2@(as({WG;fEBFZ#8@6>-U22X!^#3V z`V%|Qfe^d<=LB9*$^gIjr@$M)9wKVPoN;%C`K))f%Mp{*W>3U86rp6g6|sdApZmQA zbsO9}F&lx`_0`)#EA%5z5up<=p+_d-H*}5yxcVqI8v-0bA8ge2^w2}U;?_95iwFxt z7i@}Opz!G_8!{0F1{5Ro&1S9ECgUtFRbOMBDFf_}G6}MJ(yj1^Xw51P(k+-4nkaiO z?@VZII%q8j41%HB>bCtv(|8DkZ6jbfgEU|RXV#gv(LYISyMqorGu2ttq*H2U&5cBp zJ9(DDeGQ@^JRr^0aCP-6VMd?~HI>LypS2HZ0UT(;ituy5%ewJ+KF|$mzp_x1m#% z2V$?C2>1#tgoaDd*WT5eLFF0F5ou2@lf?lR#8xi(9!B%_)(k z3%sY1RwLMiYJw=1Nhq!UD7C_r7(n^HE0Yd;rkp(E#Kki@)dI}+#DU^|i-P~1=X0$Q z#XikBMH!i97_jAt)arLwqc8A96aQfdKqdM+lp;yADgdUGVF36n#9|4TV%4;O zi$j9S3N>ZK)l0y^HV0W0qOkk#a`jsl#PgIhI>cpw{Icpp1e5iqXwZlwzRTFgAq`5> zS5ptdG~totRPSgIOf$`+o0oHn22M?rJND|jUhf-aF}tt01`)CdY{Bk`49`{xSpucl zwX8?gBvdlW%>whSP7cB*#*CUcJ!3z3ydHF7g!QuOfF;BrfymFUJF@GBeLg$a4du7o z)it`qOEH{bYv#=Ghjl(AV4`ZS8$i_9CBEt`alWJ4HSHcb6?n>U}tyrR2KZ>EHR z`AB!riV33h8!m|27pRO`aCW-QXK*CT>U4X?;HsX>&g8rT|2R)p^Mr6PjRAV-1vaC+ zSJAME4=lJka8{tQqZ6NDN9Y!DQpKC60*bc9z%Eo31W>ZYA^iFJygiIS<{DEh#*DKR z{T7SSiF?W?vCTcDJTz%AN=k6%W5;WLgfY{po*xksD4IoTkvDP@fG80;weY?g6jS}L zX|0KsF*g_wD81fW^1Qn*2o7dM)DhpOx(-HgXO04(LdperQssyULs2XSKoaGK#H2e% zgvz3)&WQSRwG<6x)$x4gL?2Ia2gl7d%!m_YokgM2}HQc2Y=hW9RF`eGa z0&_GC?Bs#ieE7wC3`08CTe7G>p1S?mV0&MY1Dzldvpq&`r$`UR~ai zpTxKDIuOG;g3Kpj7)-}H4bp%6et?T7s_Zv4jFHt+i;w>I{U$B9Wd zQVN###~+1GM=}D+(X?<*#k`bD9wXO2hrAM=k*C>A=|VA|Z7T(No>2BFiEO+5k<}_bCN_b zd#yQz+T2c5(BIPWIa(^^x5OMGZEMyQqSOJS#&}M~V{Z0U{r0pQMf>U%U&lJ$OUixxS6$K;OIe zz2ww#vG=zseS_ZH>%z@>1ZMWK;1UNlElRivfZ>0D5$)!(P1Gn0p~o0NpzDPEBr`KG zp5974jow}LwER@apbVeeHq8$!gW_SFf>jU8aFgd&T7>(?53xjQJ5w7XIoF&ywP8Pk z%*95%ZCFXrSKh=PX<3@w-D}U!zLb^QpwAI z1&E;Jl7>P=Z_VyzqOIY|nj02$_taJ~%O$k}&M{=xCw|6@EEr!VAEvksS;%qXV%b&RB(WLOvf- za=xim(JXM`>_B}vyhP5W!jbnWUF-tc6qQxUrkbuk5u4L!O<`ikT4pW8$cphYqJn6g zy&hyL8S4`xoSklym`>HqpA0GH0<7s}L<6<#0N1Pj)F3)TV@AjcB-{5ZMpqMld&!6j z%!YZ0gR=?DMTJ9nJ&=%Hzky_3Lb7bzaRi{T-IT-Qf&RhtYxkdM2pIz9U$PxHMx(1}1+$cg5=w>aTJ+^7xz)rhS4?C`g!K3Req-*k@i z>dC~P!oT@q4%1F}C~oU~74#RAo&2wsjQ|~6k^uKs&JRp;pvk#4v-*~sT>t}*tb3`R zWokMW=2~B;J&;-bfP?WF8G*ULY!O6|T})J}t$43gJTE7gXsmAIo_Nxzz(%bL^8fv4 znv`hUG9yIfR40PaG`@vwG89ud&cbni=>DV&Zn3kW*ZX|8ScBpK6@;T8_k;@b^9d2` z#ujgfJZWb&v=$rWOK%vPF64BL;7XK9%F}H|%phbyJpvIkEai3+f|}obEm38FW%jh4 zeF%|nZ+cbrOjxPSE%z~}X@ZqW#CuBC?)~`E!QrC-aq_re(4S;)#)1N|Svld0 z4uU6RKemv&lnXwJD@;KfN$6Am6emm2hz5G3NVXC3bh{^_a%?AWzaz{&=YXO|<~7l^ zbr4ud$d9jSuLxu;#N&#?NLyq;gY1$THwjQ_R!n1g#c$Z1#0Z!P;*;PB;Q1dzVdD^o zQZW?viy$IRJKcnKzDnmjw2u9yLNK(!KqA+yVii|mJ_v-6jE)E{Ur8?zQN|TxP{`tt zVXMbe)JFt+u3~qdcfz4hp4MLr6;$Bn*ixs!^8|GYaR{(0W39k| zOLQL+Wds5a!zh_NAaH9BL>qV&F`_VOM1qtS=>#fQPbA_#jsfxxhjJj9X0ALPO~I_1 zxHt_PQO9S>t-UivVxKhT6k<`6o1X~3#9ZWZsL4Z8k_2HWM!ltAplRj(UuFt?-?eUL znrd}oC&(9S^+L)-IPspp+z+`fO^cit!1DQnPbf&Sl5He6Ma~_jcO4)6iwn%Z!Ps|bp0g$^gk_2O&mW|qc zY*yWw%Xfieu059qPS4mC7Sag-s+&@1D)#C$i!M5dbH$^qHhFH{QA)_g+pAAuB2~W| zHPKNqva@;`aRsF1ajivy&-^k>XPR$jo6micl=~-P2yTu_Hi|WR=5}X^Un#Bq1*DEE zX7)8}n{{=$ky#zL)jSS+%&__g=vk4>JT`;IkXL@@M(ljdIjEDNDZn$hD4Mh5xFFV| z{YAJBPhaYsYF>UbWy}~g(gR-LsBC_76Z?~5ka=!BblEAYGLQ@I;u;hkBT{f(wH6JCV@#syb^5nKwDsodVIBtU9 z=I)bF%}Lu;Pf=864Y8N%O}UN53`{qFk6q?Ks&5g@aX`dehN$FJ21?gHS3M=71fZq* z%Lqz&3T`+I3SW&#L^}FS96)T`GITR?H9P~8Flagwfp|xpveTRhAZ5xC8bJE(oJU-i zm{r#@3Duo2mORPzaXW!s7Sl_&mth*456zn2z%E2_?*rc-H=N)gk?3tQC(Zz^w80s` z++_4C1X0g5@5!r+5yTRZPJrf2r~2e{8XTQM4AnoyhVV5^;$WDMO{shxP_*!g>hQ%f z12zT^Po;Uu8#Ns{5aWf(>Ra{H`t+2Q3b%j3r_gCH43M1U!f7Vls9LfVC(g7$ED0IC zSOrFx22##18#xy?K=U(>+&p~wWVY{eR zoEp)J^NE8dvLp|dF{mIw1uI|J8Uq-lXp^c%^@SACKdccw*z?;nD$iHQS^R-8}!7&FFGEal{hoH?t^5?Q)5!C`|B34xkaPQLg zg;aE~ewi+j`@P<-i06f{ZwLt#i(n5J=~j`CKDYvcDU|F^560CJw+Mslfc$=0n9I|M=E{8d7gQ?_=Y`ZLiUPPt9#|Ud2T|~t-y67J>N4iF*Hr?wjK@zl9 z1Z{fX+2ll_DI{GYPFkw2R;b4ru02sGN7zfoYtZec^=nd>Z!=HBcX%5qEZRyy948qZ}h}bWR&+xrC z2Ri7hIyjv&B7niKXW>*c*I7H)L77eou>-g{vKQ6`hj|3J+K60*TvH9ubgKNy0XzYm zN-8lNL(g+?lnM~9Ux7;|xedZq|G;)rVEoHTu8NZ04u{QHBd0D(h@3*QW%a8Q&nDS$ z+#~#XN0vgJF+11iv=CEHqbEAl>O^l~`+(`_n-7hN2$nQAUXL=5_tA@ZdlW_Gy%8X~ z4@Qs^#AI*nOMN1liS6Y)kuldc88KODY1HO zF_x?_Jf%tStf6BqcS9ii&eVbS>8;uOV0@H)vAM{0)h}bUJEMQa*V{l6Z^DYY(F!5+ znR)M(`NWBb*)$6HkNPq?$z55MHGlgm``g@Ol_u{)=vGe98(L1oU@B?3=wDr?m{qPK zW8nc279aSfRvkhUB2%#b^g7L*7t#cUXJh8Qxdn&hTSstcD1rjxMh*BV0y*^8=rLeQ z>TY;eFEyX|HQ>{9c$cL%zAO7y*TjPm90Byu6nupH8T=wBe`WE%W(k8Hr=L10Npwr= zeo#;lfkH9ldfk9+K_U`KAO;*8lK0t(~6)v3(ZRr>25oVfF&7@Eq9^br41$*j*JI0ZL@M zl3Wtd*omlA*1IF0L_)_HXI^C@e2${vHIHgap(3_u_HEX|ZVU=eVFpCj%Cr-|{RO&S z?Ur=)Na8Ys0ei_HUHuY@l9^!RveXY^S9y5Y71jVS0H$G#QfXk?=-Fls_*6&3yD~Ra>7Y!v5=%TEq=(_ zvSKluCpBKcE1Bihl^&4*>8N9#0d}+MH6dc@@iw*BjY=^d#eWv5&;}EJ2v(4u>Mq}-QTiapITmM@IIYGO?K|)e0}qEKUc;EI-j}KY z8NYXbGxolMXo5c82aJI?KDK6;NK9~9vS6W`aOGNjjBWC*1`>3OlX*;4oN1Sm)P$Fy zLfnkZtfh@L*Ow7+-UfwKFU#AO`JtVjHKCdL_A}{50e#mQRqy6$I=!6}-KBZ~%%lVO zu;t(SO40%0KWEMRzpAQ14!5S<^H=Mp=6nBN*4##Is4Dz8VhqKZ8<}T<6p_88X`nIw z14g5h<~4tZmia0pV$q#USz2DcJITbmBX$Hf*(mMv!31ig)JAm@aog+jt+%o!T*Ew3=@c!!3+f zoDSuLC`CpDd7C3isx(~fY$&hM(DQYtBOgxyOoW=H=Yu#{O>|W!`k$`1(Qu-n1ztql zC`0o^4|aeRoEkwV`kIu5wru`cDN9L5Ry_!3Lu|+KGQFl`n=sp&4OA~@6N9|@UEj;l zSi!b797luhEEZ`^(&5=L>4f4mU6N!&$nj*^K|c~-w7U(^__C7$BxT>ekc&&qT&AB# z`FN~rS^4ID=A93mYMYrhwn=DhOv5u0rTx-PT9AR7;Wf6{uFaB!GSo={bmE%u=~P<6 z5R?9ZbC%43?aAt-omUiT419%JTDK_XM@(khi(5D~H?KHSAb0?5ggDHaCm>ednNMC` z(3Iwdh2r&kvEY`ee7)iPA%BYA53B`A?u^#o#NLgno?>y_u3|jdB@yqQL7*j$7)>kE zJR`7dD=wq#fvHU)>*fz{M=d4)2|3rsJhi2Ra*fSG!)TZdml4K4NTStw?(CYcb`Tt- zd*;Cf{u+j_PP<>lOpG#cE?Je(Bc+}rVBcI+r{bW*w;2Ps@eTEhk!Xg=Hcl7|Z;aE+ ziu|g`tDw*_)p}KqiZe3*w|Mj7J09qc$}n-E;Bwc!)7O0XZIhdCe;}}#i`bdw-s#H^ zxY>H-k%i0G8 z`v%iR2V_!tLB%BXamCN(>-R=!6|(eEq!;i1D;!V&jdl;QgkP~ku_Rg%?zTeeqPikN z*|an=_TvqJ^eV>`hft9-5tpUro_8-vm3`SxDbq$Q!k&A_(SY3`5x4mBy8k09&d$FM)@{MPDsW)sn0?_BUY-CWMw2dfJL3oX>i*hKaM4`7HXr8Bj1!twe~+`5_pS-xS?z1c>s`rkVNoW?@j2wPXjvav zS+7aKQ!H|7MF_VxaZ3l;QYY>`P`oG+6$cp=t@Oga{!tC~zEngVOSwqX%nb1ih;f(l z9v|gtgACC?sCqdxeZES0EOiEnaJ~=RuLBtCQMwI|dLM=LBP>z-G6|m40{OUME3ONw*FvTt6 zV*L`Z#{<)<3$sq6JEJmOTMa^x5s1tb%UoyqFf+lH_LNxARSzfikkBR=PC=$l1eusL z-AtvX(VLKgiUoMz?_oi(YaCB7LF$@#JVXU|jbzfB4G;qeg~BF#p`XW(!tg~)aq0PM z1E8oFWQBu>M8|xUQNsK$!bUYkSrV>N#NdsXipbD*u>_f+Dc$Ii_rj_$jSggn^_st8 z!B&C{NkpT^I}jMjD5b5p#F6#>CMQHc&Vg&{DQ!J>jh1+jtr4R6?yWFt^&90duhS!S zeo!$CWIPy7`@*O=aP6oYm8^A_Ga8ng*_f1ALGUAAZ?fb9H`sVO;`dCAI%Z%H@A$I? zQedwm?IQw5u~|$Z2{7O=&rv!77e}#&;aWz{59{!y6caM8VsR|Crof7+yyj2grdD>r zq+1wXNMp9c1p+k-(~9I6by<4tcLg!CYSb&n$zlgWTie-b)kTut=Ksl>P7R4SwzHKQ zcoIEuVAQ>KSPGzGVIGM=r`_sOMv?2iF4zqz7o1RRJNAs`)eGy6tJHXY11tqT*l7nG z24H@m9In2VxnQdeCbrHFTvc~3-k7?i|Cx2Ofe%i{31Nu$LTH87GW!-li%oRjyKYAg z(?F>~zwiqy(8}J63BWRB2L~K{w8f}=W1Ey{V#E&K-12+vT&ahEby*t1wgn`kqVxqY z(LAH|4n|g$bhwiEnCJt-PWx>1o>S!4Aiu$7+IIuo92j*xs!raFBkNg zlZ6ngJJ*654n_3mt)md!^sD~8VZ~Aik6}z2_;<}sM>9j8g7aI_2nGfw;CM?78A6$# zB%Bg)F{j)?tV10g6_$d6uqmTkn^F%~xzEtJ|ZP~j?p=-?M{6lF=z6E6%eZe?w zgp48w4nQL|Ibi`HRe&|u+(T{2k*qBji}oKc_L24=EErj4rk$KI)1u1{fiUVPQCHiR z3`-&n-LZxFjqFd|K@ak~`UZ!`7a^_=->FeEHGS-=u?9BL{`PrxL*2(!RHv6hYb>yu6%%Vg^7}F`-ldZk$?zz2kdx5 zr?>!9%$WgWi&9l;zMHDu5O@Agg}R?A^D2U2r?KCHd%aj_d+8Q9eCS5 zV!7GEXy$47@9Z5H75WRs-8oav-Nm7aOQg~?C}Qgv&XBC9Q{f8y>{d7wPf={gRCh+Y zchD)<+6k-85J5AL9mPEo+3<*ZI?Ryt&J7unCU*-vxe9*#8vH>`Ah8aFElC2!u>UR=YKx#hr_81F;;{2sB8>k3MD z(m^@y9hQ;6h8=i@{fL@BXy10rLj`QVEo5b^qr5)Cl;)$H+#K@+T!{kRFE~yE7M}B* zgbj#cb_dZ#XEGk+ront}7(x?1#UU~E?CDw8k0|qj_G+%fN4*c`DHW=GNE+lcl)kbc z1=rL3C6>i9j;ZdnQ_ZJS%@_e*R$~Nu*X;zJkRL&+BgbdJFwwm!F{z;oRK}UCX9o4- zu>wm5&hzSZ830FygE3v!6&m+Kawt+VHLhy8zI)q2MQpFXwSPgJ)nX%gt!-S#@T%27!Po;r8 zk6uk7aP>6b#w)K**5}d2l@DM=+wMBX8PbT01bRKj$>vb`V1};a)JY<0 z4pjKDvV`5q+9u7v`HKm6C>W(g2OSnr`F=8jkQt}h@W}*xcx$04u4LH7vTwg@al$?q zDBrg3IhA){(Ol{^X#QL1A4})+O`?cFEi&8;1c;UD%cT>)2=1}!AS+NqqafJ>$TSqZ z011D&NHq5!PpQNP}p!VC%rD92NLX}9-SF#-%7N(1A|Om$iM z!p_sZ-^$_py4W3FAK^Gz5<(sFvR^jEOMI!Rgo!Kjk-Fx}!uZyf@s(}kD?7Qu6HG^t zbxCauf+pCwz3|N`9ZxQuk=(B8Td5$Y!mE%h-DYIJK{V(pjc~!BaF-6exw% zz#4R>aR-jipFlmxS7JxY4(B}W$e+O9kU-7ca!qqE-bSnZ3nXV-UQsMHcis$JhQt(@ z)J1-Q20DbHT=4Ow<|y7278&)FxEadLSPg=cLtl~usfksjQH{+}=7HUm^p?Op5)*gF zsn}uxLa)htzb5vv>+Zv@%OiG17e_Sv(;kR1IvS{!n)_bO#AoX=WPWq-6q1n0%P&3I zG-I)7iyPJy1;8}lxIK%TO#S{@1atFo9s&rPs*&?eM7~+LDPZ?SUDGcVxr=uI1lYk) zl;Y$rr@B%Boge&IT@vOnzA-9y?dN~hGlPSmPa^^%iarbD0T}!ZBi+qKj+z-|8`;ML z^6M>2q{?!@coAiloX-?qvQ`l-+zNmtZcqdV;P&+~MYxF^3lOT|o4<#6lNDtA4#&mt zjh4bfu1=s4;Ep@jm99`pl}NGSFwt-yU658hSaE8}K{35@Fnb>zv4j=UYd-v)WQIfn zw-%$DNTh3J+Ag*ny?%hW0&~^o2zjJV%)JS<9+H?fL80ByJa!qc*(q;o+S3qc6=Eg` zN02T@GoL)9JXM>H%F_kvS%MEOHa01qL^$QDff$p6`Z{ORGx}a^Zq3M60sfl>AN&-H zm?2XU&aV9G zYy8DjfQ#h=SM`3`hs*IEf5pmS+%E5&~?mOCV5uf-O2m z$-9|cTA8cmiy+b3^6}(Gx({!ocU-bLBBHwYJy8bfSOJY0#4O3?uEt0tW-EZ%_YcmK z-}pnzd|NloID_;V9dW~sCe$K`z#HGmFBagPmM&7v;l=goq6y;#BRE;Je}B$ii-EiJ zmG|K~dav#)N3b!s#=r87A^x-w%VwHk*)?!rPC=zLj|Oxrps9+WV~*bH@W)?KF3H4v zK8K+RC0v!52KmP8Ok{;v-MWXsUojo}A(fO&Y!jDp3f8D|#zXPHFMa$M$S|zh-mRY8dCK!$#npMBOEQM>m(_b_(YWI+ zNr){p=q#aaZhQWoy}jli|CJpFa#PUZk?*!HJYUuE(;=KZf_Ed1u4Sh>n1Tlq9Q@6$ zvrVZY+r^EmtB;ZdI16%Adu+`X6T_~TrxG2YvE$V7D6xfI;rf;g7ML@FkdPw}hxNXP zkd1MFc&xLyi%t?!CwsTEzgJiiS#v+mHnL|+b_P7@j_pGo)vRO^VqY=HLZ}_rj~aM4?(v?>mVuqBcgx}Pt!O@)&&G%PsO0H5w}GF zgKAA}|{4vSqBNw5i@UI1LlNjZ4cJ)DQLiNk-5?UdadHAUiS3{=KTfXZlNXEBJ3P_3p> z+#{VbicMI+$FepAjJH=Xf=|n|mc=&cjsYM}i!@%M7HJxh-W!Yo6A20oV8us;dnf5@ z+UcMQh=V9YXayB8g92!mUFTSk)*8j-@S*-?sn zwiVJ`EP6NQlH6i33CmhkgcBL*B;jM;Xv3iuyKZCm1#Cjwj3f&pHoixM3J|4LQ#CUU z(TYG6L6OTxImEz*!v^0YXTyxu`2mq1^q+IWd^6qqA9>MDfo~|tf>SqbX0}nc)q_*6 z%7I-Pus}Q(dSr>fEc1giavmxHAq9e|Gm=}T1EK7y%bvwAA`N-~6~Chch5G z3pOCQGbzVdfNGKG1&*VkEJDPHA!tWtYQQ0}Eqh61xD?YUJ;LL1GDGQrM8Zfib;Qad zPUMTz)lG6zH^$2Y2!OOiA!3(dR?_tle1w%-Hn(N2A!i!e<^Vl1W(*YMwR9aIMa!te zl{O&|DXFDU%zTEmzko!0-`9Lg8bhMs3Hd_o`iJ>8YIWLW>_G$<+fe`r45VI*nCUYRv1aq3xE_bkA&;NTXO@XfkT&{HrobOEE*a)HE1eUanF&vXS6jck##YX59na?=k-{dz=+>zIwJ z(0jBA#>+Ti!Z0$&XpYAaE7gJ;_UyHaj|H7_t7o9-7&CoF|7m``;z>a;N*|9CXM{D< zBS6n(Y@lfVh7=(4wMXjxbu-k~B@~i)M$7hMF13ys;E3IQ8LZ><{UKwJ&=4y15l_Z) z#{G%xc=VUXny8xSJ77ZZz#Zr}c-Oq-yJ=2PFi2M;jN{p3U80-{<2+-?lrSj;UTsX7 z9WuiU#j{7VP3fr^Pz~|bri1?XE%4H7gOn6$V))|%qBa!~AOScoT*uHuCE_4%FhdYD zG+Xyv5m24nz*`d4RI@z-X*{}J$rMKb5lo+pt*-czGaB$v5fpcuY`(Il&X3w1$tGbA<8RJthd^;b?>n zAJ1Xt_ClqDmhB@B0a+kdK+_eHH3(oQ*d=hM%~4M;*K0uIi`*X_YwD>RM=V2RU{QgJ z5=Q>7DV2z8Q7~dZ4Do=naEmp)C1&Z6TU=qKbCU&ZrYty)9`20C`Hp-f zFJZcZ6o8n(O(v&7D*-UkH$3|hGg%KJdfMFgDo84e9W>c}bYzZ&q~-r4`bp^mZ?E(4 zllfn=jv=wtPCq#+Ar|H~I}!EBhMR+gXBeH$?oO75PuUyG`XH@2Pj;6SjnQ%)`Rw5M zc3O3j*{Dw1i*DzT^pA^43HNcn!#GOFURG_CkUJ?#$dOnV#rvZ*y6pIlr(~JnMnHg7 z&RjJ?m@E?>M${U7V$UDWR>J5&mV`YW>JXNwOZLHUey`TApPf&AcCZR}#Gy|NXCV_FBM7n-G>B?UOb97xW6?RQv*_0yZ+vRH`qwF@ ziQtbOV@O)g_GH@&I;8rV&PSY=x{8PWArGfOcyN7XT&9IK@(**&kiqItwZj6_fPo8K z&n_9#{qvRUCQn@SpVB5k*>MMHBO`#TQ1~z-SuGTpdbjriEus6-)shb)*eplD|8D_5 z*G+noOjf3aT$?rX#CmdYAnlS7B5199KvfsJrb1QP<)C6deh^O#(JpuJ&SX{?qF85g zp!Fbei4cH}2&iI~^b6R%p7Knl;R;tklPj7QC-3`%4sTBn+&55jiFV8b`wQ{tjwv5Z zPmJ$875}Fl0L_FQ#U~0LC({7SG%{CvB>nKr37}`{B>V4EAQA{B6-RdMJkDWJ0R$(w zZ@O}U^`T2=OASp7YCQ)>C{CKr`5UW$vA_i54DkKqSoY#=1!h4T+i@^+JRStuGLBh3 zSqtWIcn*U$;}y#3I4~dq1fs{eGM;Fu8yaBPib}GbZh1D5mXx*Rf^8Isws{yh z%mE^RBRv<%Kj(DBiM~iX=^)>uPkYD{QVp6cW_Ek1Ff}*&4hZ;{G+6bwn5GF?k(rKl zLL3 za$EHem|fTs3Mp`M}zRtVYbzmv4j$uq8NVR`_ z#{d@jI}PYAVNLZYyY0RtFJIMG4aUD}g~M@$-ZkdSvKI>>5J zR{khTJM49+@aO4Gsi`rP&G$0U1&tWbXz`nC(GpU^EmvQ11B}J6@txtgW#&j^7f3I@ z?%l)1(7dnvewtg}oJ0KMJ~a%oaTE96r>R4jo&0naEwAW>cM|P)SoX7Z8S# z57Abyf?%DtGl1FE*=N9c1`zWSd;T^;TXVY5JR=6YZGmZu7Glx(;y4nu>dq-5WYVKm zDp^C@=v-MOujLLdu|G6)1%;052?}*M4YkyGZeN=3J$>2&AOqlS_1ZoUMyq)?@A0Y+J8>YQ@1D@j6d#F5~T)}0+pIfRv zU$z@tAq{$%_iB0fp-=$+@xQL9JQN*0!Ib2x+;cg;>-YGDk%m zc&t|ALLNUq9Y1O7y)FiZ#82m2n7Y)#HwRdR`I|HLA~A-ud?3GoU=7DnHP_zUq1mt; z+wU>40(9p;3z8xVHG$*AzpdH(^X5VAYCermhN;x|5r~j&SfDtrMH=)?Y}g55Cs0Jl zqFxtV9*vkT7a%l1$gWsE9ri68JH5Q7%<=*P%hS>%7?x27lK>f4?<^8%&HmRi^~tO2 zvq0f!C63{IETp>20JVbJ-w-SaH9rC{;ToqczF2=aE+lDwr$3&Bb{@dr7SR`wV~32& zrZ@-CnMbfm!Yj}~9S2WzROJ zD_$X-35*aDe0IYhF~_W6O}iRyO{>z{h;Z}G4?}a+>7&+6O?fK@_ITzpYOOw#4|6fV zil>KxP8#!6j6(u}-2aVK)<>~&B+IMw6#J0}$$Lix!EDg%1NUqSmG|CX<}+G*ShOvw zJiDe$1;D^9)A?{Ll(YY@OmTrEQtWRcnPB?R!xqG$A=WSC>$({@B}kk0@%a$J3@}-} zfO#vm<(C1z|QVg{AiwFoZ)Twj>3dUAIF+XS0&SU2B>&6U? znCHu{=`KD*#_@yrK}d#}2An_=Ix&+>{D{UT;0q=uqZ5M_y4bb z?(OQZb~4}LX&1RZ!WzPPBhu%xdge!>hWghr<@q{5r2|b)+^bl2 zl)5!C#Oa#+l@y^K4C4s0T;K+T%)J;eN1mQ?*InnT>eZ&OK*(X@37T9J)SPlRVT6@$ z4Op#~()fvz=RxXPQ#7UuC6S5Ghx5qd9tiRfkqgxMN`5I zOhath5hu7fN6#1wFE0Ef0pN2O(WXC&Z*j*GlBO8yH`SsHxsg?`q9e!%nn6aC%LPb? z@bySe2ObEMl?uOs08|}GzoG*@K^N5bFlJZ<(eNtXqKF8hJ89@cGG|?fKmxa5CNIHByVQm9 zL`E{;lUE?q%q`;^dRIo(Vq;Qi0f5q9R^6I+c|r3ItjB^D90A#lsEJQgBszwdcO3g|UW+O}hks&#!QJCeUxb7I$92qP?P+?{vi8o#qzw8AKJYkx zFpnjCo#l>=T`aesctq?VybCZ$HEX!vcR)){!PQ7AwP565i5wT@=X?>0EDHr(PCy?knzJ`SuZfF(iW~Hd(osX#+s$e9UuG6iU92C`a%}oN6 zOT{Wq1Wdr`S;@)O!rm(&`NRp%6x3{9E=rP zW2Y7z=277g0HC->Dy0DlWZqqZ&3{GerLCPEtVfx%>0rnP%oT7GT|=~rofyWm=@Xen zVUfrI_nBcZfDNlrtkIt z$kT^4V%M8K(kea0RGYcC}zXZ2;CN6CM5am{&@)%%lJ z@#!{36Kg2%CjpF{FF*;&LE0y=E%plE*Pq4H7>6s;c;`Z#vxsSBATM@SkDMW*AyFj! zgF>20nPA2N@F1X#Vs7}s&{)~`lr+`f7$2!dOdqAL$(U953pt>g^`~tT?6o5?+vVxk z3;2cS6Iq>>+R<`IHw+@=B#oY(x?K%_LKdgk-D_z5?ou}Q>1x^S%hpLCB^zvw;V)O| zF2m&UVOVm^ty#PmdkX7cx$?BuRqE#f}-E!q z>w_!qwf~f6oI9N;m-d=qnpQItlyF4?(#)Tus zie(XvE}+Ap72yVX+k%U&;7(i^p%gH7V=j<`BCL96V$@_M=PBln$(n|n!1qDXxz1C-@7l!fiw#tgolB+v#y&pC++&?(t7%;s`p%0b^*LxZ$VE(G=9w zb00yiAq@mZn-D_#1#_J7)M`CUfxEcLKw4VJ)FMU}^)T{1uW*ag53uNj7HyYUz-L2S z4Fg5d87U9hn$E%7}XyJS(}lV$^4m5MZ3{Xel{U36>pGEntz_lSKZr!c?nEf2eI z3L%)4jr)nFO-w3)N~4;a86MHpJRT$qE29l%M6$555C_;>T{7h9IHBFBuzkl#L%w4C z@%5>`>54?wrW1o>{wSRVmBNP+b4k9YwZ3m4v5LQrcr`S_bV=?){aHIZs{I-Vs;J1z*d;Ze$8702K81%1n8wM^X=9t(pPa<7l z8KVVn$y6LH$$(noIcfVy1KWeETF z)h12dbU*WhM@->pF(hRS08Vs_WTQ=pn)9<~>u-QW!ZL^SLIt3$kd3R!a1_CuIm_>q znHFOG|Dd-j+$Z_fL66w@$ymwH6wdkrPgd>9b$D79($Ysn16J@^QJq7&ctYVi($3pF zkm((0Mfq5dm9=h}8*%|l`jV=8%|uV6m2i}KGFKwkf2c%g*PBl6BB~_!>}=pYAPLWWv?pBcl=+oD!rTH~=7UvsJ2< zbAID}w||HjVq-qR(;q2{ydyGlhfn}6l7mX20ffY3kH%Ps7i1%v%IY|gc>DSuze`^?+zaEd>(&7M~rzJ zhY--k=$f1LS}r;^Pefq_`ijoEV+1LsZ|bFt9y=2Si3HMV^>9#KqB10zR0bAN3M|}r zYBIkw)`tQ$gBv5djt~&-ws%ZXg3hhi_)j7rUpM8rB{Vxak`rH9%pKzBEv@6*@N(>M zS%@B}2OALIjU3nUz>V?IZ*LJ922aMw2>Bh*vR99L$+qwPa#{az-qo2Ru#t~Izs4*@ zcY>u-t8kUzhK8-bA!Va^1$%C1{g&uxka>v8W5?6U8lwQh>)U#mFxqY=toW_iW(6vv zN-K%%>Xl?qprss|pe2Uq5^`6H@GGT@9OhCwdRo^nwSxN3Y{g0y*J3d&hp!}}hcJWa zp)?RE+51i4Nm6$26$xAdi*KQh%|2yxBJ&h3u0LfKYUoR9cEI{>Y|a}P+m6QwMSDHh zNvSP578WF`3Li`TcF4i!Lq;TUTr#2oiR@W_mDIM_;yS#%GM!Wy-75fYf;Gi~`&`f} zFc4vv-UI_A14}nlzn^k<6~_8+xNMZ*1SdkVxyz&mu?a$k-(CLgeArW$kIX5memH4G z+McFG9;9Foio=u%_8RD1SAapj;IYplo2)BoLXbvmEUW5D@{BLo7Xef?)9zb9l2F=2 za1I`uv9>s)-CIu`AwIE5GC7g+ni8Y$SW zet>wc`p5=shrr>{b_&|biXxA8y6SN9chzwwtqq@=8qRGO!kDycLF=`dyT{GAdh@gk zat}J^PB&mO)S_5=c*^AU=6GG56DVSDu{_O$&K_ove9=Cp!xhg!FdgF=i(qlx#SmuI zi$V=kXDqP}SzUzTge)7$L>#Z=HpO*{d;zq`B41@=AG5eWf+;s z8NU3=A-+C8#WJD_}flCnRxRt?B$ejn7r#hpIZZ~Cn z^QwEw+`8XHDrUb=GjCwOnWX;G%b#1_|H2!f=XjUzOW`P6U?q>Ldy zMWi*HZSFz)t+y!_5$Oa+x18RNYr?3 z+5~W^xQ23^ilC3=eNK*JdLNTYk}33^076I$B)+SRo_s@c;&U~*6f}p!K}mj8XBS6x z_BHkCGOw`dJepV!^1p41p4#Z5i1d60CB)E-%KbR?_DU^ z#Tu{+!A{>rW}{<|X9OQYw^Z5>SU{l*S?vnmX(M$nC2;rbn4WBK@I1zbadFqyI zzcUWO1icIyy$I2y+6*FsgTRnFEIgh#3HX4rd$yL+ds`k$ z%zQ|(*&lDe^E9~?dVcu%^p<@VaI(n5KI5J21ik_ldmz^Qkn# zJ8>>+VnL4y3k&fz-|BLLlGgUuZ(~N3mhLgH<0f_nV=-VeyK6CyAS_)=YOrATm0>L6 zK!Kg|`lF$M6fAch*40tKrvMy@xCXle1&gGG83d?-<*__2tN9?&5A<-GAudd>tyBsDHmG}Wb` z7!4j!Zv#VoAvXDuCJs z_WGsbhfGcI)aq|r0@|W|lAP`T8b&4#Q;ZkgbzHCW&o%rAn$c#UVp1{cmx^XsN+UO( zgkWLR#4q7;Qa%%YiP~!MGhd<~Wpz{MwLT-e5+2B6Wm=CtisJZZ(mtt(U(!$#%XF&2OvWU7$u$i`537W71=f}7SExavzCd$Il1-C;-o@>J*D0bD_mW^EOaYK8{ zTfXy~o?z^wf59V!C3k0ZrI#!{8u;kU8{GXvE+iCk)Iv<&AKZppK{IwkP|hrdx|v`M;C7ulf_$U|EdYKQThe{ ztkM)D%=}MO%ig~4^CX4#-aC3aMl=1Au!=sZAJ}_F}4ml8&NDtNmBRj*tqLg-7SEw##+RMl?dw(oaBJ?_J zkgJ^s!+0R2VJ|^BiG2wevG&ilI7sUed+T4gczDQanRd9hMSbw&q^S9%X5rk!!iFNT%16uT+Eu29*`uU&ibw?sndHx zTfucWlrNc>dkdJ-?6#H#D6NG>6N(sW#oi0z za_8H~I3P|sPBmXLbbM-?>{k?A;iv?=#%wn8Y~l!|~TKRd+n zjn$_lhRbjf1kLl*gE^-zgA>Xd+s_lqQCj7qnl+8!-WovKf1hP89KQ|kgC#{*Mv_o9 z7Xvg`{~mNwy{i{4*3R-K z*3QnQqRl^}s7^C#y(j-?l$}pyG3)+m5KtYA2F6q~#Y$)=d12TgNg1q|kvF}=Lrmgf z9t5Ht9Mo`69^?Qk;$_D=iLnunKpBL^7^i0gHY~yVR<@@RE34Bxmy|@4hpLV`Q*;Oy z|J!iEGRRd;6%2e3UHwH2YtDZgA3l!3GY*s}MvHNvBnfMC6+02V#vp+9O@qr{AvL6e zkaNIXZ=6HCR^y0CtP!=!2(*qxjRXI#i#icghB;gPRqo6H4bB>GPX-s81w-xrs@~Py zVN`Orz#ZlQG~ruuhV9NBsNv4H0oApdIpVXp@?2;Ts>P1f{u|qoIVO|lEpmcRYz4LP zn@_ML{~2RW7P3WmVcJ5W5dD}!vk8UrCMa|s_mQ(p;D}2d$sd@UMA;0vQw@XT+y%db zf($t8uK=jZ8$5l12uE0Lyr(SDCfsT~b$EMY&-pzw#UL57%NWU8)9;Uf6AVW$JxJr&SdRMJrK>y?8W4ht(swMqCSW5mi9di z6U>f*?}gYD@Oi}!Yquy9&Sw8G8rwC55}?W9404_2*!x*(PW|Uyg@+_y3DwP;r0&8H z4?sW*?2BY|fncdE#TU%zb>IbH7&k-D#_F6Zc%Npiv4I@h$1zKE3v>~iweMh#$y@1l zw;$~YlO)DZ5^&N9NrZzZ!D+2A5>6GR9m+EM5s)dzmXBg=%|&Eoqwy81P1!Ro(^bk8 zU;rvM9~4$_`!AeJ)QdrY$Ki!M8(fA#YK{{m-EbpiWBNp@r&KJhITb@(QY9Zuy`+Wr z7T4un)iMR&V0__v(fE?ErSEmq;|9CKfAq~@7Bv`2O^Hx0onPBl%ku0oR&yFU2pI-4 zBp_pr5Ek`MN$Mm=LF%w-EJ#Wm5k**I42b0aUK7X!ayuL@H{R&bndQp=Cpb;!7Y_Ii ztEnZp1;n}eL7+MX421y?kG3i%D{Ep(Oj+F|6fH%Bs9y-@uqZ|z@w*Yz`f<4>I->n5 zrpDNH_?#AJh7=R$=xkcvizw<xQrC1g%_MDUT&;jtq#iCBaz{^ zc4tR2?y`MtKxZBaf*VqrWMFRR7c)*w8Xd*8ppH|HBG=~9#p*$^G#0j!>c;hhGSB#*f&SwY8tC;$r^c$* zxHgrNoS?~W&>KRgi&_1KUYst*GmWgIvv)8G-6Y_wVHCs@=x3Y4{9c{DAd*Db;c1Fg z6!r2ZVWtq3*T3H*>n~0;<_q1}4kqagEf7#~vZD&Iv{huN|MWI=02KicdH5DM2d$#w`%-M$|=e&h0A$r#=V&^!u$dQFP#l&j|?e zX=(`vNQ?J}hWN_ZZ&Ds{P=qgBxJBL&sDd37=w-c4~=6y>ejAk_;V zpgP)Fn|f0)Zg$2d?M(#7Gh#9~0qJDMl1c5of z!9h4iMNeciM3e&}(@^J6*3C9rvt?cHLKwu*kXDOJ2O^8l3cegh3jiVh>qOVK{z**B)i?J$)`FY*MFB6*C+9T9{{ zMtWFWF=B=2OYJWIZwvJ5pA3ok1gJW@y(0zJdNzG}b$N#;rin|%k(3FT!i!7AW5|1U znMq(S6^|OxFC=NxnJNC5;;!Ew#DDM@j=BQlSr3 zka8JC>V1nmquxadRMo#7%W`ol;9JcYK%Cb6aD-~FeJZ`_gC^&7K_^FX z7c3l0B=tg^4Ufh2#jp3@U&WZqo)2O9lRFB#b^X81oD5 z-S5yma(3zlX6<*n9AZ*+QVZ=O_2X>nb-#naN`3dPIk7h=`Xv;Eki)J>3QgL_6SOtbiqYlC z<%{ixA0JY6*g(ixcF1;@a=Wgy3aa9cDMV)z`Mho)OBG?p2kopapddk7j{QP@jC`>+ zE$c+3MDRXQ)W1x7Aw{9SK))%{CO1~Uufk#?Lx3|v5GyPcY?@+am8+nDR`NKhQex$| zEA3NzUj2UCbm-<;-7qu8kaA7nr9OIw(KM+z(GA3bBeObBi^p^to|H~ zg;ubk6+Bn$dd_wYTS3>Gwzf}yDKIoBU=Fp=IrPUHajn_TmZXb8Drj0TX`tTj8ug(BEB zlwk(V;{ULuS@m~`q~<(C>M^AW`Qm0JEK<)d0cFr-N=E1&w+CN)gsq4-Nw3`_R^x1{ z&ZM3a;HmgKY5nRPB(#>~#{^kaCq`%I8g!NhpRtnfOjqZ3@(W)r3TK#8TV%Zfvei2L zKlT1Z5(xO@il6~lxB8%M^n)h0J)vGQFKs`1Q( z^yQMW&Dm|{p|mQts2@+64igrFQ#WDK#>gcrY^6w5@GV>Z9Q_WWD5V*EYcYe4IWc=B zFxQpgNl=YJBM*;t&&Gd&!;2PP)C_amJR`!uP|w(TnYi0JFb2AJl9e*&O?8D(j;4$R zn&HAMK8UKmjp;6_0O3|m0xISTe0sFTH?cTFqKuTdUUeGCgWFg(2|m%Y$pOh-CNot( z$dI>BkdKjrQ=Te@M&NxzLVDId_|CDn?)`bPyKa?hExj$vCY$_|f|PfD_Ii7)4#5q8 z@S>dlf`{K;?xDE$W7&Qn{b&zy1-M@A!VzD*{)YCZ%NBKZmhHzJjDoYUm}w$Z z*f#Nb9jRhAf+IoUD@;hY(TTfqa@R|DjA5+V2a`#zgOyLRPo%tK$47x5NUU&g&YJZLGQQE5$W7b#T_XlQ!-_$m@4?4m+(}%IAZ3O&u9bV zMXU)|yFCl{uyYpv*>lHsv~Fj!u6^dk=5R1c#;rhC*0nzn{b2h#K4XVN&r}sP)8+s- zgJx4a-+27wB3iyM1iX&I{CQR&97IivpA+bY>^aLhKQ6<%54Kv}`pcru!rU~d#YEFU!{&m8?6WEJO zqWlePanYJ7qf*t>wk#%+ zQW7h%wwoTY$NK?X!YGbsr=X~GPZcD7)&9X5P)G?2;BgtoS!-|ndInVd<%PVV39~Sq zBWdsd8m?;(y+d~l>`5p8>d$`im!?GQ`u2_aK8k$n042UL;`1Z#D61i2B?Ta2Olg%B z%e4}YxTK+t!L>0DA zAK0h*jlyTA!rR-D!k>A>!tCuUPf!?AXx8t8Zy^(RC!I=U5;6eJX3htPCj6S6IHVZ$ z`dt@IWUM;;&$b^qxX+5v!u2-+S00oQ%wWNscb$;%zTpKxKvsef5OYKhNEomfvs)$CK;oqf;^-D*LPox!LEjj|$H6m!`~|xjRox+YM^BG5rT_Jff8YT1^j_>e6)P6B9o1Za0zAk4br!wqUkM zAe`^E`^B7*OW5Fq2(oVQ)uqElu>?M6p{UvL?ZszMkA}0`ufnvP^b0h=&r@7=;QweR znyH~#>!~B`^ST}f-bTvhm&A@GS!3xhNx1Za$K9r_v?55&Mk79P7k#7fjeHSt`O%5( z{B?VX8jYq7V`(-uFIJnEEK=m~eu!$F+Gqgu*>GKC4MJ5@pmJS{%rfs2nmmyPmFDYE zM#E=-H_m}vXh(+qgTwivIq|X-Gv#(pg8E&?hpL%q@=j)|-HCN!G#fj(cncA5iO2JM z+v0TOW>%<;j>G^MSD4K|6fr?VDv&TjQKfXwPIg zKO|;9XOblJWV4EaW7>tjAeryiu9bknDKSVgOxFbHZNP2Kh17h2Yfb_LM$v|oB_TJh zt4|NAfVmRil^w};#5O#!IicBT=0Wf(M);2#17EM|g$_-MTi-d^41$j$*J1wf@HE+V zu9-hPI;~kee8AZq#r4V2UiU#dVKqGlW9%xIymb*#A@u{wpTmbX+Tx`dHD*&b%@&g+ zcQmJYr2J}c|5cFo@4Zz{o(-`OjRY?WBCA`{SP+zo=H!9ds+l)KZ@7gY8%kx+>`0*$ zlv#VpAi{&OXcbq0i<6%rckYFuMY3tBV4BMuijJ)e*>d7!$FVtC6@8L#rv0NBNXtt` z3*Gd3G{uI)2wy}+X_2}ihO+_L5c>lq#vjc>A|Np1KY25jY2)8Xl2D1Ijrt&Nw06*9 zh_QFuVhA!j2L+w@V*YHr>;{@yWFw$FjTFWuxiMN{hnp>tmza_lBJdM3S=^;k>>_Wu z16_VYq(ZQ{rj!=r<$P|`rz3g$18F=Hc0py5zY}>%4>gU_SIub--ld!v#`nA->I>pg z;vG3@im&fp208H(Gf4v6P2X(2EkjDWS1HO1IlRbWEzPD#l$c0I_jK+DMw(4+q2Gp& zK^qQXrGc9&C2A+FF9bC6eo9cdRE)vfI!(V8@iV-%E9kokzzGUJG_?i(5tRNVLbFIm zr};jY--)s!^)6nhD!&AjnsnP}!8T|BO}vTd zClox_-Wi+c%vN_4xm&H^i#5{62=r-kV3YGqp!q$c_;3vje(JX|oU*_LSYTG$kypc{Ee=!9+N~6TAV7Py56=brZzT6o?%E6j z!O0_dK#mgtiFFaD3GH*l5mtaE%1xJn=)66^?(&yPr}$n(9wfR?Dk|IJhVZi#`#4nt znXb=_06@Q*70ySq`qAm?LS3Rcbl^0+Ty9tnA;dT?a%S>~1};2koIq>n@xx6a@h&2G#7b!=h)E{Fyut7};fbT>|*x_KwbNJ~EUMHS$ zgHyX(J2l>;`2h^gS5xIrv&~sneSV5rKdv_xkA$zOeJs52c(U7zUc3TShi^x%+%|pd zO7^mST089@y+w?M`ww?!N+1VU|NH-_uD5snV#Y$Qjm5@|8>csIoSB^(R2%0u_Sda1 zH*TmmN-tn$4tnWfcg(eSzm0%Kkn0(`qFCPQgENW+?;lL}wfBe8J;_$t+{Vi9_zF<# zPv9gvw$iRb%eb~dLbBSpU*Mi<6 zIqvOy@0@(w{(8E{i3VlS=3Mmr{pl&?F12`Q3-kF{Xws|MVeiHx=;ZypPia&X@m+ceW2khjl z9s8aBq4-v`kySu@QMaOrWzs3)S0KOLBfFAn0FmpLmC`wN0cfm@Jau`S`MRp*t_J&{*F@XjB%+; zyI2qj!-=mmbU)-j_hKkn?r!JwDS7vt+&BVj0Uu0utMa72oHuw{d(}_nMc+e6WgXn7 zTteU>zVM*7bFVR_`?~hA8C+~rGA*NorRi#|mf27J4+DcJc(S3zB$yHyX*YXKEpk1& zQv3iM5bcFIUa=Rf2Z*Sl1!iC$n&AO%6$17-sc9}rrsN(>scl)-9{GB5T$R@;oy|5H zKPhf}ZNu?SPiOzWeeb*RnV~vp0QVV(w2{Z=-nzQ=KvWqYB0r-m0MXw0bkwSmMJfU2 zX8ZVe@>tP)3z2O`+O+|v zVnc5L+gUWY%sv)DO*~2&*G2V-L5de0VNePAW3I&^>1`bB3Z?yd}$$ z1L)Zo1<)&m70o^RbrDFb?=9%YIb8JZ5GQ?J5&i$sur7OaG{_UHEcb=F7BkXBB+eyM z*LpsHe}I&0xJ%wNm0pECHz_Z}(d2ad$B)uQ)T7+X*pr^0^e~m*W27`gv*O+u{|EEM zv16eu&BY1A)UJoh`DXu%f)?_oI9$JvMS>k7Q1D+YPoYm3kSJirUc%?9>VJ+>!B<5* z6Gb8qQ;TnspMg1rpGhcod|URbxzviUJ=qwkQoO^klz6)fEAU7PB?7P`*~y(?yN3Xc zKzEn!L2YTgG?ZzXVOk0pQg{?5`a*`AR;aM8<@D4(!%x^W{Df&_Fdi705&#_(=CwSi zV{Ej8c+5&CR=WT=FhLjhu_V_)BUrd_34aHd;6kR?mydx^7`I@o{ZJ8Gu+!d$U~7lH zPrdA0$Vi(a22cO+n5dZPEa~j))lV{{(OUgfA3UxdU0iqIE@%K_Wp(xXbIauxOr zs7UfGuXiUm*{1f*e=fWq%OTcH_5C@%XGcuzM})3^k6Zchdx;vjH1U`b)q5b3J@HWn z3!xcRM2Y%LQOvvgZMkL{Up<)HF5L|)>>Pgcp1oto?oAel{3?Fl_J}9-HPf+!8-s(N ztqqLU_xGx2O*BVN87iQQ?TPJOAG4-g6o{c|T*C6+s8xqT~+Ztni7|z(= zEoUM?>6g6-W{P_DO4kw%E0jNSv2Q^MFNuYrbxZ_t9i7Saue6UF@CPW zff}bC(h&^gm##iY@z<^KIKrJx5B~|&ZrPMS(~D`A=z{JKj?X=W8bDJLDfBL;m^kklv=vUX^GH4&phIzSM_zkPsCv3t#)UO#i z32YC&vxwZyYtkxoG~Zt9hapDn=EYZtJ)EE1hn|L!C!g`K`q`3Jo*79VefSxivjHh* z_i=&`fb3^zV#k&y(#!qSJf5=tV4OK_>3Rn%YT75vT5Ui3=`1lf=epycpq||h9|wP& zqeHDU2Xth#vdir4wG|=P_BTJ9wYPj6Jw;q|(Mp6Cx}^FJ!R!Nk4(K~SF;?x~{T)xX zq^yMug@emy=Vuc+?P_-ftkYu&4|1K`%M734YVUk&m_$ZUC;*UKN6_RP_h=o&7imzr zZKK>th-%?x{*6=7z>WfihY}(g?X=&467UXbQjv$2A>lyic>9IFfhH8rbRY>4vZf%= zhIb0?zWy%WsX^rn9&A?vvv(?DwEi>XV4E@fM!3em7cCyHABM~RzF+hY%yd&_<2t-u zDxQMsR&&dq!+n!KJO50M_mUpzKBK^PbO@KTSV%}%3=w4SxkdukwYdE$dL4B|z~x!>Z4^mP{7#;A{l3kkRU@Cg6~K7k+_|tp6@=F z!v$e=>j;`-O?Er?+6(eKP1s~>{B{`9MhSD@YKJ>|&u1o8*a8Y(o@d@mMd4l~;^rD0WR$XE6fg7SrViNQYMj z`&YijnciD&9rbP+_2Zk~6{Gch^Qy@=IMw}T9UqKl*M8E!DL&|5F>;&x-LMeA9XvgG>`y$YGWXMDsL*xrm-1%HBv5v?1XmeN+kZko0~?( z1K8wBdj|b#nqla!SyQwe7p3oOi(Zq8zG_X;o+{H?>GIm5uS!LCuPNFe7qzRC=EIf| z=CD-(HntEZufU zu&n+CovLAA=n?b-)Yi&Vx%-eSSY6oOy4KTK2Dp-$&t|tm<<)=4%Y1)+Amv8KZce6G;*X(eVME31sT3!VBL{*|9dr+fu`)kP5yxo zzl^r7+4uZNJgF{rXTaCLD*VPrloZt)Wa)6by($GKx zVHA}GI0P{pfUMu+VmIh;4>k*T`nb@VT(qQ6;r*Bi_ zQ$^;F6*lEV2Qe;IJr`k*%=R`ybJ(He}inx#0e8kHjEwIt5vBW6M|#gIT*bf(cEV=3iU6trgPvYoa8eb}uznuMAurMY zEnKDcjbAV|rhZY~m4kQSiH`bhns*iLk%v>-ml~G)@c-~#@D#RRX;Dh(q@?PmxMb8P z$bkjnh;*fK%F)`Sszu=mQcpDs6t=m~s3<8zc!#gb>OFavP$q8k_LfJM%)S&oUiBE;rG=hWg{>Ry1eT&U8Bu zMQQMlN1YitBheL>CD1K|&^wMekKgsLD@n*~BNCyJ?zVmGtHbr?vyr%OML4=sI%YIzV%9<;lCp#T{GHn=#OO(uV1r%TV?TAoU8HL=6YH6`XHX8Fs2i^EsS_z{s-RE zG_Z^uERSi1UpfMsgZ-j6XcP=SqzjHZtL3R@Lh%f~|KN0I26;$j!t}QlL3;Ki9 z`LezuvQ&Wml@hv7E*lQa%I;@}PdJ@WSG(!+m|oFVYd()!*&yG4GUtoXG2X-6_R#d-w0k+3jL`N{i72 z9*{3>aWT>bsh1KP+PhgL&Ogh6c%I)#dU9fZq%l(TO)Qp7<7iN&itTpV&t?0-P1b%s z+uNSP5igxwO8!^^zXgy8^3kmj-P+~xrgpJFn`gZ`*!62_Um8&lN~?g?Na&j zkBwgQ8gI}2@$bSSDE*Y&BN_{fdd|BG+`%lmeG`GKc?aKrmI zS@hcaEvNk5v$lJC;;oN=_pwjE!rOP;_G4fEi)Y>9?RVQ>Tm0a?zr^jK`xq7f9U7I4 zTx@9DN}c(Qd*3%gZD|cPIVGAN19oUc9}nH@-=D!gl|y>_$7B5w$be6J9}e7Jf9ps1 z!PiHBG8FgTD@yYF#@}3Yh}L_D6z0`!YLFz(ax&?c9k}L>2gn#?qd(WXeEX62Jng}n zfX9G+Jsq_=rjZN@^YBbWg5&*>rw2(IXZNOu%7FJzp}q4n;W7T8QVsF2nB)(C= zFc|MSXiY$G2U*`Ig%V3B|?ZCm^O!!lo0_ zuop**GtrB-#1o{mUAy{w;o{o_m$1Y~g69`)SQY?Lf0+TVjA&nr?93L4$Ka~M?^Q4= ztGMg?UD7{lwgZ_yJDh ziNB*D&X0I$5S5nLzd{3rsYVAW6W&#Qj@6I~KyUr%%qUZ;LqBofHn{kN+;fRTM=)e% zH`G+wv5yCb#^li zVJM;Uwg1Q{W{#T#^*!U(0hX6RdN!iWR#`b}esXlwVtr}i7vkSwG;b}y7W=2xe_L9Z z1tvquL(*Qs=O||WG7ra=I7y9-aDLke*og>^U1PsA(H_~`6I2AP1cBN+VscG!Jb^M~ z9VU8XOi;~hN9A6fug4QJ)j(Uc+=CFJb5VP-_t>I%f2;7_)CgqsdILEHfsX=I={=zb z5>8!`Y$z7nih-A`y|Dh+%*b?aU1)S%;$p#0FHK0=rydK_dAtHEnbf5i0*R33dty?- z9n1H@4*A~(A#jBV{+J14Q2^8$T&6|5FtN^P?D>crT1D#IS1obViLE0C??c`H$IqT} z;=gO|I&!G~@YGl|@}~M#y>5U%tC4_GPF&TN*$#uXmTjqnE|7=(dfX^&^}=we?lA}VD|y&3o(4F* zcbFH{Ksyblnb3?SEhLQpntWL+09_ckd!fT@?>@fLfaC{A+S_h;@ggk69h8H+i#+aB z5g!jhkb+Hp1HH=q$rZo@kc^bR0kbr{XAICW@idfA8Xr79*wI_q=qMY&FDkmw`7m+r9P#1)77e9t7{ zoA<>e0MxCS1Sr(0tp2U3YJIvD(Zcj2Oec%wVmUye35v~wAdwRr3?aO8Iz%rcxNOL4 zax9ENMTVkwEmKk}5h7~yVN6y3G>IC~!8~8F61-X{rN52Ei70KqAW2HV<7l*CePjk@ zYAvOJq1j#}U|k)tD4fGvS);%Du~e;a@Ez`J9HQ#sU_xLxT5sC}`b+v&Mtv5o=x~s=dK{oCA?nPHeUxF z4H1I`>rG~m+oe)Y{de}AMp&yABT?`cmzj2{v<-ZDs7y)cJOaAxtf=!Q@B0z|-;9%c zd-b*MtQ*$ub@mso+O|>yog}O5dOeGl69;{DUJf z{~S;_#bxM_T^eJ@aHo445873Xwv;$TtxG^MM+!H<#Xbh8g|HieP_)B1m+%`apE|`^ z)Yb!{;;an!8KEzlF#HAwy-wzG*t@_BB*cP(5Myq)1tB*IA%z2_p!HAVUqSMP7Bm1D z&gLEA5@iUI$h0rLvk&jP$*oHEA|lI?k>c_+v!(&U-Cz{+ zQI{v-Jgmo2Z>6|WvK)fEq>=*?;v;QAP8XO!^zagsJa1qbeHv8K$(%Qolhd<$witsA z(A&t*r}!DH4;SVUO*Jp`3Aha}1^BK%M{xbv9x|*hi3+1&-T*y2>;(+STumJ`=MWg$ zEqmJLHQ)-ly#NCLKbT09spt|-1Dl|klTyPX$=sTL%Jv3}AfdP^c`nqAVnnFOYPe0;td}80HUW?r@e@Kjp7cXK!1!1s&#s{Vd0k z_=}IZlq2@Db!C1Q0PzPw2sPDj^XvgCGdTRRL|azPI!?kmx%IYL14Sa1FjAp>qJ0b% zfNhVuSmYRW4NP63E;%gKg@>5Cx%y>Z=Gnh+@~Zu_H84f>{TGH49N_pC27tU6ag;?_ z-#!KMb7}z;C&@fRbfu-~9j>7L9GFC;ecC%LL>(4Phg)q4cmjY85})9h#ER~Ibw;3= z4yw;7vqv=1zmfkNtWL59RYa!{gS?io-Xa8Ara zHB%yQUC-$h!CzpUERVy-yox1!<9CFsDUjMpRbj(K4GA)PVsef!EjeIb!2|aO4 zHOdRX=(Y};s?JMOj$$XOAp98Oh<}&jxQQ7qGav0C`rSKbspv!b#8nprDKU_E@wXgc zBE|>8AQWU~MuJNRW@=W2G$u(Z|L=xAA7T$z9w6+#8Y=~&DhC(0e*H%D7_)hZ z^mM`~VPEnFy)?!_v|wQnyJruw#YVsr-IU;GvclW!dgxP-CZ zo@OI6mpPohm04Cx9bVaR>wfhpj2MH<+`i!;z-$HiyXNDfZPd_3yA3;)aG`dlUsNl} zs2Mj>e4j>&@6$;1pH+6*xFVUN;_#UiTZqvY1rBokr5Pd7y5VOiM)EL`HcNW~CfS1* zagZuob!0I;tNyZxG;2%&O#RLjXnz2;?Ovtzm55&0LhZ^FmpEp=zkbmvNG`@|Wp(=C z%IxhcPY-VMS+PmBVACMh>%l1_f6QNbUK?=K=PD22YSN7E~$Eg%=Q zI-BWNItS+S3&CHUB3sJ5u3+K9S$~dq`>d#C0%O*m9(7M11iS(U^q57qRV;&`F;rlQ z9!=GEM_!QHCaXV?cR#^9T50^V-oYX%$B|fJePJX`1$Yt90?aXz7zdGLqnY1OI1Zy6 z%lU1(AsK?LB&`(n?_hW8cIw1FkKr(!FUosROvHH{(8HrwEXSF`=@6LY5NS6;XNC(I zr3{oHDvjp?0LEIt;3#2N9RrU()Wi$!G9x^#*mQc25kAbsPj$kIq)JemIXthFW z&k!CG6LKGdP#Yv;|0fsTE-D(tm<I0{Rle5uxc{SfQF=g^XY{2hSDcSd1aO(GbOPHDmF1H8&)@EU0j)@QP$Y zP@eb9ByL(M_8<45fV0DpDMKFZ7MrER0`%Dw%PwoqK!!+4dZT(GXEq1zVN75(hn3(A zJi39&U|83l7~SO~nhpzs@J4J3Q)uu7(`u;qYUWdTdBAUckMaMtoUg4XDO!&`iQ`|` z<2f>jgQwG@n?#?(0BtkcF_l_*7=hm_r<=T`0M`Kg^hRSW30-}_0(=rd(N){=? zt)wLyQ`TGZEFgkfa8l{(aa?=#*VtJ#Dh?s+T_cn53_#f&N!;gD#!{K3g8Z=V!-=S; zWj2%g>zN_VB8)Zk10xMSY@q_z4u-W1_A>$@k65RhI->RJ6uB`C+1B##w)5rhi|=BZkm9AL&LsybZXGmFN+ z0QF-|3pLS3hNgO>X`}$Jf%d1_kdi9HtAdo~Js(n)JjWherU+oYORY}I${;*c9ROzh z=R+_YQhIFa^{Z!s!9?((AhMg1{Tcg5IglFZKS`cwI*)66@@gXM>5i_hpal#icYVXd z5Kp&CZ^!@FOhI@lJDPFdI_mM0plAx>h6({b{TE@@O*!N3r5Ud%2X1BpuL}j z)qTteN=sWK^?iMTBMVd33P7T+938AwfWt9WusK%f;t_R9)K5DM$HbXc&M-@|PvSx* zkiTFT2B>V$VrE%?oHIC)awuq#&7JNh+=yYvJfIhBt3Mzve1e)4qoGL^KSGMwUH zoScP_3*>bulM7*p=smRGBfD2vhs7LVkfv<-4`R-urq3~d zMg=lLU%HOyCDRS;)(CA76U~&g+O^q$K3!}aPrysXr}%Kp-Uv3-hRs_z#Mvi z1wdg-Pyid{5;ptEF5S1NZu%!0$T2u*Y)!42D&Oa$Y77^E9do<8F|KIIq6i%d0hdR*8eKMkj--E?spStMiDEd`+2Q{wnfk z8M~;5M;4145$V3Mg+~{$XB6%6FY5*=qV|?=LXaANL1pPYoX6*OFytzNZa&Svt=UMXxYbX@!W0R!WH6(VUmwXkGoDSqHyOI&fxj$mkA(s3mL+_&i7v zTw#3D0QCUQSg&DDEdeN+YL4A4-aX4L7S6a2fGAJGIwCDon#cE{J##l~R9lWKtN)Xb z0A5sJL2?TM7b;uyA-a&-a9M?wMb*kZCL9N62bmp0A&S%r7!4b7`B_KN9=NMTk1 z3}MNs)$uBkw~H(Vj1ZPQR9uICfdzG&K@t$~ngZDB^|D{w9cJ^jSYenZ0oLa z>$9tvgzSYx%Ed^ViA_@B zH|tVgp(IyIVR8^sh*IbZZj$^9$Uz(r#v)LTKo3Pnke^eEH=_lUkLC(+7Hy4R9$SIo z9ie7+6>@}6MZo~7h-t%&`^DXv^bezJEmLJEE;5FjHp=)xWp z5Y41Bre;+tY)Gih%s3;8l<5O@Ym()pTxlu2NAW=k?cJDU{q~-GPyNjq+^u>zaSz|z{i7zv~{$5eYz7}e(4(ESJkWsD{SOuClWRogTM|tq}|}; ztZR5fv^qgm^d8=?;C);vp=___0v#O)EfTUvbrqX(xKS!m%$=wIkNO_d(N}`D7YlN9AR_t4#X+%k?Nvs@jo;d7&bQD|8<_h2NGL)Ezly zc;aauYL)(TizCi>A5P<9Pc=egSVbv8ca!jTbU{YxqS{4_H9r8Q(S%NDyu+h1QetMz zhzTEbd3fdN{MP+MVYRvkF9)9oH!!S;K?<~+cV}X=Hj(}o{ zICh(hFnvhO<}`B^NS>RqFC9A5KgrpgZh{0iZf|| z9`F;4?a}E!3&3m(h4tm2@w$2daW=!-5%!+$2%s5P?O5bZg4`3Q(STS(~v-A`DJkZ96@<@pV zASiTKZ11Ec9w+6x}11o&clkB(PEFa9|0rz&C&?KE`07wT6XYr5Sm_kEi`%LC)W9 zS-2xf2lP#krQ&$&Tz5*ncx%l^L+d$?qGMiriz}IF^?#VE-daq8{#sWW@*wN4K$6xw zQVB%P18h5JZ{N&RP)ZCtUP%&Yu7_pv`Q}h@fQ(DGe$v5?e4=+VHAf25GaNPa^gvo+ zQEto5Y>jBQ#1!NVXcr09b5b;j85fAE&rCJOw#=$oYHi=>Nv<%(`Q{UB=5ypST@|Cw z!Jqgj{lm(ke;*4VsF-?q zaP4W;!7(d$^p8$SBXkSMIR+8A_&1P{nln7&$WNr1t$>PizZNg9$;Z-AO$A3M79rS4n@K>+;^=0+%HZ zD4piK;^F#EXfPGQht}oG-6rC}f}Llp7gBueJTVfv5F%_&GHk=fj?A4VT`nneS3W#d zDkYM`ft>B^jSme^(+EWEfVtSK9W<$}sA?`Yxm?MHG?8puNm6VRH9PvNw zA-0W;$+yfA_o7z^?UvUygYIYue#IP9*G3f7v!{T?L&scbFLR+JvS%qLf3enzhxCOo z1drI`l{!o5n)DuRN)DV?weY!C6pU96`yB{QLg^I)0+20i29V6Yy1b0=Hmj{Dt!L88 z@XN%Qzs@Sdf4IBluEgs=ehieP*}l1}bsiv)`u5<|=Cqre&HM>Jy9NaRUc?cpB5*e$ z36uq!J|OLfC-AS|Y#yGPn!p;HgRJnmQ58yCbPk$R@z`7GN^|>FrZ6${Xz%E|5SPrB zbBafesxv%%s6Glt$XaH16Z+Qxqv?epgHyZkBt(GMknv~Ol?fM0n1LX=Qb65mG*}_O zc%NH4X6=SGH8R1@hZH|rDG>z2h>)@ktgO1s+yAjxXmvWhJBI2oZ~B)E)0lLW=I)tT z!#IS=w>EqEQKX8AFkPoM(C>8k)CTZ_!CiW&Zzv?sQ^IbG!PiRwVUc*?WYz;&j$(oa z0%mFGQ~(BNpkP=94cYu4g=3)%oZkHAt)vK(a4FKIOqU+Qf`{y(nG5q{;7&I}eP|ZU zL^n9VMZe_7eKRp=*kYPiE@VH;U@to;6jnjO8T1IFz?$ynL?$DXBI%j)5c(Sf#Gnr_ z87~pQa9%<0uT^wio}Bed#dmtc+G_E|Z%jD65_B}&vR#D2f%88|0hEn*iN>!h<1)t-SBGKKNu|VX( zHM(p!19oau+l^PJzo4g}UrDZ+J{!tO#C*JL50Rckd3d5`sf$rsTiNc>QFXxVo>zC} zqs@90rV(N@Y=wdkIA{2jmvX8VH5|p#z>Zn{+bo9R3AV5r8dteCz;tt}$AQeKNhrB6 z+@i)Pmz&Ki9%JY@&h_0qdGiBpAJY|Kd7#-sAP+)8dJH!s4#Tk9P=B?E!yZ8qB-m$| z`^ggJg2n~sb4qORk@8VCxP&bTNlm1BPE!K()pWDP80&O%TI$@U1aLsgyXLf;9)L^R znoaZUL;s=SmVkJ}OC5e-)c~IWyyZZ1ng9bS(@^k6KN#WDkR1K%9*VB8DK)A>>y5o& z-KdqVl6}Sa~{mlI=jOEK=5dI7`hj?UcRG$;e>ymrkA()N|A> zWm^OAss`Z9Oti@Oocb|r_z~vQ4%P0C&98-yh6Q6`XVVX{@qH8L&83U;+Gj@gfB?V&aQQh5aLQ0?T;EYKNG@#cE`h%OGGcB35OeqV` zu;q;4Tn@gEA{UkVk05u7;bYFj5$|$umnVj|Mf}F|secT=egLC_=3vn6!L-;M-L#`G zrQvB>qdCcN2vZ5Mn}xwmkRB@H=WYEYjaU2ZFwbwKGlDXtbLX|)&A0I=%I|;{X6l=J zo~+)XE=U>+gbcRd!P+Lya+sSvO&!09HJpO`m`bR1SA4_B1cD&S!5;n7Fynb6Six)p z#74H?ZN(Fw`RH;OTz=MG4h5F<7u)gi862d$5rL?C5OtQsAJM&wV^qVZ)l0HV*6uh$ zVlYWzw2A)o?N5bWm`H*C#8=frqtomWM%&=siPzw*?b)9HxgVRi%x^9Wi<5=CN{;(~OWlkvck(-`E8k=GZ8Y z!bP)I0o!s}35!>AXBOp=>ht1G)~P1Av^k9!vG4daDm(gS%Q0^v-!DMnBX(Y)-(#-# za}XhID((1*f3V9+gl}dWbxQ;IC|KVj9T+p7$Nlj=)7CRD*6IKzDdk-0)MmPivD3jC z(vzt)0xlz`JWMjc-`%XIIQA{ABHt6M#$^Y@p)hoj$4rpkOmhmUgj7PR$hy$|%^=A@ z6CfDY&^q0Kpm3x_XjHixChRVMULHOZwx@3vBzh9LRB4|Z{g!%HV_hG~O@T!GkW19aB{HjYpR)9KsaVF~?}^PO(Ns5! z^2xOmW6XzFr(#!9Y|HU>o3J9Bu;A7j0yAN$F_lS1tZXT(6Bk^kVBuRT(sD4%b=3NZQ(MB^8`J%1PbOD+q2^#=)>$#*l){ZX?dV(AXw8<`x4VsLC6+5?oi2RXa_F4 zxy(uz9La#|hJt@75#wZ*61uT>`)QFk_E2b$Qp2&s*^fNSG*1gdxWFh9H*^VNERj?} zq&je*O{#;2Iw#0(o=D^B+8I8{+Gnn9F3=ZlknuFgd1o4Q93rEQ;f!X(`lfOw%sLNE zsTr(wv-xFAd4WUn+j2|J)VPwp$0Y! zj6uL=P8uedXvAP2b{ni`y7`{UOE4hezF3w8Y;#cX)%dYYSjnC&mPI+6whBu#--gFLN2Z~}aS-I*5+-gq2{ zWz6L~6>(oGQ>n;pg=fuPFA>Ax4WfPLM9z_%7Ky-UaG~AM?R1QSM8ly)2Vqx2It!sP zC8BvP5}M;eFLaV1vl-$6+;VbDRZvxeFTBwZ6)zx^>ry&dD0c3N!=TkW?Z5_(V1+*@ zbx|8jJqcYVt5(WnqB0he=$(o3nd$gf?E^rnE5VC_3+#4Xa2Oe_71b!vknw{85h~^k zVT=Haca8flZ|@yg$v9`7RxozdaU!7p7~Y-q`zQv|KzTYxe8?q>8Ekx9KbdyZ=?bAl zm`$kQO7sC3J7Fho&asSl$jX1q0uLTAD$u`Z)#d$4_vE{RaepdPrdW1zWQJ1l9A+-qxJN|z>B zK|WV@*r48k!^k1O^F z0Q~Ipao@AgsPYZ3R#M}*+$ay&9Y2pewmPh#g2L@M5@lH#&s% zC&``Q=@i2kB6t+!!4_aZCD_PbKB1+C46bdF5Q`6xH6ZEfRxH0VAdnIs(K$)u*AHi? zFOD=Xr0E6-Lleb?1aW_9(K+n=VG)%h#2<1g4C5G8jupLwL_|xYxj^?we|HAb83G0C z`Z3a-gg~M}*`rz2Ev|D-Idr0n?$`P14uTgc+m?gx^vllSR5O3U`X*Ir9?|hMqeI0} z4mF2d;?!ezhNk^NtSX)q>AOp+ga%A(mYgC`*i}0n@|U_%9i3W@zzWz(MK0v-9JR67FWHF4l{v z`kCrr?&)B4X;H5l9`8ahT$Ih)?RWDziW=uUT_gOrmt6QM5>iNXyJ z3J8JL=moO~NMF0b#J1Q)7pC$zktgfK%&@Xh8%(kwjzGl!A~6wlF&PMjN`h4uo(u$5 zLW=Jb%=1&!0%+H+%r!j9K^mQa zh+I*7X^yGKiH+cY82wZ`{g36(0 zAe2oaIQOZd$d6kU%~~;`W45zGrQSln+G2B~?74Y;JJI-G{G;x_gSYO&Bi!p-Qc8^i z)ygLhJ$y@_SIg}QLzcKpqwq=neBpI_KKlfcI0l2RK#{a@78n=gXpa=sB9c*4!*%`q z2T+?XhepqT4^)Lv9RripVPz31PhWuU?)`&LH*is#2k21`VQ&;#eRwKBNQ2E# z+bLQ>7nzej#wn=?Pn46*F(!!!xaQ4Apo6VMtqabPy%G(od65qEfE@I{r6A@dqZx5S z(?0p+6rvH1VzyWR5#DOx3vQ$c)`~o_u8>EGHE0;ga)F^(6eLQ>wRJHa{wQcgD~KH+Y!uAL`Jjzi!O59#ZS@;* zb11AsB1Lc5RgfH?NUJE}e$UiU(hD5CbrdF0j^&LX1oxw?co898Cb>LE|mh@iyABlRQ$rckTbxnpzz9s6`Gb zQuF^UPiw=v^*K}qb&2}=R<_2VOB$lm7~jffz|Ggj%0)nDh&pTIS29FPgKp4o5h&0Zbv07$_I3H50Qg5w)N+HTE%< zJqj*gtbS#((3>tHBkjv`ats;sfdG<(5y$L2T05sWkBBeN=8~~&0p~;EL7uBG3_%m` z>A_trziOD34dLOg0toTE5S|mHnZypl=_$hz#!u9Kp<8w`GD<8qbGt8hQ-wyxH&%Of zY8C!#ifCLR%o$e=SrCGRJ@>~X{W(Pu^<+aQ2`Hr0%lyb>q9WQn+b>{?Gs<08rSrAp z$E7X|?K-C%RpQ6^H+l6yzIKI{)zC@|Jee_h`VG>Siq9~)r*^tA;gHXyEMxHzW@`KC zUu0;oQo}1eKypg7Yw+#u9BqSv`hWI@$Kn!46RDvSNHt284`VR<1hGB-8Gf-)IwrNF3v?rCK6uyc4O3lju(dlv)YXG6fK!ZsWD5;Q zIgg{HCDT|XN_tnal(Dht`?^atbEg-F92W-x3OZhNatTwRDJEE3ktEf}%VKt7s?BW8 z%4J8Z15j$`79K_A>|Nh0vN8t>c{X|OxFcQ|OGMVwu>zpAyg0WT1iEK5ix=$Z6jM2e zjjUmZjZtvCB7EsX{Xep!xurg3O@f|zYagQgtO57=H}fHByu+fy;`9X6&_bRc&@+7H zo&^YrFfIed=K)8xE$e%Mb%r%i*51}ECS$rMJ_#2_IG_ENrAj)8wfM|E`ZbGoM8?8v z8WS=_zc6uRyYNW)|e#)mbo)ST8Tmf(PY2+Q?;EaJ(qXx2L?<0g#`^Ey7*#gK5h9P^ILr9+J8_DEJ= zpXQ*EX#FZ25|MJ}&~?hlIi!ynJ(HRW{vnfrEiLnqA#N-1XF9^>9__tJs|<(7tP$xSlPf_*@G=Q4P-K51lN>u zuIUZ_frEP&2Lok}4fvNr>bK1LtB(1Iw%|c4tS-WUERp|cl5Ss4Z~!5 z_crZ=Omb*sQ%XO8wkY`jGxzTCc3pL$@0@e3z4l}6ojvnTn?UDU)t1rGE1t4~A{#8h4m1(16s-OhvI z)O>+Ykxo$`TneJEpTo^qVv#@~c*FbNa3=4wBm#DW<9Z>3>0Y(S|jWaq6c!)E2rJZ-M$%cwoXGQWxSn~6EuZQ z2VU0BvhxNL-$4?pN(s zyO9fFoMoR-;TnVD%FZaRuouMEDUQVs)1v3SZR_Cd0`Vjx0U&KncmUHutx(NKu@z8V%jK^jrkq(cLU>= zLDtPi43LyTMmz)Erw6_;1L>Uo3X>i5hm@mK&D20%mJ9qze^s;vZz*Fu!_9X> zQiV1%>BA`@-iBG+a`kZLK;oS2yB$j$gAHELgUPHQ73rZkGIA0DhNT~Iw}Gozo6BY4 zV_4ZZ+KV3;mf956Jw!+{9b&o-e8{^PRzjAHFj9_Ut$v^!;{Jb_5g_|fyFYeR^^zgFCNZZ0gOGS$!Xgyz!?H@ zk4oj45fKPz7-X{syap2dr8#&yM=XH?v|0>RW(G4sSa2K(Yoe*6(#Im$W`dnw4lnmf z{{jp_J|n@baO%gV5thE-(zc;A^Ihl!Ld_=lsEV76IbA3-aTVfGub$f4 z7rh$*(&AS}CpyO5t(g|V#i|u;dj-Q9#3VK}+Rz6=Xt&&13FkM#tlTM~9%wNLTeCz1 za(!VuA3eHBZo9-_V_sir9PxU`N0uq;^0Fmgk!=OL)hd_~C2d4XL5E;hXoMnmLkRz+ z%v+f^(&oFY2Q%YunwTW z96;3`um2HFF_=}@F${uqBBI9F7$UvxE?~QkS7YQV>PF0r!jus2Jgijq#JJKEUG&hn7N9X(k|@s3YQQ*ke}O9R&rUIV?NG*S3=uv!DLP<5;aQ zl>T6rmH_F1%{f7(Wl-;6UGUaz1*6KF;_A<%--?@h>L>PPvPQtO0a5<$ ztBt-2a^JY}oNW*X24_kZ2iPcbMmpcw4zOV!>8z-A3t8$$gPL#G<#5d|N?qn|5h%i1 zIu4(jWUt!f(`jrnz2ft1CvZ=5Gdag8uyCQgq2u=Bp-1stC(2}+B#bS+wF4uszcr~q zxvS%W;gf?2fJdB}JRhFPu$ZBK`rcr9b~;leB+CuCA7js**$yx+QC5X)a*4QszPsrd zSDtojOXP1ZseFRtV1}F0$A7=0$Y{37!6%zd>E6+UdS4JsOSllsDOlvIW@61mQC6Mq zSZ{nn6z((rSe5nDpT7&wL+t5hr;H=QA0~G7(yPCZ5wlwVAUZdjXi#Hf(4a1P7Ms4- zDQSNuZdg7kl4j#(mYd#6FQTU9=wrG0cK9vpdV%OO_OigxrZ=&9pdrmVV>< z)6gx$yZZ)0=T6}fFC9NyQOqLXR%aBI;5Z${g-a1_n^V+=a_EwKmVnJq6Id9v4MT5% z82dT?a}9EC1)8vI^+4RwR1|E;x)}_-4bo!CG#dwYp2cdxX$y*@F%+%L%hfHopH-R> zBt~TAnmATbBB@`1Qps`#y^J_Dx<{GI8Eji3ev#as!f0_YBE+Twst<%zMflJkma>tO zYg)}=O}b+fWg&;@G!fmBpZG@e|8ITCxmaNl*jDbsP=RcqyisbwWNLYYXB4IirDG)9 zr{WxuD$O|~d?E@X)`1Mo&ll{2AI(YuuM8$Psb0xp-iyOcd0tp_hJ})!b)3Vq0EZ}= zDtK#4-Y6fTo1#Li<+Zp6JTrzpOonBfN4cQ48E-mi`R>nkub`$*Y{Q{bOW6*(iOIzD zm2K#GG8yO!yURoiT*z+qpy6=GrRWDaFB^8EzLn`?U1%r`yA|#VzbK3wT8gptiIm-X zz;I=j9YKZ%(%a0(AgqEEGw@nMQXu6?E7PoOtxG@k3gW5#1C6l3V3F4-cb#vzEZMQiyztz;kUplm& za>U%9qVV-DoeO{kFZC~FV7G&{bbM{&%OJ?S`q|*F^5GEcnfjpweQ{WrA${NicD6O=gPvojjO@Cv=He%9&;!gRh>k}@ zH^H|JjW=yaC1Rj-tO6kh2IBIA4G?=Bw9ATTUxO^W^tw>?T0un5-!w?SJZNSJow(Q0 zy!QhV{=G4rjD{^~(NUV-0e!MYnUzez{KP4OV*PCWPozuk1J3bu7kWhyVfr86C{PF= zE`ceZvX4RQ6CMEvH3H@Z)n%C>UcwJurNF8hzW!&{xUfVetH(zT1{I8_cYTAgA0-FP zs&9TXM9)!1@Gw0CLP3_R3jFQY|0UhJ=k!|t?9=w-o~ZTFUCC#fME8%M{#EYF@wP8? z8#|#eg9ip2b__YW&j-ZXxe%L7uiAu|CwFkj_B;FqC}aX&J;Kk0DJ*vd5v))I7efK3 z91uCyadMg&U^EjmWA2gFHT=ojDgB)@!>aAd)5`tapEzo^^?bJpI5pWHX{!v7L$z(U z?z3C#omO=SP?|%nf+$8Dn{m50o*!|`-#K9P_Fu4rm$|E?S^$5LGBBs_jzka9PsQq2 z{bd+9qcc6EyJO-WB%1@Z1xbWeKHv(^iqgwf`t5HNjC2{GUdF}|5GRCp020`lGY)Mc z3g2%NY*0HXXwYUL!1sT^>yxwrD>bnTCH&;V&b@6Ry$$J)k9l`*E;cH0yli}T=R16N zJiqH0qL67NYPlzu`K7xpb5E3^Pi7tnDzFos`eUdW;~DJoL*#Y2k5CdT4dzLS< zeRY|@KLpy*5>EH^`yBmIYQ8KV)}d;|r%n#tThZDk(q?%%T14AWgw=K$3Cc)tz|YY< z?fMll6f@#@e&mSSoJEE48 z;QR<-_<)?a6k~)hiGhNw zQ3-{u9a#Z_ymo_{;)pJ?f;o(%?Rlu${3ksbZ0NvUtS4sMlVq@}H{C4oaGoLzV|xyY zFd0Q+tQ9eVE)-fd6~K;+A~dQUJ|bK>$(HR|*+AK9uDoLLnqBvKrL>7Lj8+G(SXih~ zU}BXNEudE5Et;GXnUq{5o?Jt0tiOl338pYCC~FWyr~YIwoCQ37Yp2bO)8Jjf3Nx{m zC{Mu#rwnliA$0VfdaU6nw98?W2fIAc3ONpiNkEKG2a74w zM&&#UxWoJdEI=sufxh-4Jur?qZs%+o2%A3>%HS1VdMJ%R0Ut!%2mVzZBqif32)IKB zQ0}o?67%FOF$9_+TA2rnH@*1g{&3u|67c#tvPW?I_gLFSgc9@WSJrwnp$0MTHbexk z9|H=9X8)0D6##G++3=1E*CO2$L4?N;7|>BJUt6Zne*0G@4yMO@pdj^ZSvy|1H9{1O z5<5^yf4Z07 z>o|<|sTH`>_whS3z4LT>?WBXsk-0##*m7ZUEgj~nxv+R)e7U`;JVpappeoBQ`R-mZ z0F|ip=J{ZbRo7pXkA)Ct8Z}kvPiCpQC$c(00RL z=>X-l=K;yG|I@^d0uubm;vA!=9H=H(sD>|iSq`mWKxg<;JhX-U>e1ijuK+E{h`;NX z0}!n0pVj&(PqmyYw_Uo|e`|MDF8vm*>c8b^rJ2AmVyW^4fdW}~jUWoTrlXWs*!=Ru zWW>nxZR)`UUW*&Mpy^>Z;d^WkH_r9M-jT(>c>8NU_{z85{~JFjhK19Yefeq2VRY2x zZ+AF>@9-fmC$5h>uC`o%h(r`MZR!eSyB2s^e-lTcJa7Uu7)IdM7$|V6Zgx@HMcPg8 zxfSGsKSK~Byb((2rH)1Kw^KrACjv3s6iEyg=WR@@wYYSV=wLo;SsMFMTYb<&nigY! zXjKyw>EKKXDroCYMndFzQ-|Y_t3#_AV7(Nk%9RFKTT`0AGIt@C``n4gh-7!W82c=CDJw+8cA&0EjSJdYY*`Bs4R^|)R!&0 zV9|5HqO^_3gB;?Fje%eacr3+4lOTu+{4Er|C2Jqh*Gv|$FSv}=#+}@<@yEX-42Fn%qM+H!94;aY~~LPR2< zQ;F}3>Cpa&n>IVUskOUA#d`9t@I}rb7N1SA>gle^$gB~AXqCt~1AfvcRV}{2C%Mu_ z44z(ECt>Ok{S|UPy2Lme(glzU*J)4HW8O=wKn#q!o6!H(>Gg8u-= zn~9m0qT*0DIadw)?!T(!!z|qpgq1)6mA;&XNzUEvyfD2$@wqu6=nvTyVo3al?!_kl z(v7BElYRsem?f?%rwomPX{!E5;=!HH_QTkg%9#n&0@J+GCM2EUjz#}QIGi1EIMw2Y z8_XnK-I+yA9k9xSs_qHlomwoh6F8`_mc4M+PeH{Q=R6;s1tmz!s8<)W&OdOQ~uMd=3H8u$!3 zAf6=wY#D&7dS?PSbBl}^Rsuz*l4M`Y%8bG z@QBVBFuU9v@!lK*>{Rk6!#Hy?puIzFB4pDQq~z0H6gPB}o*Xb)zh8NGQGP28Ff;Po5P|;%uFkHD@hv}1a4yZG89&dUH z!?UnoLtt4iwZg`1CK@d$d_lDrS{xRUkZ>PXGCzS5U^FYAh}0mZh3E1Q*y%%t7efjq zEMk2*vks*TEeURK5`WV!#*wk+N}G&t zou^fZ*L0Q+*n7U+CB_pNTSO~paWH0f`lrZ}S#e&ehH2lc6^zR@+Q8zX{~pP<;qWlv z>J~zZK{=5_LWf3Tfu`})h}K|&kUGy`sSOe(=Z)c53=`e3dy=?I4W7o90;PgcyL}9O zT-;)Eb{9w%E~s=!fgSnKDj9c%7fzPP<}VT;EsWCcgbf0e>Hj-B4}C*!G{%Jq3TER} zVBn2C5TjP?%!cv=BRCQ)g58G7YWN_tqqMgy_!^Rt@t5^~#;@PMg0!C2+iD(R7zE(X z!ho-kLa=>Ek^?{#Z}ojWL>s?<%>t9o=o>g#zjMmQI&oB1^mXVfr>z+B55&7d{~jMl z{lTPUS0(tmwf|~^)Ggo5o1y6uH`_(rcp4I)+E5m<@1YuAskS}rjbu9ww^m6hCrPj11nR3Q-EYGX4Egv*QQ+_yYU8&g)%Q1^?N1& zy#_G1Rm0g9`bQ}R+fOF(nuYc-UBj9NvoaC>F1WNiG+YnD&B7kS(}a#UnC&by?6nly zn9o&Q#mO=L8u{u!#7|vDOr8_>9P?w~^Ke-`OE=(GxThEafxqn@e|oR4zfP5zl_-QB za4*qX#1l7@i|7s$G{M`$!x=kH(6^9?pACt;By`6B+3eRM8}^#iT@t=)(uBVZ>A-M} zXxf?)$db)!4c9)-DNf3sg0m^!h@>b95yr%sq-r{iQ*7l~M;SJg(BC_%UcR=``ghE^ z%nrD!{yeFU5hNMVz9Za>7RhebA`uR+{!%25YJ-G%P25g>Um(${8o87L9F~V1)qma1 zJ@U3$=PiK@dhGx;JmAof;4gfR40MQ}lVuxhhM5@R*C$8*S~|;+qp|4neRh=S3BQhT z!$Zwl)y)_pZ`2^8DZZ*dFiFCDhekA#Q1OK>J9;td!1#4G59BOIFBmb!7=KuTj84i# zv=l8y*X+O&2)l;C$CsySV>naRXO`c*J`5G8Eaw|tO>|^7N%?9~Ld#s$*yU#OHQDwf++ZUU#g7=WmqYpHQ!O7iliv#V%HYcEJ zy>ZO|h&muQ%tkIuYd9!nA6&AX9+8_k_$Wg> zaSxD8HydCO$TFBY{1v83hBIwX8{6*)UpqR*S0&H`7~2AXd3Mz8*epQgU;O_q@J0U8uy1}7Ss~^7*C8L{@m#nOFkU=~2;4krJ z=-zzAWB0J|>;|F~3d+Mxp*VdZQusu7)xHWgC;2`9Pa`9_KD%=jn&E|=t8%qrW4IPw zPK6&>jgk2iu!e0g9-=b2n}P~R#$dZ-y@-SUl-RU*E%?*se4-oI0`!8(HtoU~lPV+P z(}f%lcga9*%>56s$_dO979{XcYyqLW5{gki{F>vB?fWVL~bHgneNEAzzf7 zq%G{cE7k~qoMOqC8$flXl8Lwp&jjWpc9CY8g96!AA~O9N*8oGzWkw;C>(%We>1YZM z^T@mb)yHJDQ>U;01?rixcpdBix0z8k5Ra%G2ZzE9&}H^wJ6)S@o9v<}CBPNUN7kfc z#=Of}6Jp)_%;6MA5<>Er2f{!++A)Bw8(XoRXZ+Y3J&%bWRGTeXdTHt8^?cDMUIe7Q zt28}Eq$=#D^Vw^RLs%t(=yp;zM*OI37_&1WG<37Ovkb2-bLs-?`Jx*(Qc?307~&Ft z>i<$<^BB|6)dRzM3v}x*qe#cwFVMX%4Cm9Xf*yIKv!~p__p(U_oU2N#LKtrSB~J^3 zpDIA8iY#q+4%C?F7UG8$geq*^{czVRTXIIa~z~1&y#7cC- z;s1{AKZp7+sG1R5)J?YkoDFggm|*GN&JT7W+%zsTA{*E4BGENg8#^75X^5s$vxt72 z*^)-efIo?KRMF56u18hM85iOMf@n3IGW%g*3Es(dl{&(q8MeaGk0Q>W z{#?Nb&~R|KYnE8x4sC8PKyGebWIMz1a_5G{<|W9o$-8e{Y;GXqae<=1ZeOt)uRmXq z(z@aNA}(Y1q0%rG?W{kloPtBq$*^@51U|f`N067x2%_ROgyZ%g=L}>Y2LT9}tD^rC zLu`6b0_wy@h);9>;zc(oX&9?Ud;nu&&M}RYzn_hiA?&q3OsRHUR^)PD+xvv)JzaAqYegRKN+8}g%u5_v2f7 z!~kMLv+fALpqs^-^@h08<_3+LflX|#Llut+6GY67P-3PGrZT8{15UB5wi8v|tXaYR zzVMqbc1kBW$=H?aX_;K>b%eWTh_LIHKkGSA?(bv@n4fkAx?KVaw3xlG>9wvX0IcWf zcyZ8q4@}`yGiGc{{YyO)i=M(4MgjPdKG^}w4AAeDPo_qn#28esc!gz*pMG{%ke%&% zuyV0AWuiP>#!Kc!vzS!btzRvE@Kxj?!_}2JHw|OVE#o$1L@cy%O!=!wDYPj^$OfXS z*Z)6bgQtEI;%eGsqze!xQ1=veyJBc0J- zftr@D<@G)KQn)Uk?$3<})3+bt33>zCz*xHYAP;+o51|-#M8doWk+$NzW?7IB$6mw= zH7lhnb|;^=LqVL_ZIwl>r>74kjn^ zsvs<`VS6aT_Nv<+3Jdc<=*FCH8@;1!euF|NvvpNKL7lwu0Y6%pm`;lKUr~a+G(o^O zD8P1`R{x87!2$!xQTzZeKQw@qNz|Z4>z+vW7wK=I3a|p1p)Lra;dg@U!Uh=TaxL!7 z*xCY*miBXs(?iThm`i{iX=%XIf zhgH;XTI-m3)EABrK45Ml`G{q9 z0Rde+U=HIKH~2N!w5lKOqS#dR-}KB8S|LJXsiArcwP=kKgQIV`2mSsv;k%nJjI!1X zPuIi$Mmr1bxQjvQC-;@Zq9( z;Iph2@<*3wX$H~qhh1wmmIhn?MVj)+-Nu>^aB@>EDz>aDubXOA(anI{F zSIPokB(jO%P8E+qFc(!KgEPVWMIEPlSkQ0iX@Hk)-5)g(1<#wN)LIG9IZ_o*y~{uE z;92!wAUc}DTsYg(glZ~K0U(z^^G;Iz>p7>RkHC2*kRVEyh>P7D(BGuzRypq2aQ==a z?kaD<*f#ps7a%w@yo-k8wf|mu!{P+S54<>ZJ-7B*O+?Y|YkP;nHxOV@TEwJBB*g08 zO4rf%Zm8G{_9|E81b8y4`di)pAlEkxKx})a0MP-njalgb-zAx}(sEGr`Np6e*4)8^ zXCjt`gB;?6!3>6QNIqSwZlgMKcYO@)jWTrhe2abfJBp2EkY5C}EtC@-wdqm;T`SH8 zC8QU8E%UwbTcF8Z>-!oIBzrcZ^h^wgIM5>_2$y8SJ&nQJ5iIhk!S zQVLY*YkU#_AJwsIcM;%Sb>9&jE1gN*>(j%3UAO^L@7QUtW)GfvHMWSrx4+TZ5r>1O znYH6-{Q5L`5Z5>kF6CSG=*Qi|>A^Bym5+W!BNG_xXn$C&stZ>!Z>A3)I&`Ri4*b-q zrVJwt|2k7pe<@Tmm<3al%FGOR2MpmK!BR6Qo)wb-+_Dy1-vJGr;;oFB$*OnuUs6Ir zD{MzdAP1NpTD5|x>-^wEzT-6OZfGl1l^LrA)4BW8GPBbbn=ig+ckw;>Q$7eMHmE4N z&=ROlLNV%fWKS?`>j{T;7fE!3H;y4k}{H`Z@b%_3aQCfH}(G zF`yHCRT&U=nQ54$6$D&+pwj;EJd*H2HqZW*;7GRZ2ZXVFu{Z23@ij{ZgpUNzz~X_R z3SDYd>E*H2r4?`ysUf?M=41U#vZjvH`l#mB19S6eCvdbd#N_6EK=b*iE}LIb#u?43 z(z*FjY1EU}FyqfezzKC0Z-wh1t$6+Z`>WPpTHn*lYFn60gMT8>7Pr)UcszqDq~6Dj zz*bp>JiyqiY9arDQNZ7_`oKjuz2dX~J`%I26XZxKh0@{%>VjPb-PLfP%7WquyDO}l z1=Eh|0kB3x39UTtUG<7_XdbN^?MNWMIMym zDl}oNdl9X{mm<5?&uZE&H(b#W4P$VnK4y4N`NRftK+-VHc~?;(oyhMj4`J~bOgEL( zSpRQIlntT5i=uvd4k=0BD(Zhnr|27ln=j6g=RrtCy{yBYv2_WSOA`luUjHq^&x`qD z3oanxSbxD{eu&8i0T8BQ68_dcg$fn#6ayLjun-Z_O^Fn>RI#<*OIz5}wurLrJD*uw zd0K6PwMZ{v+X+3}8~u{y{15ovdcH)8)oHm#jKPb)@L1z)2bew`!~OsHIPV~O{$DWA zpX+g6ba?~JWPvQJFcSd`wBZXl`RZTBDl8HPFPKtj;xkO;psW_4hO(JrwOcJL3g}?3 z9z9+RCmx-0(8Gdq^o(netT>c?$(zN2|@UAdznWo#f;wVk50|Y0^mRPgBXD{?{Z@@eJK2c z@fFFW(trP*((f>1P^^r%bk{n^QZN0t{1)oSkFff7Ee6@m?oa{)DooDU-YMnl2*@%aQy2-tk3G`ho4*b_`RVY)~+TyA89exFu9qrLj8 zBptS^jM869-xTh*(L4n+03%->H7+b6BhE$3$U@Z}1R!+Cf%ML^U|MYHh}p%A1-l86 z@?$IM87&Tp@B%sdAHa%mA3{VVYSeVz-N(zZXNRFM>yD2uF2zx}UF=2u7_$DRQ+0E$ zf|EF&qEmQ#z^OSGMn(P8=m={@sdVowC@h<=>YtYD7K`_f--NtEC@-Z4)H& z@%YDn{{6qui?a~!`H*-?DkB|ip{N}FP&d7mzsLD|@3p-GbdJY+CHJ_xNcl*?^9LocW%Fur zHopN@renUCOAnXqt)26sn{j!VfqLZKmpuHofB4ulfBede-_n%7d-Q3YhBX3RCZqwx z`(X+;B@g|=YD&~Vbj3@G_P_rC0(sNC?55|YpU7K&0K4*WHoc(tdFA;-e4u z%vnqfl=+`!msz0!*cS~u2Gq4I6#&wWiw@Ms$AqFsM@dT!adT*zy0%N8h?cN}A4YnP zKaP#Z_Vf$bT_@~qsKS*?>Wd;Emex_f?h3ns(nZ&4rxh&Wy6fWXtC(Rpz z7e87Oo83UDlXmYeIG#$i1v^8Ux(3_z)K8Ia!i22xco$k4k4gQNA9JdnrO!v}=C!%Rv0Y@&%d;MwJ1N9oX7<8>8Z%wqdLl)X@%xl$uZKEDXq^p(cGr z>Z(F@oCvpnPvrStc;&+CnXl;OeZ@7SDmLc&Rsn8PGCu-t@GXKx?Bm)^oEmFSxtfSXgJY07D(nP4(W)a$$gnxG$G{ z$dsg9G6Ax(m z$y8dVlOOLe))Q&(Pf4vH7d_+I)l0v-0eU;QDK z9_C5}C;=S zo?g)%&|hPRG69ImYGWgWlF!^fehpzC1idh`n9P#X%ygs)o@hktG0l8&O&=2j^Xh5W ztFTa7S(#ppDcmAX^X!G>d}YO|03t_)Je|f{PzH^^Qnmeb8V8Rxq5`>Xj{;~*+|8o^ z>S$N!2_EoRR7`DdC957qwam=Fj%xWpk_@V?9*xnde>z5|snY4CEI7S8qqZipK^;1>-MwCnKIAodEDL+CRo zrntM*W$E1Mr7x@hZG4L&;?gF5Os4^7U)8S1o_G3ZuJly8v$vx#o&FERQg0=~SSvqM zpL7kW@UF!w&{>d`>vmI&7_H9BYEukMCU26PTKgvoy0|B0Z7akV?2E}@G z0FbP_A|xTdnmk4ae7CB1@pYaFA;Rja{_kNsVeNHJYyE`GF}MWjut*NrRrMEDbLmi3 zzYeg!v|PO?VI-<~`d4c0OU%T4@fk| zJE9c?Cvs3s= zV>Fh?HO`O-5UB~$rug3anS_kP1o*Q435vKkhX9~%8aMeGdz4MZ2AeP(i0HNh0|NtC zMtXc9h~r3Mx`0kdS;;*mkLcwbgpZR8{{YxG@eDGj%<*E((&=xC8t;?rhYcfV?|%Ea%}g(R9zYf zXJ?4an%G&MmlHgToB08Ljt0Tbep(PrO0p1Hpp5I?K43LW9-^t*4oyQ0Lo+xIXB|^J z6GUe-6YTlt&~t)|dyI#mcRrpYN@s@#=!yDWj4%CRfcn8sb7uWSPwwM>oEZGkwaqqL z^X=!XV$zwpGWD-#y%-hI#9HzlvfeX$Sp9le{@Y0{FlR5R&i8x|Y{>gyR0S;c>Oml6 zOag&2O9qqgjgWj@LeD076v)_1llA{bm!deI6ZEYC#~!s;^Th?COfQ{JRMaeu$Pvdo z!Amr;FccWcaI@oX0)0Nv8IVH$v_bxrqavGwgW1$27pAp^yyD{7h zx5^{9ibM&x&(pdk=5|ks0Vt8OMz?xu+uk?^ zdYw2mIZLq$%6ufULW{l7)fmB!L2{(50{9~TAKC3K`RTv9vwXXPsD&Uo)!E1DXPKdf zSeWSdU(vyxE5q9X5(F=gKm$%cLe6yRcZ@~exXwOxCi05H??xOh(B~CswXpq5Nw*gx zdOUatT!UBev*2U~;qMwE>N)y-8iF1gx3DX7Rf$-88!@$^5CmQ$k&PjB*;O7saBfLT zQRFK-lB_qFao$MQOXh@x>%kq*L&5E(4-{zm6=LpFgw@>SL^Gya*po~zy5#ZPUBDhi z(XQC&D(W$4w37i8Hd4E%CmEgs;v6C7oz7P0mcwRDn4{|3%jv7JWsjxz$992U`tuMy z+u5tB{9N5*aSo*da~`!F&X;UmsV_{#w$~pS>t7JiGV+@q(<+^??@o{g*0{p(I*pr! zXSqoIr2c-c_$F_|$fdvvTF51AAz$Wpb2X=)*7aXb)qmLOzqp(C@bAj|&jKHq!20{m zCYje$GwI1LWQfMDpJ;OUZraX9F@SZVDC7&Vp4HJ$7k+a?P8qUd|o=O)w^;3g168VSus%Q^M>3yDOJ zpKbXE90 z{qap?mHk#zVic4_9>tSY=F#cRz{g> zhC-k)d->YQqR#B8dg^zXCR72t2sEV{sy=*RXITvE6YVsz+}K$*`?op(Yv(A2kV`@Y zZK8#B9YS~X1REkTY8yud6A20F8yr2 z7^+AI*51Nnmrt>ZO0Oc46}q^|op%we(6SJ|LO{qFsw^Pv3M9jV1rTz>)L+1(Z!$%) z^B1zT3)<+}B*j3t`ZH{Qmayc>u)ExoL23??%dOBt7acO5%jMWEP|swYup(hSk!}c; zM3_Ok@-@WLRj`T-vxbzLI0im7&H*(TIF?C*-OUybI&K|fTZhxAEH7s^Ap_8a)jduY zWC&uD%l%xr;MeTKa?f1dc>@JgFWuN(98$(p#10WwNIR;RgR2OABadHR0{hv|@5kHU54XSX z<5y03mx=`(=dJz{q;=fqLYG%@Np!;Q;txXo*jXNhfRD#D9{%0M(-_kj>)2SxJGKe{ zM78dmMmJ4gd>UOsao(MNrv3w1AvI4&DI-4+mIjbCJ(PC_if61ciuVno6Sguo`o${D zqh}l!2*8%^`e$6HRrQmpj8g-U3KVRR3jFLCXf*F%>S+Y0=B5K$u>Tiyso3*^BeuW0 zcwbD|_EQ~}_~8Vcq45aZEvZ5N-uvlB^!)rYg9fAnM?7DE9Qe~aWmPcE0dtIpfZ`Vc zy$vh1NyX$P>tl2RsONpktdF2wrJGBZVBwN>wod<2z2W07k@<96{l;)x)7iLh)E@ri zR1G+gAEWJPu>SC=Vt_q9&s7Ty6BXU(FSGm*zaq$k?eG0Q4`8FZv0d;sR>Q*kYVmnT zi_dunGGgrliTDGBOG+oOIZ%HRm4um4v63Ot9E6=7V87X~;NK61CBBCMzKRD%6tPHi z`mPk``6Z2pL3`fU6z7&r z)4PgKLutQ<~GBRk{4N^eU5l@;) zD;O8{1cgvY7~+w6>^0tQuujpA8b>Gja8509;V;Lx%xrrqm6K zk@xAdQ`s7ZiNGy^=BsEVsW3X*$ef)Yi{?!4K*O{(h(}__SX1mF5QM(k@f^Uf##zt_ z0vlkbEGdOBvPCUPYbSGs5vki@BuH(;uK79_^257AWr5$K=Q*fx8YID$rXV>Kkm>-_ zHgpxmaZibF^@Mr3WLu{HGEG-`U{A?(*geiBv_~RZ#6#==neK}1ZdLkq7C>M%TKS$5 z(|4P;YJZD*u7{Yq9Cz%QBD=ha#ShLirbX4NtpAB~Qa;O6u)Gm1m*DCyoBQu9Sv)Yd ztYHS*1qxL_K}=>rj3de)AQPdU^f&+_Ib~0T3WXww0)aE9IWPi4XjtC`@`$>aH@*;K z1VP|0V2c|>CjDiWA}I;51T+raa;<0MZDqu4CZL#30P+G=y2I=^1|T@B(%nWU6-B2c z`Ax})tMm>xf#6C3f!gLMS`FB57azvQReHT#xa#HxzfRRafsdJMntE@+S(sfI6EmG= zuXiPv{-Aiqs$b~WNBa-*jM=}g-+wQo$%fwl`sFf>)ya`W#*iYt{x2|*^8}cQW$;M> zl1o4G-uzBb(0|U-y=A=qefbAq&>G|NJZeH|NiWVd@rXrsovazj#L&6^Usj&XOiZcO z^{(`17x0urc zjp|ha1U|VuH*)=qUg8YN<@m>pc_3lqpn@6lCdSAQ_Ef;eg<7pYoy(yZuI7etlOVHVnle;JsPTN~(6iaITrrf;LX~MhXNKWHlpc*(-p9(@t}f` zhO3NPHq{lDmql4dF@1YVf``#%_mpTH4f%nn>D-b40!KR~+Wxb!I0ke#euSef$Sme4;!CQgGe!b|`IN%A`}TU5kq zWqZghv42AB!=MZq6!ou#@0Q66dIpsV2h4HmyU=T7Giq+`KP3ZHmP2@m5O<~mlbdQk~Re~HHBS_Syd$oT_Z%Q z`)uWr-~{M84CQtQodOZ-JI4Ip@;jOdpVhxtQnXArsv@x_U}^~7BjB{-{Io~w=AH*` zIqR-l86&I_xz%TKR-*!Fi9X~EbA=*Hy{U`?tNKrLmUc^G?mESo7StA(^ZU8~zJtut zq5f=4dVMQJz=#K^e7VUqzGn8g%@!Ee@Q(N}C`K17x2 zr(L2w6<~U(|EIg*ON_9z)wz^DfZ7G)>i54`W!LUKaLdkix&*M8cBrR2U}W>fUer6g z0k`OYYkSILNNI7K|96`CF zi{Ml*0ah>Rpv6KWydIz|v-LAtO*)Cp`q(Vrd&-SImO(9Gjrf4=F&cmxiaVH&+Ntrh zSHCzs^Q>s6hb%%B)8mPda800M;xXq>brEJ7`z2IH@P zQe{~5He8(4KheC#_q_Ks_r?yzu&n;>`s3_)jGZXqxDePA&}8nL?XyJbF2$OfY9~-Z zz=?kU{1t@&Wjm@HI#Lr50?4dhkg_(L!~kP_bYvWLiG}5Z5EV0BE%@OrB}-XWa$60S zNENIr{5w2@|G}K-orrv4@SVrsI>`>+}4CznBbrMSj#BAGBu`P@)HJGVfabeJ?TelpY zs)#&@xC0lF={J56z@aV~U2talSbOJ5wr8f7JuThwG~OOxUTzL3_1qVi7DN+i8&$ic9)KDbH)h zCfgJiF#Gg4M7ay}HIhk5p$>=XP~9K>NS1*jVC|S!6jTH(^}%#P2*q^dgvK1kqS;Fi zX=F?TI`was14I+Aa&9*qgoFb{FoILx!-o|yvshWYyQ!HbOyv)UUe;f}{EpT?=TIr?FS`4#Xm~_%hL%OZJbpku98tjZ3 z%ubzx&tN}UQQHFCLfXXQ1Aw9KbnDwH44r7Lk*^%hN%*)2UjsdD5j7i5Mx^Lh@C7nk zJF11OsZs#sF4WeLggJF4+|I2&(S595^NA1OCx_&PoCEvpNB!+7ainfn z^o(Ll^cjq%gbNrt3Z+g#g`qk-km&J$1mS5Itunb6AHHL2D){12*k}6BLUk2P*u8R1 zd{X~0A^uJrO5j{k)L*ZV*C*LS3l2VqjD-Z6k<`I*+*Z7lAXr85UR_1r*iFi$%tc z-#gRc4(-&phO#@37v7!-TLZSB98??85UP|9OmU9FX(;7g=0njG4fc-*g3;6nzuLu{ zgotNYsXftuaYf>t>;M>t6p6=z^9kGv9Dtpo{gn8LZ)_0MNi1x=sy=!z&sMKV};iktNLIX^g3yNi8mSR?2k=*H}A zOn=4EP4&;hoBRFeYky|$5&hPC%P3B%RbnIDO6}97c3M6jrW^;t0*}=YJ zi1ARe036^OoS}Ybs^34czB=osZW|SEMrpq0v_yn=skLs7Wlu$ZzcUjkk<9;cCNI_o zLYzs*Cej#hEs6ZgXZ!Gy+kZokeZkb#Y__Kx!G$F_ z8ko%uWD~HcGr0Lmdde=jiQ)EU*gWBuK&8U-u`y=wk2E;o`QQm+`LNl3%U}rQ!>7jK zeKs8yCfXufsB6RwkkmME6zl5Iy@9=&II(N`7%ZkwX9Svzc{F~4u-#rWi{fxv-Pn|5 zHf$Ie5A%}u`?sDzDT!e^$kMSgh-R3_g9+DRX)^A)UJ92E3(2;_!J!7Y@CJjCEb&oV zm!@MnL)jdxqteKJ6G#=HkoD4j&_4cb0Jx9C{e4ndNNj zF%rNah7_?7Y8JThL#71pTt5?UKu$luAp#|2W0kVe*^^0Kqc%!CIKvVpdd+&uOGNa~ zL#&u_Z;=g*lmwT}Sa=*ksb=lD29Hl=bZAVJ5?z5fxsws3JV1KWlKtE|IExTY(rIrpk`wdaplN!8 zY07NjqbVb!C+$(X{;%^0iYg=&E*>ojp5;vjrK&!IPv?51YTb;ot9 z0^dq>1Skn65b7ns>C(e>m&G2fnG?jI{KqB-M4RD;xqI-({i zAXX(%>^c;HnG=zaFMpe>@LS&2yxkBlIcPRN+CZH?!57VCd=qc9Ds9qIJfNq8&2(}~ zd}5i(cd*aVOtC`t@ z_p53)NM5LS;?^dCX8Y(mbRut(i3gjAN>l;h*n62J0ekh}42AhREZrqNEe6E!W^UiC z3+VuIF!1w+EI?1VnBhhd+75LEv;cq?!x_Nq+0iq7>g@;fMgE>XWx@WYbh2gdz_b%O z-Iy_vmvRzlqz(Rh>vHAIxc<3o3%>19bimi|dU+AbP9#rHuNIS8x% zd7n$GSUiJN6$$18EZd5l8j1(=xC}-bhi(-KJ#^j#!y&IZH8}UMRf5q~b|6JCGcod8 zpzB*IqRCkrk64w|wyb3d{XTQ4wsSO|wPc{Mi&au+8-b}8b}pkM^fXhJHn@FsfF6~X zwh8p{wfTW7A&#r_ZL3oOin(H5;GEV2^w#M1cZVsFBN?VyjJl5=?PpbgT+Oi@K5x2% zD$CTu0ESqinvO1Hw6t}IlaO?I$^%o^rgz;70PC|`xjXB|4G)pPu6=PVmr-%$kjSoK zM`=^A>eRsrH{1o#(2CD@Qp);^+7-}2clfiXoa_JBUbUf3NWs|@trtS+=G-Ii#Ks{U zVhhVMex@ZT4Uj0)=JKoHe1WeZa41+a8js?bN8$i|!p^H1KVQdp*g%L*!Lmh+Y9~E} zBTowm%4M_m*-SSyGe(6Z9f4a1mon?T8+Nt~@wXoBglfC4X}HVW)4FB+PPGFN4x)ZCe9`)k<%N2xH-+PS zz}~0qy>6z%Z5=3KL-9eaYP0#4W>Zu14RW~I=+zWg_1_ur1V0Po1r2aHnH{|LO@572 z8^nxtURZc-iih-#wALOfuS*KPp?;H%KE)_zbiqRY%~~&JwD{PmU_A zpqbi3=mb}EGE~y&4a9-x(xU-G52i_^jkcEY+&OHttWMjGrjuPrkBEgMv(>s&*<3t| zf_+1V^+ziIV%V27f{AuV^kJ$SNC}4L*+f#8M+(ueVk6p5rS1d1Z_fq}EU~d&kcZgt z2@VuF*np)Ak1UFDE>w%Lf6=K*fB01!f^-6fPH-RDh_3&45Z5e zFxJ5O$u0Z*Ob7X~BjMcgiR=S<%@`pRDr)JBB}_pbgJIne&|&&ue9d&r3A9hdIk_xr znwzsejD2#ks9zfK#bA-!-T84xL|3NP$P|b^LBD{)0N#^u^#D5%dA@j@iZtQ}WnfC3 zvzwmexZxlt=nDcXp~*XQ$bx0++#xEZCxNrV1u0B7nlkhtv=?zDG(pfJhl{~erdyuk zKysEp=Q&5~GN~*%01s4BMLY$cW2U%>IcJSaIrcKLQ`V7~*ggj2@EBJNFLy1lJ|1qT zPcRe4+^oq1G1!A%2skRfFszAA9{*1a^Lg1~-3;N#;9#8i3CvOQDDo^c*HVVqtYtRa z{k6ZyDZS{5@fhZ4Fd}hlMXA{v*0`;iQ9_RED8}4<8B_;(oj0hRO<)&GA=gcvrZ#k; z;{s1H0L`0{D)Q!cBSH^%xK89y1LC~dkQGr;d~dzaMjxO66Xv=DU`4X;F6(ZV7oE1x z#Ngk-GEi0*&18zLybe__(KU{NI-w0(rQl;%n{%o-rLF-@MUGcfL4n!a96jQVW$dIb`IhIke@0q?vLR1i^VSp0&FJ5H0Fw_6}@H7jeuKy_ z9)}G82#iIp9^%9{W~(BMVjEPENtGS#F3nn?hmq8_$y$^}^%rK)U&mS#<`fN0$uYx) zz}}-3`8z$5zmgGx7t3Bf;FL0@>IQ!bI1`MrJKUI~ty&uoO+_TQViL_fHYAL^H#uT2 z`)9C}{yvK>d^AppYNJkf*&_>~rm1eu0t_8zIz95`Scxb)m6>4JG)L{q7PRcY1eOcj za4CTMI(@XWAR^^x2pa_#w^@CX07EGt(u;OCI3a|U6+?|+{EZ&t%SGc5n$-eyj0-fc zsuw7OUn_JZsF7{H-yNpEuf^$XqcAZqQo_LcX#1;oSf}3}{ zYe{amF1>UTtUNn`mNI2d2BH)TR3i?Dn_P*HqtdRi!ycJ9%`Nr7z1%;5Z3KOXBT;Av zvOmRj*wl>XbY7l;fWJ2HW_+KcI|R)L6EPj`m< zYcoK6=EHwBqWdwqW6j2BqDvEGpP*;(iD~RgnwpzlU;fq+;+D^EZof+m@mOTv2Fmwp%fWAYc8tNF=_}ZcV#u53$x{ z$)d`~>R6sKo7e>wJ(xB797;W2HEe>9MNB}ai)P+yX)BIZ%I4%uNi~Trpd|Sc+^f}B zYnMNa+zMT6PzfXhA&F5iV2~|l04mVxh5cCS(!PSSWLI3wox*h@(F8iSV}+p+stV1x zU56$D7aK)6XJiHkbA!KS;8)=Hc>VXBl$cStAP*02C6HxpXk*~Q6rpW+g;W9S-(N4H>VOf7I8py+gm7ae5y{h> z`M;wnG-ottKG#ERRzbE}R45H-VVAcz@{;Y1FC-p;MoF`!F-aG_RD*F!*MCBjC zgc!Y7DKJhqi1WpwPF6fvC6L*6d6|sCP$(0jtp|2IUcVNx#L>x&vNa!}N;1YtH|loJ zq(969{fp>Nc2p!@(L&gaL|OnW52wf_Hs(U3$v^C6_Kp~6BZPL)sZW3u=8q;YXcFQ< z|8U;X-Xj49bC)yR`8b|=4kb{st2tu@JqMq`@psDzV?O)epF@>K)GOJ#&i!y8V25}Y zB?T6fAnMb|cge74Pj2o1QJEvmnVoK|^8zD!^TltJOfQo_vM)9v(X(tc8 zvhAw^YAcrHqlAMU0aoAy=m|5c4aolYuD$H|pQ% z4765IXlSeF>)&$v+AFzaJOk1B96TJUE_0*PWU$EVouG|(b!fzBPp0eN7kp8qm%Y-6 zT9x_2v}Qg84ZTjE`Cw81d?*)1I{J!I#z_z4p5%DrUEH(Xw0#xpvV5nMW^XPG^B+YD z8`>Fkj_oGL+U~<<(}^v?&OXj=NT+~KKok@k=o4EsJw11S_uUj90nccXa)RnU3+JFX+(_RdwDKQKGb~nIzo!WX$qqrzym$!oJVXqf+U%b`jaI` zw}z#OYSN7>&kR&&A-WGy%t_m!6&E1%T?j3H1s9q9=JFN($;cbcMgbgSuJX$CJ~a1o zdOe?J9eE#wH=a+p?4^@TRO}s;kf;ap7mw(XI%Zz*(F!*ZUqVc~2tA3&xqJpkKaYnM zk!oDGyXP1lYtJ){dYgG%>k|r`bRGuO#D!DHqa7-R22DNifg;h1`ppD8M<^uzdwQ1k zy5Q+Br?G|>7G8%~4p8)mz12Y{-6`q=26h z=;&sAtjLJ4X)HL=souev^%~?iu#98H0yiYe8VGbc3qep2t-a!b+>(L>oPZTLi^fCg zKuwz|p-bV|+UFNZ9VHE594H`3yJu(QTFzk^zMyPulI($~I81IVbD z^0NL+HH|GM0D3M+X9VFy`sUDHG0W2|Eom;oFlR7ZIk8m*hKUvDjg{01jG`a?6mkl(AMG4P#$ea#U zqz4#cwvEh)?T73}7c?Rt^PQ2us>wxD{}*#;JgIZC9B#X$i2okE_yu8|%IGDUl+Ebf z(exHlPKP>D87QL}Mm^#A!0`6>8cU9~1vo~pH-HN0Oi_bFigE3A0F9INHBOrcf5T?Z zfX32UV5~2hiJxc#@1t_JSNs;4NDW|rbmer8tUTbybSDKR|anUC_IjA#WF`#27a9xB~;q=)AU^Wg7Um8)-4l5UdU#yc?fXJd8_W!(b z-4aL9Ly)g!EVBGL#auIYnXKqJ0bDt#GJk&me^d z%sg4TC=ot7K)yw14A39>pSECt)@7*8$Qhwq-Gjsa)_sR~Fuo7_%(8aTt!h6p!z%CZ zo=NZff@X~VA<%-prjO%P?$u{2p^)|?($8A0Nar@0Hw9j>MdoyzYo^#fJ%Owh38IOH z!Vg-Z%Iu>H@0*!$JX1^+gsm<&`iuoY`rOC-488X3X+k!k)9HOc3I<)jr|%ZmsDFWi z4}FyJxTohk>!(2$YpoJb(C27!zu3eNTS? z%KDDGeKTW(*83dZ0c9RmzA}1VN00NP=~a)m@aRG#I!~3_mLHMm*YU2^6%tqLb{FgN z6(Uo&K|I~SF$IFgO(>oEo7iaS9ry}{;bg)7`^gBu!A7*j>E(A@Ff1;nhiH!Wi$O!w zBJs=rG+4Wl5%5fHIcn0B-63I85?&zJ3A9E`(gs4oI1-lSF8`HhNJRG0zZ}I@D>?#7 zP0J3T9mK^pE->DDzyj+_I+8~Q_&Ja=kC&(H`(%vT9NY`~=Tt;bAO|*_KJ=clzD}F~ z579TW#x);Z*qg)uq7Ot}U!B!VM54OK2+uzr=?{8NCd>l=} zg6U7WAa=Z${)~(JxZv`(3cmeN3mr)mhW~QDashgqU&A(#tbkb@3^W)Pz&+w10xd^q zEg4zbGAsRN{rFlE*6=Q{s9@8MyBxk+a;Pnm8qN@`+hrAs=X~K|)*KoT>#~vlIJpm$ z4r=8wAS--80Oe1X_4no4Pv-M{aE1*r6wo`pA#7@-^_7wiZ*^&w zoPj~$J_h#s_2UY!RcQ_F#xtBhXw}6D;oq!zsUNYtrmhbG40OmkLckd@e6m76i~>GAZzz0&v7^F_EtS!v%<;eIWG|*zw1y58bo~F* zWAf9>Q#4dj{U58Wq`q%+z^BAkZP0O~d2^U>%Ef6l8nhy-X3;LcNk2r229 zanqrFbXf;cYV!Jh4JTk27=z)x(%XuUKor>=)=o!`1`>e*^Tx3voxCgm-x8hkik z{Hk&WSIrrrgRA{Bi-jlP*)2 zOCw{`pMQ-SdC9z@H@Vhhqe-Z_wgr3G;?UY_(37k5<|F7_R%lNemnO*6q{i-tp&C=i9#*)c?NMt6VR7MRs_HN=&SEbhcqT`St;w$~8&__x4f>5IZ_H2LsHv_U#2*(7 zqC(MUK=(MHSguStVMs*s%EM?6g-~?PS>No?bH4^77=RDfl;N1bc>Yk>Zg6dv5+>4(IkH42a=4WdXn1(P5B`k$; zlkTT+7dC{j1PJ1@<9>GHDSUQ(^=B39dYGcXA1&!eHG0ScN-PQS??4X-dsFpvO=DDF z%3l%G9g)AaU2O7tli-;iqLv4MVqK--1Zbg`wBn@TZnm|y&*G>YKJHFU0jTiiA$Z*4 z5thDVH^)!+IZ*ZE#?s^CG=-p=UPG7xsYJG=&wgGtj7%o%45Ugp&qPkeItwIs0lhKe z7@pl4Q`GP8)#3?=Aa1}22O-6V%m5R)8MKSMBcoK^gl^K;W0?$^X>lv-w{>TFqMUn} zT+R7d2=_bxN!9(8u5J=3_xHxN{O!`YBg z_IAsD>&cY8y)8=%!CAV zi>ir$>@!H_@J^nl(gCe5Hi#f$h79|fUa=YG`+9WGrn>J?XPBAK|4;ga)e=i^wqpjo zN2U`OEk~eBAn?!B&IHgpgC3a<07YPgnp5jZ_NXWpANA|T33H7V=nB)Q(3doAH5;|J zX`D0Pl*sP*HK{!imON13kRdY}cGDjhmk!<1E~U5xA)12YTiSq~uCZLyqfi8aX{qHR z)oENr4zla&0SFQV7!rVrD)1Qr7OSm-55}6U+U_!vkIDB40j773j{cx=(!i|7m#g()oekc{`=k=4R~l#$~NA^a3{GO?vrqUMOX;*S{uj?x&vmb;RDB zbujykweQ8YZNB8-PYD|hx4u{kBMMEqG*Bq%F?u22L<{5wVheZudY%I=UK{Y|n|fHd zXstYID1a7tQ6LZCctPV7x&-C|ma+WI(X33E>)xWivkxqy1&Ty$XYd)`MPO&xH_2sd z2l24!prOw;dkMdIS?>zG0ctIFhF!kjzdk2D%<%FXu5yB4dg|x-39{YcTQR&1-7xfw{>@beLGIMzeFf2B z0pGAjuYBF!b*&5Ipa{w8254a1AY{NhQpL`V-mDl$+LG{9jU_~3gagNwe_VylBd)>@ z5?5M0a*gD^a0dx>a|n&Q)VU(}@Rj+BDC1pT%@@z#T|A$w=+lb9CGNu3A}whmyUa2w zj`7iYkCp3$;k*B9C0p|)9^njh1^$++QKpTRTMc~XTg4eI`~M;BT;Tkws(XJP|JTg< z&*UUbaL5EW|KlhFBoHw|cxYx%^8kWHd{k+@pK6OSsdXrN8#4_=$T&;dsHqsm>TSSe4uc^5K{w}A-JgU#Me+}&9ERXMInk$Wu!}5!>IILAYmfDq4^ z7RInB;h}rfIxpXn^e-DXj2i$h0f$)&TOEJoPL}Q+TfO20Sd|y_MH)3%eWEOWv9IvJ zcSCDhZs0yLn-OzFb`91N-tj>PnXpQP5Dw!4_l5I9?A+K%|4PMCs>%PMKXa6PK_RA+ zCMfrIOUGITCS)%IQSD?L+>(9UC*v?00+lAje2;tr2Cmb?%~;k6tqm$}4a-wj?26M* z#eEY9k&G|rojNUjqDy8rq7Ds434H-f|5><+Z`mxRh!5nl5Q%4g#VRt7QWe`y+`BDh zydg#VnfMYlQC=mOM4zi1t2c~g9Fa0jqZ}}Sgz1%0%cNtU+}!?O2TGY|XJd{uhb?1+ zd&>RvF|tZM${3kZ9AMlQp*j64c>$?YC$Ph963WD>A4S8a5Nh)!F_nGXm6SRJqD;>a zFcSK#2Jsw+~Zsv@ga{skdl8>FIW*Np*-p#JX*P?!;jMOF;vgeO$uIqB}PTP@%u z@Env?WjrC8Fa4$kQc;QuF|YltjLCiOW`g*rIp%`It>j#0aAFSVv3LPoz?5NwF%8=M z#R!sxi4g}45Zppwco9Jt^g%Ymich(u@I56cK@lgANG7pxv`A{M@lc~p z4p#yL9!c1KBwM6z0i*t7y`}?cEaeq(a#RBRJ~UkIE9_a7P}#TH^T7k}{z|`OBA?dV ziy_Y~D5oqMg|G^mXyR5I4=9u!m?6qYS$G({(_2w7K*gY<1(J1#xx0h0X+zOMx0uZJ zVuJ1}dx?lN(+{(is543LW-8F;JfdgbZDET3l)1=~y0}3k@f;15BU29u01j0H9LyLN z4aD`kPzI)C#xe*)BghWXVbsRjjX$CA4s(rCc;k+0cc~2i^vQs-fyp3AqKT0#ZK7LUMr*e$Pq*kY26uF zOpraKaT8emdgW0H3MvE@g#jf?=W)!8=o{3!2bQuRs>5wW5oyd$Z)g3?npfdfh=d<% zW#m5f48Y&}i7-h&(FJEG{|DkUQ(1Wqmo1`H9A!^K%-d)h$VoC zKTpP*C%p~>U_Oi@C^=Cyp<)G_<#OYxURY-W;sE=R3=@=xwTt_md!WbWA|D z%s?)%A)dbXS=<6x3j(vioS_-g-T|$?n3w!NjatEup3!85QP^38^pOS>As}rDVu)F; z7Ll*#%leMME1?B2ADU=O4}#->)xT`N$(dgSIT}`a4r4k?(hM9B4oG|kbcQJVScO?N zNq!eb6~FD6DC1-i=w~=e0EL8htRL>Zc;5-_)Ffof zFj^lsE4E^HD;;%?V5d4u4KEpBFP~=E+ZaEC&HY`vi78QmqsaF^1tY}m(dT$D@SUwo zW0w?#fZ5q)h7gICxk2Wz3YuOk07U|q=$-@22R zh+3(iew|6q>+ehKE9doUp+OyHK>? zCr~FN9nfz@EHKU8@`Dl3NG66l z^*~H?7jm-5V!qNfXPz^&rz;e1<8J9y2rS|r#&+)`2>Ic!G9tjlt`}RGWG(bE+0+n@ zL`7l{t&@djY%C-?L6P3JdC6kLkqACLuflg?w&ksIyFMHXZPM8h#O|&K=ui3+#3(H^ z{X7PSENp$QSo49)!&XSq`ltds@&M&Tw4|!8xYeqvs!WpnV+h52!9cHlAEo7J7aKW| zbY2V<`-X)}`pDRAM9`vkNOGWkV!TKnj!i{v`UB7-O8auz%oK_&pymc|g59V}NpPT3xAjh_MVnDHaiy0Td#8evi2QVO zgrxslt5BcT(b6Pa(`^#-W{TruXTzgfK522J6s)yk7qmi+cZSXb0!{A~(YhU%M;ZYu zUXTqhp`OsJn91cKc;`!0I~sxE2I&CEgBq2~flis!qhchg`Xruw;Uc7Oeg0Zh2Tt^K zyDb!l+E=Lk#k2V>i!x7M))tT2-vc;atY3{-XG;&`ZIi@))?dXeP;tX;g35VKBFkib zf!UfWy!^IvD*ClaJBZY4%rdtd;|oXz(?#OAWSEfr8B((HG)c*M(nIP z39m8hIYQ5z74V}imozBiIts`k6k&Ap7Dkdg0}e@!s+@FEEH0!aAEEs2M@Z}AX1;Fb z+YJY4i{g&tMpUGN5vM4CU>Vp%1(vfRH<3(xK7oTKYz~Ex8XUA@#{ePhDMN98FoY0e zyO(Thjr`ucLYHLEnqjTDl+6NdeH9X)29a;7j&4!dPVMHBn*0IYr-4573#nYZ9@L9L z>6VKp)%2fqu{}IixIbH9$Z#1MU4YG2p*gtsu5;_L80%p45b4v}*Ijrad$tt^bDqB- z3Mc(;#4;OLmgX-JaQ$Eg8%0QU=0#!CjWzz~rE0IW&2biSvgT@LmD@`B4-(7BKdHTf|sjVP2 zs#%)%8h~7PFI~BUn2v5N@GZ_lcU_|v)W9}Y%eRDif=D#6NLPl+mGLu6X^^pG4du$( zq{YATBSLnqX0|Uv-|S$R!^H1>NMST^GiR*Alh8<*4+Mq&CmGmVntXUX9~M)sCW$!8o;8$06Ri%b=gKf)C~8`kU!!0^ zYPeeLi~E|z91j`<6Bb+TK?q@+L>Vs6NeO~wnVZ4o`3#v4wG(-|XwUnn1q|5_(OXwdhfn`0fbzxyaY4aeZ=ww(-35(rUy(mP@*&?0g!Nkk(1g9H1fT30{JTPg+9; ze-TCAbF>#NNgCfT z>jgy}rao?qBZ;w`vfhI+6u7r<*1y6+OUsJM7n@>w0iKz6eD3X4J$02SWd$VSM4zZQ9tdJu6+PW z!K3>M12d>u=HeNM?t1!JS@Dx>K=hz2?K9KwAwF8{sxp~#97vY1I4+x|Xf$?r&JZwm zVhizUkVKmPmhX9+zJiKVR}r5Qqspn=uHrXTfKn6-kSdaaa5CViAiZMFdj@k*1*gJx zAPwn82N^J}8#&%j%!D{;9b&Am0nDXbITV6mYb!lt;tzPv~2513mrF06z?Jwb*# zter1J;S#OT$G$0z&McmFpDy1j3?q9#J?)3k*+{#}BXXatshL|S(>N&7fnS;@!LoKN z>d9^U%r>BQ$*-T=1=LP|lLBNtm(=9QIB74bkUja)! zB1+hb5rs3M0S_&W9-^V8;b}Cc!6p5$2?A+y8o;tDnp9OjgGjq7k74h7n5HuvKm$Q% zeJo$;$SmnfM~;l`Kv6OTi&XaoO}x|Nz@J4MFe>XY!axgOjuCZ;*r3(oKP#T;wcdR~ ztNen7WJXXHmw7OWna1`t7lGK+$ZH?SORdQ9MMcwTQ$J+Fg#_EBK+bWQk|-q*7}Nyw z974)j-77g2--|GeC}{uFRn59ibTJ*eu=G_7uY_T*ok(z?z95bI5^AVgGFJuFEzS-k z(9Rdp0PL?)eGgNf=VOK=X}ye_X`Hv- zTr58E^zBiZ3+em&!P{Tg{_)FAYPS5@4n4Ygj-cP)(AGCfP@3F2Oq7R+jHTnY`t=id zTIkP+60x0@OBr&gZRv{E;n{&2A;qKd^9mD-t+`$V9ttgGJu4Qsj)0J6XZy5fiiJ&j zC`WokzF{UgbMO-f9Eo%o$ph81X+}C(QzT(F%DqE=pdhEGeu^px-KhDcqSLlGJ+v)O z;nzXh?j?Ny=*6iYcrKVL4J!~k4`we-FQBSI`c+t#v<|S6`76~&7TO z%JLdB-ED$ioC z!(V!U;Aju$VPTLyX?njMby7@}riLm75M2Q7_R(Skt@&0N^NFYv9ZM~_SG5jf(qLw? zktJG%4$?#hU|!!#zZRoNs1t`#OyD4>mgKJ*$PZ(%r$WQPzhXIE-7n+yeiWb2vX!%s z@RO@e$j3aq*70;o$4e@)2G9<#x1iMZ(#DaR4oV`B?01m) zp;EI4OQBNGyUq&GUhn|^msuiXPDc=Tu0U) zhm3QW)Ko};hkmFoK_2!{eY z2lZksWOU6vgi((6%!kvbT**wxTFJ`Lk4;S85W=;K%+=bTQO9%!96*uBt5|Fwc;diH z%#N%3zV~@Bb*jV>n&Y7<=4hc8OJ@OadUZ8@ zGnQIg@!1IpuGcY)3<;JJ+)mZ{MGQV6hGE51tj zV`qQ}!Ma1s>aO;Cg+#7`av!Rz1)FBJDr02(U$x=T;Mbl-J7Am7gqBX|4b$o*W<1r; zzp=6NHb{D2i3uMJu<@7P%i&dS>$k!0w>`D+Jb^Osg3LpT9b~rvmQtaQwK6*xnn0lV ztBOM3W-&0aj7r|&^_l?Sp=6&#Gf=neC~900tn6f#ml4Hhy5wzVn7-8FE}k(}d_Kg2 zRYVQoFZvuo_=*c!>fPe7$n53mMjfePFqu`e)YP zk?VdfI0@OzCz5EB{EK*UpMzp zg+b^soDspuNk!_RHN;$|GJfu)iIlq*bA6P^hZ+t0mj2lyfoYWd9O_VdykKB(Z11!v zXqxKN8pQ_<;?`Km>X->$`wt6Dk>sun~Mj?W-DgWV;L_zuQW+ogkeog;L} z%|@`Z=bfwO>F(+enZJYhYI9pNlLRt%5F(QB!LSvVNR*dQ)1p2iu;d#588yrFR8*2Y z6-CXqiC5wt6!j}~!0=_+6o!bpXqjqA-*7f~GX&Dk@+Tt`^BzT3(K6y6X2k)-FyaFr zR5z8>ysL17%1J#fXD64O7hsBz5fLrP3l!L4Ie*kLNy`bz=ta;;59X&=3FxoDO+(lZ z=2DeE6oOFQZmh8~?_v*;?x~$Ty?Hk$T_cWxma(?X;+&Q;jVmRD)qW!`sd*0CIzy$j z*04cu5#`g=?4=kvwARRP)r~b<+g=Wa#OQDsg5Wx)&$jj&HjI&)#)h6&{U^{2a~PCB z79QbU_7HeTAt+!vO8zfiQy*U-&$D4Z25p)YjVEnNXlG<;1)$YP_v1!aNJZi|_@jM* z`UJNR7B@|eCOX+DLi_GhbHy#R%(#1wfmC$53mu?FBbfcop%0x%7^=6BE`>!T+F7C0 za3UKn*`bRcIT@c6=>iIf%X(CS(c872-YlZV)0=scJyAlkHvgi1O#M)tS^~fk>jFUi zECArLk(({hPnkK&1q&q3?{~4~T*MM*X@wMHyX}9w+J6011>`oIIm=35Mj3fTN^5-2*TIu0KMfgaBh; z;Xl-B_7MOL$|t;xRk`Xij9zgxY*dSbKmuG^Zn4Clo7W5^@>t9J7wfruNTEjXae92t z^FWJdQLt!iiXKiAnA_KgzvXQ_Nk7`l1RvNgGu_c&ZFg9}y9GLEgcnzsgz{M94R>DByRpys~3{`ZASg7fVr|gRk2P1+ntX2nx1fE_wz5 zg354^d8bXwZ>BpHHG}qPJxz~?Bjhs<(%nqh2m@#HwjF#7vZLf*!zgS^e9^UJM+DA8 z9d79Ex~1X{p~7g`ee#D4JdJLM>8rLg#1eNx(8V7XXH6Gj9M4qa8O;qSWJQz|yMO<2 zlzv*Rr?IC}Xno7mq`;;lN^WV$sz6ziRYqh1u&HtCJu+yxruG@OX;BOWdGO~TDCtN@ z(e?FAnrA7VPQ|2?sgkX=R=s`<5D!~DZ?L{mOjRl&B81>KPH6V=@~0(mUw zwTWW3wMkWk5T!#vlWpM^j%dGS{iv8=CBgYDcaPqz*kTEHU{V4-988dR1KA`Sx)3Wp zf)6<7qxeo8yljWXBvW}a4?w#o=V8JC#sF|(y@Zt+hvH4`=nA|!3 zJ~3u<^6*{^D+^t4f+r*U;ZCZawq&x7o5>HIfV*u|5K!BvjH@xUa)61UHDimXH9nep zQ7sI8jE{7PMsi&kFk0g*)@_c`pj@6=w0U#^zasui^vh=#XY$q04FY$#*>c=i=I;KG zak4qs+|v(6=?_Bp)NdgpySc&kI0f#4Y&mc}$gJY8L#_q?5N+iQx%3Xu61oT}p~n|w zXh?)7AO?P*X~B(EU?N^z$bM=n8MkoESHZ}7m}*eqCMiDLB8O+QzGkJH-U-T#uKgrm zOTQN zgAz!o=$o34#pR?eJK(`slW$NL_(npz!D$aAe621%)9y5$H*+be#G;%y;Cf*5ze!Ia z69vykv+jYsCPBc?!NWuLW^*X7w^~B~Kv7N4wJ;8*rBNy%3`)*ZFjQyQiA-OvvE9Wy z$=HHlAN48el!YMip>phes0o-uVcZpKu^KIvRP7%L-n3H3EJ$n!lQp-q{ARIeib{6r z6cwbSnZp1{c+^2Au(e%*9+A9SXYVKSjsoBpqYHd;%?HgyX$M5qkd5F#5zh2Pvo={X zkbK5WR3&>2JyGllCgV9lkh8~;N5$!Y6YI#j5F~cBzk(}kRY1JLLAlm08}l9aK4 z@c55J9%$)UaX~wpmo#PB?rW|rewi-po0kjqLXcs|&pVNrp@ zLnfY=bAx1<&2it@c?vS-q!yid2qHny%a?;kc$CV(D90Bb8xBqRNaC0ro<`)4hFXM=rO|mjOz{NsAwO96n4l5F#BfUlNJV5iNXQuvjj3LZB+zoz9ChKD zieiPL^U88Bb8gvDO%FLHc!@LLGxh{>f2-^Kk(rb=OjbE@0BM2fp;9Q@j-27C*b56^ zpNonO9_np+o|2{L>X?92DL6M(tfD%QwYs;|8vO1jW26a?jWNnzv{ncKFt>08TCbRS z>OZ{%7o)vh^&pJmO07|4`eP{yM#UhFRV%llq~I;&8PZ3k8_pj#T~UIt5#C&wz8 zZL^*6jNO@8V<7&UXenRCgmH#q*Uo00y4c@q{7vFJ7l%6AyTKMzGA%7FEwl#g_A*Xh{)1) zt@=na9m#7*wK|FzYiu56p(tO}EK1X*)`@)4mL^kY-s+us%icOeMAcPgIUJ)L% zn^qGU2QZ1FQLTxaR6V8-*-yjDfrJaQ6?r#h3H+6N1@Vh2?V{tAk3h38R7)0V(KeaU zqac41J=rF z3NF-ZK2%U#xv0{5f?lIfFldvrHxJKia>6MPhnCTcqsKbFIuJ@IAXvSESv9X|Ty0CW zjVl3c2MPBLKpI=$SYfbu@4F|Uaoya&go#Q6qHGDR!J+MtToj6% z>9!4_^q(A|CM$V&wV&P6fXSzhz7)GF{F6A48pc4O<(VdeOq^XfLo9KcJQ}fV`1lMp z{*x0fAF>26{a?%jYbv_6$&XIeLI6cbove#(5j4llB94g&%!2^+V%k71e;Nb3Qir;e zq08;J3f&`PF>pT72kEr}3-yPi!@`k5(h!wKT7Yp2QNQ;-X-y`=Bm;S}{a!sOKH(80m>wj7w4Gijw2#Nx_8+5*E$nj_O1E%lRYo{&W?d??5rB_fMgB!^G}YYiY=6oVN6vIFb^ z1f24{EIBMOL_6E0k4XQ}W_g~qko1=Ak&n#r7O_pow)BqO%2eMw405g;`UzRB0NJb| zZ2cEp1;oP+z&*?Y$yHuEpoU&N^w);CwE+oxO*h^-0fe7WIHwmC--{YE-jrTc=mkq2 zp&heT{ds%ANfak!Wc@M38#PKE#oNs)1*K`&au0C5gnQ(yJmH- zp+%wKUer7%h}-v7yBE^@`FvA=MdK+hog?VNB$nNm$mNv~G6LkoQ?=&wlvfE3NvRr_dr4C4KOaGO2=KMxPx_XKiIN#5lNZ zO*Z{a1G%oLn*TSacj?p6za-YtCg$RNFcryVbVsJplj)(fFJkirIP;v3A?Y?uD<>v` zNEt%KeC!>>VSy=0MePc7YN^dL8>T?P&ByUU(?|M}T5~>kMCi{mEfEtG?a~GCc?z0H zz!Kx)+ANU-R#6>+DB!g<8fiyK`IV_YGQC};YU%BQhexWV-B;WH1b!kj0qI4*&75jS zcWgl4wmy&TfMb7_Ej&z!%o#K#14};@pdZ+3BZ$B=ZL_4K*OCfo7$BwiCFME`nk?R$ z*Vz9qk$pTmq+rE<=)tY{Wd;~i^ObFD%ny-OMo}0v54S=edsfFzJ%~D;+#eFe6RmX{ zneRQ>5nQE@Nflvq=^^Jymc^%NeUDoeV}&R}gDL9_`i`YMh2-W(l{Gn>#9m&1dIQtA z)~#TSSL?U>1P6wftV&#$Iz%V5QUW}D)ar&`D}f7MDlEs05uS`NJwla?Iz6FTjI*Zk zK$m{|Xx9jr+VkmxDt$^4rK^-%OdoM^JX&xvv*Q_rK&D1KNPCt%Zm%U5?4{)V>7*ih zPMz~q@;OiEOvl=}2TVh1>0nt{Cmp&z! zpbFk8*3uz)bIsCA*XJ^i1RV3bl+iofjvu<)6lNY$zmrR;?(XwCG)rCvm-8p&iziro z6@Sp)*avIjgP@D8XN4c!5UGtP;xd-#GKwC{HpqA394C=cQKj>Z$mIwHbr1U>_A^BTmY}XTCb-5CnJ5&*StEONs!t9%61boXKK+Fl$No#0N#p(1+(9Y#Aa#%2ic>=&mqg0QkoJ z)|U(e-4amBFE#?n7aJtcfr1J4WIK^s@LT_pC>1TWyhqQ3iwqkGfDX<@pxcMCF8acX zg#h_d5&31R5Kj^x1BF6MWDP+`lXp&Q7Xy$52F|ID?npowOFa~V_e%N!=6&!Zc(%7m<4sP2=(B1=zXFM^lF6g5zM7~Cx;|E0{o+!Az0 zKtE!MbtoU6z=u6R7uvgJ>SFqBS?tuj3=_9mFowCkqv`4{A7<3yYda3oe$X;-adAm) zmfPuzo2@!5%U>0WzUd$0T?_m-Px(`KPX!i77V?tq+dr62I(#qU&grf4fYd)Nl9ExQQIJxHF6nNHToi`K-N{6`#W==oKiHga-))N8!E7%B^` z2$g(c;0I;WYjV-#I0vfJ#HaO}+Vrb-zgBiXy^Y7_J7j?Q6bmNn0V|hRP6h8(zh>jm z(NpQ4CLc{1P)RX)p*Mj-EiTNK{J&TXt2yFYvhYMdZmcy8DBHfwN*Zh$O6G{B(CegV zcRm)CQix0z;B82a0c=C9Yz{4;vE6_aW$U+Zz=i-1)S#VxfG8207vycG>o}kSsuu(p z(=|=|hQRZXX&e6Jin0Kzp2U&?>I-t92OwK$m4DR%9^$g9*hM36Nk6Ys4njDN48I0x zG3uwX$flqbs5*l39>Ao&)}s!}z{P=gvOZ#mq0yP9ffO41}bRZ`eep(x`W1m zKBwRkv>o~(Iz;Jtvp6}6Y1@=PLoKnGG*H#NL1AE*O4#wntA#YIp-yg*K_c>WB9r=j z37Vi4l+#*;hWU?Kwpz}zQA}|{^l3X_s>5_*W*q?38eHZx3)-|O3no|@UzsPV1v|55 zMX*H=G)Yoa_p)q8%&5$kCS7EA0TiW55show)4|Kq1qKnrx&p~EGll$t@N3A%4Uv8@ zBql?05&#<+_3-M3j5MX0f7_PdWU&_&=ZatKtx&4s>KLA(6uH3)C&1x#xz_dpM*q}D zc1ib?Oax^ZaAJ2s>3cL~4|1!v+LlPNj|oX(`W@vj_6QTR5+iFQrIs`X{h)vro@#he zL}*fweym2n&=(kZ4{R5O{L>E_o3C@%pIbRBL^+ZcK=_cGt%B=JPyt=w)}9FF9~mbM zsAThk*#oWPL2WMqWiVEyQmxivqCT*xbDV-)-}tHc(J4Eatq7yhS(v%K+|js?V`yGZk)MN$USg{nld^b&E5 zu!uGZL&0_I-(hK`P<~7+(Xa(TdtbNrh%)O;aR3krXS2p#F>ttztabPZRvDBmF|7^7 zNzxz`k}>M6B1nMEFjyOEZjk66Pfh+W_%Oyq=8{JO(Zo-4B|9QDN}_|>Xm3@g?S?f| zXZ#eziV!V~O$cUlM{kyrKxmJ#Js=?4*cJ14*m=7Zw2aK4{1X9|u=D}UKOCSI@p&#& zc~O&Na82r>^Ydj+CBUN!s7)|s0XI$4YFLWVvpS-U$=Fbi7)LXJ_K<2sNTb^UyF6af z+lt*+hL27l=&P@}fiI&OgLoat+EW-vZErD;ot|a$1qJ}rsJVyKi*_GU`(vPH5DceI$ zchQmqJKUSJRwF(dOFl{%yy4eo_QTpr)X~VHlj^7EKrUy{KHRb-5UOIyjLM^9h? zB7k(d^q|@FSvu#=>t2FK($ad0S#jVVWTWDjl%UI)9x=rJ1|_K(#23l4Ov^p!U&^sm zcm|Hu*-L1vteHuPbrn$+h9e1l{EFTBJ!!yAI}xjW5?;f%@sVqNF0rZKgL&582<)M$gDtwl444ibBlG69=|o z8|=BY*u~z9)yBqxV$E|$b|1LG@~Y!PRXoYl4Jj89@4_`C&+rRCX_j=-0?heZ?J8}>uCIs8L&gMHac3#I~$ z%ex7D=w0is_e^zQKA%*X@=DqsE?UWA zFR}!?pvn^o#THVk6#yE;VA~;)U3xA6vgmY%9n?##XqJ?~Xk-ba#_lJ-FJL2M;5NS8 zZT$BFlKVX*8gr&vYe|ccb%ImpT6%>H!q7?z(pE&CbvmozMpZ^5j@4oItR+oaPIsG` zc3$VroaFNrTu)V5h{u?XSa=bI%)Ih^|0EYjd;7v>GpfYRX0zI?*P6`+S6!CGFmyvC zZR&0|gQmbnQD9))4)6BG0t*5p4Vv;Cng$2tI(L>ExLP+D1Hcv%PD>b6ZJrNF^}u|G z4&APkG0vVNzAEH01|;o;rVwTMNa zvuY-s^ir~sbd~BmHC_*F`^K(vNW7bR0;kk^ZttQKutP^g;`W%-$i~!Pwj)= zG{6-kDPJow#3L+T@JWw6#qE%Pnu#Hf4Ks#9ng@u}E;L1YFaw-7HLQK(0rW}>4aJpZ zE?PR-uok!ET!f%1$t8sbInM&7S*2_LEpV_-mRX2{aLok3&Hm;s8)0pjfdy1PFytQl zfXqqo0=r6Boe40Ou7E>p02WO`B_UV@3Mfoq<7@*C4=$kLKY{j{zP)-ybTZ+iKd+br z41#7s06j;V-?diAtBAycuFc#$N#h=Jl-b#up=4`dQ6N%Z#%EeqgJ8Jg&lmJ4>HP1{H?j#*>aq=3Te{0J3xDD{*FR9;!yg9bxM458Kz zS}xn#`4Du?kIc})UAl|)Vdtu)qUB1c<%+D6;DWSMtw>yDb<%rhXa16^Sm$a)tgBI3 zXvYJ5B1~cQ5sW+=W197u-PO;S2QrHo02;4I6`BX0gw@UJNWN)s1BB)jSSx^jdvEe!+fp2EG~zfrQ>fOLB5cmf#}fA({c1B2Ym) z0Y&>2pk-r7`Hn^2B)Z_aNpzVN)7E;OgC`)0;pJzxjimU%JQ`8*7KCRg;kgT)jfF@= z2aT9J6|1QP-0NMip~P7~QGI|g622Zc0+bw4kN7K2E)Lu4ov>Z4g~?8>jX+hmvEjb{ zK1Nyk(lfSnvY1$C+I%5=gsr zfGSG<0vjD30P7-u*lg;^3Zh8MXnP);$PKxP*Pn$YJW1c%rMc6Lm7Ofybi0}14BUUA zMM8w##%6LFOZ#|O(vH!jLIiDIISEM&kDp`)Soj>3oD$|?LiOLi#&F40>YD-k6jlrg zmG`+2p2FhkaB5YGx#1AL(Bq3w*EQ^fuf&7z(M&x`{lP-1(zr64v6Z zFe1{JmaYZ$H?$W>9EcuA%1j?s!P$RYG8+K3j%?xth|tb_D8Djx<%rHDJ=*dwEl)8m zf}gM4#;-sgZvQ3xIc~{H{@xnsz)}zv$sl3fqH4TbT2i5U$%pB4J!9JU1r;WzJw&R-_Qc3X6Fon>8uLufnhQahqmn6 z)b6=he^qV}S*eBoU>0gz(hUSbV6K#jLl^Uk@Ha}xDrtdJTuZ83hb){5V!(7%7*lE- z-HFZUFQG@OZUq`ezjTI*EhsW$-3_(#QdWLhCfempfrG#%%f)(WL1Lclgq-yKUCC_f z2W=3u{yTnvB#Ts<#iJQp75=Fw>S`y#RpcterY_n~M%&zxU{d?ppbvsB+Djexj0Kfh zQr)UMcdX%v%DYgLAr?&c@9W<}=p>3yG(2)iCEbPvM(nFv=q+@`Bow*-WFhc&e$nj- z^3tqAqD_#YM4Upp+o_cFnr7EwH=_Fl1Cx|o8~bpe1ccw89l3cjH*&ulvG(Wu^7AHs z0Q`#3jeBR88XNlv6nYIqu2-i~J+_m1Y6UOQ$gcGt9{WHq=No2Oq?PB@$Zq{!Tl{V) zelL(rzxp3(g~P2LDsSS>o2b0`$tH%55I!sRosa8gy50Ds%`B#Iy_>p0T*``7?rUcB zapRv%(hq68#Q^TppAQ))#$yQ613!Zbcx7wi1zm}8NlnvaJ zVX%n02r=J@cf;OlnS;txWMJgg+~Bq8IMW{}S1Hh?(0R0_V*+#~_r$mOAmxJDT)g`0 zySb-T1r{>9+wr52M}aQt_@GAb0?-Er>MmVs_OTat+ly|Mxn44& zixuATQD!MtW}y9A)HA)?C8-q+3tzkgL+CBQRcFQigiN#?l`XtIu^Wj)Pxw8VjZ@om ztr{6lX4Zl2YgF?bxS=zH-q^`A~%&x1-JqrVm=9L?u&x@l zTIUwNUtsut1Poq*vL;|^TL!t0?+6fC-!O@0v)gT&7LksQu1dso;VXc#cod~uh#*0= zyjB?!{9JeytVio8ktNxhyV=MYRLPwpO@fWJh{@mbSFMwS_K3g(jS5W75}{}*ChXj^ zL}szQ9i1b69iSaVL#jV{iPa^PLsAF|jbeI5tvJYq+G9G8S={e;Vuv_V4h&d7Z}rz2 z^UysMobG;BBbJG)q!ofL`o_L1+0__Ylp5#_G@E*h9LoVwIS~Y=;(6G%VyT2&$Ur7_ zz#?H;vNddbeCJRRvYxa8peZI+qX&%omPJ{@9qA`Lrn(xbyyA)~BaTV8!P77hOJZmak4oxdnAIMgOeMTx9s(7aAw!c#S;M-&a}R_o zS7^5n9Vc?%8(F*E+@+X{_aPb!zI8wR1PfveKzL{{W@+PVw>v^=fi=oD5+$$=-DQ3Y zxNKQnSF>tnx7kfIdR^olhBIAShxEIt3?K3ngPhxBFqfRC)^kN@Br(ZDW#j z42lho4GJ9)%sYN#kW&p-upY*@t7LOpzmL8d;H<$hZHJhgu@iaYM zO%PJ)cMZ}n)+|3t+Q;+7h(#~!X{#tgMbkv(?0IH{j1|Mz4x}>?`s`dHPF)zOplPoz zntTxu@B0TJev7w6ggWCqwPfp9wK?NbLvh;j^ip1M0SC&cDjtA^{7RGO4@oiyLj5JA z6TpJPMzmwOMny{Q3EMkyD`2!Ds&Bf}Y%@l<7`6Gg-w+)mI){z6U}A3BT&~0K4Ex;U zdR8Dl)v-8KW^10YP8E;ntyM-XL>B`HYkk(GA~vcvvi2(yrg_rJ7^EPU<&TEf3|APX z(*5KxhhuopPmuoH6g)~`MddrSq-S)%>_Rc)cRBJ8zr@JyO)NIY)>vY3nK+6V2k01f zlGaP?n?2{e66S8gGW1pRJa?LcN@n3S(sqStm=U$}CdbC;8)V?lU}4N^F8x-Q4m)(O zGtp8`^KK~pg>o4**m|G#=V+Evby+TmV!iWKyj}z9Oxrs_XDxjM!HIQ5s|vAuZDc)= zpMlv>5&&#x{9sEbA)ydgBqY>q<3|a+8dBxS#2}7U1gM+?@Odj-#-R$Kb4v$Ug@T=e z2VmIQ+)XP9+>J$If=a+(e$vxM9=Wj$i5R(*3%({oK%`Pkfu6lJFDSHe62XC~vIt>@ z1~HbUtEHac>jRS_NJfs33}Rc@xyPU=OO~`82epcV6|F@ zjcFYr?ENOZl!#BKNs|-Rh$mS%f7{2OZPTE?I5zimO(MwP7m`J5VQ6@uZ^d-~VSantUBjt<3&uf>oIVtKeGuWbF|J2d%nkIU&xS-cr3 z9G=BfaEv;MgB|y`d~;mRQy{fHqy=0&JhwnC5JX0^jLIA1N5@K+B0OODGVEY)OOiRv z&KmUe1l!~iW+4rZ#A|(Ww;;G<;l$DMt)(~BlH}mM6@Kw0cXifz9@tn5KE%~!R|+)5 zr}&rw_(TDZ>X~GkJYRHMaiSSN_?9$Go!>|yvke{A{}!Xa$2S$QA-i@bBJIRmfGCh5 z*)N17EWVSM3iFIHq-OCOMw9PHvHT_IYDhgZyJqAWAeK)GQX($jCg2o%eb*Pn(Ru zrOn<)<0WmVLb$UauRvIx2UOSiT05#MK3axPuK1`*jzCjG7nl*V6~+cLUGe7aegoFL znpr3zA?*<0ZH7U9vaZX*>8#qc&ZUomtAM*01{#nBCc=-Xx~BBO^b5j>2|@nub)mcQ z0^&3h_t9?$X+W?;9Ig>w4Rb=Aw_}Lk;*m(n2E{js(eSM6wn(-E4kLNgi}`HR6R)F{6Gy#%#J zAG1h$3p|FYRO=(QY-+AVtB@09vL-0NtFI?{i(X!yfM^RBfs97 zd@_nE1e3S%(8hvzD(LKZ-FN(G`BfE(9k_cqo(2<<#sAjR9ko2%CZD3V0@Tz0fXn<= zLu?Jo*(gCW)~<^`HyL+FaYdLhB+f$pLg zSLv`YX4tCyL2SKHkH1uN*L4ua!~g9bV|e-lJ+2mnQS`XF_a0Z%h3fBAvS{~r3QfE~ zFCq6wij6;e9oVyL?$M5J-d+SAcg`a4{hrhh>p{@kSKyTK&+|G~GG;BbE`?%xjuo%& zU=GTbz?xl4R?2OG3#L^^BP6s%)yC;fO0&ZIOzA^ncQfkHtP=*3#4A|h@65-9O1;`E zGnazk48^i+*vR#eO0NOjSU?41IIF#g{FbqTm0?A}3ZK z5kh;4CL=o&O|@krXS}^c>0%lNGwMwwF(!YL>Z8*##faxPXj&oxLy>sypO}I)4SlNH zea`dTPeR*+_u?dT!FdnL$K(Y_Q~>{6nG4#1tn^JQRNoAz1EdxL>``1j{%6N1e>!XYebCJG;w{I_x&) zYxG?N_~)5%0G>*W4$KSg=^)lr!#smV4P-)MZ&PaCWr0b4R;77ohx5`r`c3*E(}*Y<&z@)qb19^SFr-_WW*2L! zCu{@#i=Ozn^>SWpm9wI#&fQSVe;;VL?|GnIVCB0YP*3M@x3ERE;%EJIcVaIm8mgF) z3-VG+!eGvQ@rF4(Q`8j6iM0Nu~w)J!>)b#4aY<`UGlr09?hkwW%k5L#ELSqWm*jUYl zaBT_&Ce0?Ykyp2#u1y9=Rm@3DKX!fwkaiFSuMa|_46N!>SelP3(XZ3z;k9vPmaX zQ>uDAa=SeFZt`oy7Y3IIzjY%eqNSF+ejwxTn+7^zUliE?9$Q#m+*Diy<#^0kIsoS?pjk>s}w&kMjp_APvXmPI8P!XT2n%{(3>%%;jDH;-W{{@S{~&8_%{iSFMu~4wEd4&5ZKp!hM#jc=?2b>7jTOyuJe#%^@mG9>X^ofl zWq@iIOE?CSWAj#`<@y&ZIr4RJdB?HUh^$$jtnII|>h;*Z*I5n&gQ~r>f{D%c>RJ^s zZY{#TT;G|>0>Y!Qjd;4mpQ-y?Bbz>&&p4AqSZA!tQW##fOlKF-Xwu?bIK*24hq+mN zeWTev^b-3=Sv{Rr*Q?)ekg+`8Wa+;yWj@-+c9}%p8x^UuW2=`SDuv7U z5NxNbVMW_n5ccBY4ND}6HxCR($Yc_R%9e~HOKC`FBN?J24st8HK5Ek)dWY76Kr6TX zWoRKB*o$?sT2=!k*Dfm%WBbVcfNA`)8RYttJmUMJlJ;kh-NdvL;S+M}$HqQb!N_ix zJ2vUEgmB#y%)dbv>fO6<+8w_ZOzou%F^ne;7@UhP|NG#);~qL{?Zo62y{Ila^*2v^ z<-ouFWH>Q-mDfEAsQg)9d6mpPOf^;=PuGjUPwwGq$)1nhG@i$c7CrF4o=86Z#@9@! ze-i~fyU@6^xVX9Frin#wvj2U5;rPVniAB%8_t1ANo%#4p6XUsT`Bv_2JXko9SH^EJ zGC1Sxn}D>kd9$?Hvccg$nb1Q&G{FgZAoV1^0R}|7$L7wAw0rkL4p#P~yppMsouPm4 zcK(A~znb@2^#-kgAxYf_Kidn_aPj+J9Hx8#p|_>$)3M#L|CDJ{RtOzxkRBRey_2?Y zD3*l;&MMF6O`wfe<2y;Ny*ckHM`I!G!TR`?yqgYn_D2}XOOj~}k7t}?526AGXEN8H zNr>Or_*k@Db>EbCO>E{Ro1r#S8F-^Dx;s9>---|c&+y0pTlDCkEUG|Df#Z+56`jT5VC_F&l{p|Xu zVl3D8ot2hln9`!2tO~ytPO%jT`SqfglPhbT2|9_GzBApk_0cmirW6Dzn1Yp(laS+? zZa1fbN26zYM}?O=NRKS0*f5{(u8%6eqtO8JV*G|`*3{vd9t~Bau|GNNr(zbqVkr;4 zA3gf_&yMIB%zgCfS2f@M*6c>%2?i}GWP(+H@o&)`SKPSr{~Yzs*Gw$>)#&%W>TdY* zjnKlJ`(O5%<$pF^WO30AH|~4-&F{R4%hwp=ewC-2^Qx+6{Pe#a<6Ed%1HoA3BE@mw z@b4a5NV|Ue+zN5`vG3G46U#g0gY*eYX4WiODfFzAOh^T<%41WVlvk5ik_3AdU5V)k zr44GL;y&tigpXCCy3GDBMkR`57nj8f_`3~2&HQhk6vn&T+z@cENo7{nt(h53mvJa@ z6KqlJMf>x|cL#sg1EH*Lv8PSif<_ZzDjhi4N`FNkL=$#zB|^Mihsf>rf8di+jK1zq zCIk~yp12?1_%a-R5EDcO2Q3QTw&`{IEV>h#ASR^5t2Bj$E8Hh;zHB#vgC?%Z0YY*c zEfn|o2PX2`=1Eai=S4R2J-6R$BH4s4f@<@)D5!*R7y;)g0HH?rMUVVjwCQWB@94Vh z79`PUR)1jsuddiBimLqnqnBQK={;PEVyxVv*T3e08Nd1puAfNQ&mF4vJ@f2E=mlA;vNt6g<)CtqnQLgzy23$eSv_wL86e*QbX>s(7QDa6*Bim@NP`HjGC zLzY!K;V05ky)?Gz1XB;jx3oVRH|?jau#KJ@2sv$+K`9+CZeU}5F!_#-PVM83v3sxY zy|KvM=%(O zK21|D(ZSIv1v(~4Db!?Pc!55P$3XyiMpj?~5H(lTPu6-{EeTLgVNH^^*V_v^Y>NWb+q3+uxhyjj zae+DeE_NNzO@2Z>Y=tqQTtt+}+$+8d?hhI6aeQ`2>a2395%wC^J9%|v zzIX_oHE_?=J@-6NKfzo^Qou#&6O$wqZ{A{3t0W)IN}Hu9#N$c&Wx^yKL5w$W+Bq18FyX?~d zX^~!M7>L{fXX>y67Pup$@ysNr>|liumA#EwV-@y;MFZp7i61s^f&Ojy8O~?hs>87CG-HMSV0@E4 zZYyBXfv;L(@6vKXh_uVAn;`NkulA9o^o3(RtFw6DPQ<1yfG|>BW)cKb7s8FFXQ5SUCcd2s5MUPo%}on(RLaL5^uW zKu+25Cl?wSYo>vBycbEF+8(S@5Nf32O-yQ1OQ@r)_xka1Gu^71_D8DUk9PYr`v?f8 zTKxcp`j|b+;Z3Fr(cedIgU9-ZLwwW95bK7PRBT(ltC{u?AO|X|Fr$p$X1hDtU5hQ# ziT|(iPq^CVuhQ>hmWZS=n3~{%YNm1=bQ`-Jx7z3E47YNnO&#(QaF~UEt}5+ws>k>V z?Ip>8>09aDU6$rYA$okonSh9e;@s6&MG8=JLGoiIrLnZ-s8kh{&f&fN%c9;cy3s7ZPk^glaeSm6piZ%;OAqF-4LoOmRN(FnBu#-vIo*jN zr_Z>|)9Z02;#(vyW%>>!tWkkH)(5#sUmg&b8o7AXLWd~9GQfYVP$E)&QG1_j`pT~= z&j14@>A6+C4h2TW7o42!8l%Jx(hzAobZ|Xp!}OUL!S9O$H)VOO=BKUT$P3cb2!&`< z-^2mF4@1MA1I*4ky(N`Xh1#iM>St{0y?VkAJl-IHRDvDf&XnrAmyvJBgHb{tPXJZE z3V-)Iv`dEa!Zy2^w24i>yq)Y$|0sF(C@Fuja_`hyP!FF7(doaDCV_{t)7eLJ6bF{x zNFTErNo+KSXy9ab*GF@(lG}UDA;l9O>$rA{*y8${(2u;my~_S>!}pusC)(p1?S#~SJlKSvhCsIWP2rS6dO>WH{W%iFweSYP%|7I=xnh!NF1uoXYcghKE{fn z;WWgxCs-!Zh`t(@^h4eR`~$kmj3IP2Xtx^TRUAK&;|u6tn|>l}2c=nZ1%*`3R>A(3 zrchuetWQ0HYH}z}aiO7-PN2qX{~Iqy)+sEWhXBZN0ZIp;PlWT=u;V0Xg@9&JlcG?$ zAvGqh4h!?Z4YVj*wx%JQid2>msT6*Qi+Q+pJe zmC|n&65C1^- zlmDpt{Yr$&M*;o>)$U`CarLXN2-vq<%0HdmE@JRN>+HSR!ys&s7=#E#hvYM!a z>0-%|(KeOVt8_EpUS%|_S92{DL-C4o*HcckuXSOd(BLw?fBKJvfzjaH;P&FkGRl#S z&fRf2aymV}WgjBVZRmg=@m*J4Duy=<4peU}%0++>OG>b>cIQd{C>wKGn4PzXRQAWX zOD`8u>g3iJtX<-R?yv_aHMCKy`k+CA^$=%$;#x4sjG~iP(_h0A?kp|4h}=P*QWCji zCCiTc3BY&LgA{m>{u}T}3Jyhgv%gRsb4>uy0Dv4LEGJ46$U+yt>_hT&ou<1rHXU#a zD8s4Gbfu#1&W9w!cUw7wx}fDPiiti4z9@(Y| zjGHs43kuQ4$gA{F=4a0|Kx%i_MPa>^ok$*u8VHGri4UD(zX()n%MC$Qcr@sVk@38S%bx&c2S`RwAYC`I$Kq; zxdR+=95rQ7V~D9#h3X6Z(#$Kxhv?B(2-s98R@N4lL1gR`MJ2}yN58l|)UnDI7b(3v zAg|}K5{*D6nCe>OIzUOcvNO%{g)j(((lkG6dZpQA5MM9sGLs6YJ&k-J^b=GrDsN@YZQ(Ov^k`ED^;%k2ue1p(Ylj94pTJi({Ls!1)G zvPvlhCP?$9BzHDZmHh!f%48^pgAKCsED`90Xb~iB5!T240fSVUbRgY~2OO2$oL(cU z)srEU9EF6eAiW2j0n#-B1vH)<1mrD57I9{_U&-T=2V`(mS2Y?zvY+ppI!Nsea-I+d zW8Z#=J={=3i^3vU27!UL5KNomAUcGhx)0={L+0d26bx*#N$96dzD9B+XR|&TRX{GH z3VsCtR3bAiNE96~5)6w3OP>bf*0`;!)R}ykwM}Zc>%MMeWZnGSFFC71v>+Pg>=VHg zi%Yuc3$rQR;6Hei3R^)uoCR583j|c=BCn*Poh{^#VV(p--ztMIXKRf3)U!d06N>@T zreK2G!DkWcooJrW`GKyINDzNkP9)TWgWj?R+YP}$ zFaYv63lsWLnwdOM4N!oI9oLth(F%+Ej9FBjgtkyhpjSRIDlsNOylV8Ms7dQWG+8E4 zKV)nru-!0h^;S5eKja$DUl>GST}jkJ`eoG85BUhK5Cb9xxhP_ViuBxog9eK1UO_U% zrLu(arCGMXm>A4%Ou`R)y+>QWrNdXsBTj;3Od;6b!4X41w7~gWS$KL2l4ynTFny@} zX;w8`mxvhX=#>=RpL42^u^_B#5AN$?mR5)bMr@2G{`S^HV_cIW~oAFn@E zlP^~y_O&Q+9t*sxhe4kUl+#rMbB0>BJkyhUcy1FLsOOc|cR?Fo)Wd$AT+CFX&vU4q zBwCW8rn{QxF>w4&d*NO5LR!#FXS(=a=QPP-7(5rRs{tUI8{`%v%SEQ%utB<|+|(qE zhdk4dMM~k_%-EF7VN`6VESq{S(hK=jda4A%D`kS zVel6H91~z!%qqtOT4<wn!SV^FK~(MNq>#oZ32AasSy zphY$XX=X$Ihr!Vu>Y9?GNL@oL_9OG7VgFAby;XZTH2Tdf@dvZI(5G#R(%+NIR&&8y zRWQ{;jL|+46ol^afNS;!e@yYwo;B#Jn$k}(Twz=`6q1wzwE4Dnz>7sik^2SMuDPCN z+GCQ{R=Eow3@j@;Krt_9Q+9K1@Qbj=&gkOum)bj}nT+%O;&bzvK+VRE?Q2H%Ta*4O z^bI)j{`zcQHcwDdKjT4;82-)Nx?IPxvB|#49h`=oVz`V+m54i38apYgP_pE{u@1}$ z7G$I#7W}CAEnIeRE_MI77$In7FMlNKe7Hv)QV|F}098WMKBU!QM$dZ~Se=~7Jl1*Qp z@1sGtCLoL*d2|dcTF?ZY3^n?_jb=TrhxIyXLU>{*jT<4yO~CJ2gTygNFav}P(B;E! z|IqR~D+4~pBBS+TpcbIFaYBITlO=PI-ooayBcqd43%xox9)1mr6RctlEkCCe=bPj7 z;ezGuk0Q)s`X-+_60K|PE1>uf%FY;CrprGiLnqa+ft&Bh3cxhRHCaY5nbIV#Pe*pa1ui^ zreHJbVUf$Ix+g{KtkOSbNT!Q!Cm9BQK(I8uI0>a%c0Tv}b}14KfJChujPxT&-w2Vm zpeTq?2mo-US)ken(7^qSvL~F(jnD;p$aZml4=|%qSy_GUo+3D1@`={S=0Hhi3gKBw zDh;)`Dkc=~2k(Ii&}neKnUW@52x4XbscAue-eBU3hxramp((xIfUd47hj&) z@~T%K_4*>H2=J%|n&Yyw)=UQ9rkZI^m*V8~jlQSDK9s{&vH~TWnVv}Oce=9^{d@KlIi^A1}g?2JWK|^O*>)tz7UJ7_>4H zB{tn>u7v}PrSD|kM368+q~~?BB7Hbm>iF8WPFd0KbQaZ;0F}cS&EDSF@z!X!={i4v zU_zj!d8-+`MPL-a+2h(PD2u!L=sy0V@|KR#I$ib>g8qFDr;JaJOAkYIwor-}Q3GNggg*6uXrb)haNQ3RIMvS(RHBOP(v+0zq^NfUa zeVRb4G1E9RyK;b|K-&aQ!?mqgd6XHPWIoy?=6ALgi32YS@i|#8Zx1vGkW8_ZW3p-t zX*|^f$eNK5_oGv0vSHxa(5e8ngGSUbQ=_RsU9d9<^**bfq8iE~DE#_f%Sll@^%*Ow zO(ZTWK#5_~c;jSay*$SEYW732W)pDkk*p*cjEJU>LOyadRMX!`J4LKwVZ&-CpbH)D zDrOK3#&~ElTNs>FQq7rSuP-TzU0D2{SNx8Jw2WW}#oO4hr%8y0j7M;{^s{k@i>7{5bx zECt6Nit=$;`q-X69F`jFK0bYWaccKp4rw>!4y+ms!Oq%;WVh55X48k^e~dG9v-T03 zhG1sUoUX_8?;N!wxj2yO#**$TGy=2SR-zArRm1kH7cv7f-^>5tGb;Ik7DJ z@h&&uizuw-zZM|%ri)qLrn$Gl9!XI7w4Mr&jDo*A3JDCHdA_z1=W4>8&iNd>VZo}z+z(uUL zHQ)OO7MGiZa8({qD}(z4V*+2kk|`=!r?rW{nWqq_SK+=(g|Ixv5u9pii8}|}*|Zpi z$HfL!me@7VZ{y^!u!#9WAUt|ISThfwW#h1H?u?8|9BEwS6RrCM$=a-CiShw6ljAJq zc5?N8NB2nqNNE^{wEQH94W6MtECmZJFn>56(GSKLFu#^_x0Q77M`?w5WG9Ocb|sWh zI#RlyJF+du%@cuDmzX ze38G8YCgl?V;0Q-#-AI-G(wzKo?#f##7uP}*cV?bznZ3;Ibsvz&f2%*8&S9C%eK+nySUB zS;#1S5C^hG@8e`Mdp0M!81#YcT#t6;^SwtyhiBS@aSRY1QO<_0xk6?(reevtxYNmj znVq{6MN%@lCw8`Aq1+LWsDsOC*Dhh9Fi__0cP=NF9c!=Nz^9p3*>MX}x(6P3 zv)}Q4!V?8Z^Utp9^}$?qDh0d2X!U-)Udn(<`X4ihrxItSR&Kop)R}r{xm(Pq(Y;$L;Gqj-Mz->Z>Z(1zXaqd%b#9udYXW zN4Ah*MD9fbbovO6bMw-ks}%W@#ssGvwV}E~OQg3VsO>2F1F%QI5c`Dx?C(FeUR6K# zIWR)8(h(%jQEFeDxz)K0`_f++aB169+%odC$#7F%ebkPItswRy7*9Xb7;~c!gqjW9 zB#Q_i1?!O_Z0(Y+0NdHf_ebtz#13*;9Di1rxNz8?6>iSyV_;m~n)gTc_xiNTf%@KR z*C6#EG1jA^SL%ZliLjxHJsXY`+jD)Cxor8Y&_Mbt75psRXe?a+@%5^Gy~ny9^~$>c z9R9>?AeNDB`(F_5Un~Y_u74EW9L3$~L(I6Nw+3K8W?%jIYr%)y`d3}oJC>2HWZo<5 zHKCjxTd%ynUcIlkx?ZWi<+UVTawJ3dtIk`6|0AvY$8!Zz!OhC`V|%LrYdd>*H^wOr z!4L?lgmA{&^4>~|CD`C`z^Kx{)TSyBVga?~uH5n@Eg!S5_ZSV>QTTob-vj52-52cE zy`bB=R!{8KB;)Sz0WGo5&^tn3J#CCdPvlAGexCX<_2Zr$QKHkb5oxBwzY(U4-T2J9 zW0HqpQb#ao5RMJ{;1?soFHmJGMvqq5fg~u0RswWIo?OKw?we!xf%S-sY}wfXTXW5$ zk<;CkhavhKz2(UI2-K6XQ8B)PDu#fFY^lH z$7S*HGUyY9{*J-hde!ad6d-AF2{cu>UlenLB?h!aWh$yMO#-UUJg-qT60~x%ODEmS z5rJkb1KmaTnMogAA6MD}f7p&1hFN5y`FmQ>-Q9j3fb4mbFc&V*_q*fof%pqgwvEsY zy=qIR`C_Z+VZu|((=OE)Pp_BFgCR}Eq+rTI)jK^wq&u$ft&9w+o7mFI&JN5>N~t@$ z2a+Quz^faUad;Ky7#MV*=xW#?C7Gw>LuYBdQ1S-P#(~H{5%1J9KyHLhLXNwJl89wi zj|b;zTTL5j;L+5)ni}-hnaeFSf5&z8%4_?p&P&15QT&*s&czXTZIu`ru{Q&B5K<`& z!p8a?7)G4CuOBt2=qOW}URX{t3#ZpAijuo{8cT(jLYx^%Oat28#`S~nqI!i|U<7?& z_5TIyN4n1?O5hb(ysh$gZzz9v=Oj`@vm)+C)i0JGtgbt_U;K$7_R>jryiaH0Oy=J` zJr)I(`~F;6MmJy8*5ex=TBooZ$fY4lpdR6lmaO>%j>zf^X(PyJH5mxB6sgZ|Yqf5B zE+vjy9copo3C$;-%p(JEx~kcbKP?nt4P?%<97J^dB<_cD7D$;wDiYX3EqefG65GtA zXzu-BY{FC*L3K^uJvvjhU7(0dPC$-0&}J7!7c2Pj<~&_0yy(?fpM581ZK-&@N+8H< zUDm{v3sqUaYipvnlS6C$8-_}1e<_b?g~ks~oR{AYR$L>-V92w^_dJINbbjzDsJHKt+`H4U|eXzW*L;;D>H&n8)gn8m7ynMm?-? zF#4$58cW*trc6q*kz(6WOxe6TS_dJ%4dj*-H6tTMMUS%ih=rm=3rUvhY#K?fsxyFZ zsES!J3(BzL=BB7|{9q%%+13MDSdlwHmwv>4+{lsxbq!4&FOVs~NLL|%HQ>ny^bQRi zEmDz-N-oZ@#Ra@R1$t!_xZS)N@pKH|Hn1_l(ms@%fWtvCcI4I+qgcaN?l!~a*iRNG z4RRmFz{3b~R(HiPit2xe61K~BcPl7ltsgYXN7RX)s)flYCeb)J^JcE4j~0=ZQPQqA z2Htevx15W6V?J;NgGZU98(Q&!%suo!rVxUOcJUY$v#>}2p8XUt!E^8Ybo<{m3OnDx zw{X8gJN?naOPJyl%^Q0PeXcr9>P-a0m7KVV{f|`~^JW4zLg^M4BPl)2#=_|F9KsGU z8`%)}E`bI-cRjP}S10=;(_?AyxWt|RK{cZ0O((*;&WL?YsM4?|43X7F1xFzrEV#nZ zWNGAwMIUz$8~PCCh#hV$R?JOZJvX(tKgI4=+=_Kb8>}bU32u*VJ(jiIRR|uj0tmQe ztcG2KZ{v1ZG|ROFnBTe6B`5|(>bFs!{)>Ydmm6#{ei>Y1k`^Dp5$iMpxyA)BqeVNe zED!@MubUg+%kU!nET)&zp z*%j;sSVIzAFbRCV&bi&u>Qvm|eEbi0H}OcaLBmW)!q?DgiNjF}wTvDosuS^zoyeBHdj|?ONML>T z3;l^UVHg8BBz0B}Pu`Vyv`1#ZZ?H#I(nt&C-^@898DWZ_7iEoI3tCkIFfeyETsCZ|8e88YdIW-{ztqcKFph=+>#C$7Wz`cu}4u> z5Nt!uHRk@)qiq#jN=2Bvsh^?p6US|NhtRjJ+P!h*1Zcq2dEqt`L|mYz~Iy@fMNTn$YGi_-Um58QU zPn@V}R0UvMpOGZbZXp|}_AetW8aH+l=Mc3F8GBnThOxG7aRfr(U&pW~nWj!!zA@_6 zsc8q#youy(#v4%<ord%%)4$53-7QS*qMpt%FT ze6DaCi@Asq8>(BN=v<1<5i#Z-fulj`o^umq?oTn(5f)=C~K zug$?n_*p{1#Q6YCNx9f+9kx?26AS5;4HPP9FzVH?NuWN>dmW-k_k92goC{0^F)8NL z59cgVV01!Dkf7GdELw(kOjDm+_^l3Jk#Q%DYN0{b?EmL1F#LVHh+W}LW6G0PyCKxPOU z_q3+7j}nT{xHCySO80+&BtQHp%US)wL{g?zw(4q2{GbV)Q~+ZmZqoD&FR+$|7eHar zRWGq%F)JqE<_yFA8qWmSed{OY+v1Hb4Xy{MKr@?mV*Oc?0@zh|PE_9j938K(1b(9c zKaHaL4DwK27C%Y%zy#Md$;eKa_HqDI?UXx7d}$j38Nj)Xo^vLY zmkSG>oo;@CnxUfLMdWL~4I>B6AN3a&xPI2E+^%)v9;{?Jd=gI~yOWat@BA5zK z5lnKPK~;Y)uO}ZS1vS1|PFM#phH+C~7JMRC-t!D(3u7!;`x*k)0oZCKm1NE(^;X>O zk;JDK7r~P0kX?>n(mxcDSsv7RF288%JU)<^XY+x%c0PSpc*GcFSU&I%)|AEq_G7pu z>0~7A1~@Hov??|3NxgcKL8?Qxagrry#kSRUIsa(&Er?;z3QhYmVFkONU^5|k)py%F zChala^XyfVp7#I{OImPw&Fxt>N9yn)($V0u@#fb)rrQ&<2mdvQq^Av0Bx@aS?&tDJ zucsTllchRT2hZG?yB~Yg2f5WC^OzNXHRfZ!)s2(%!<2N|@v*lL%Bioj;)*~=w1Pv4 zzPrM(Y9px9rk*-#ic%27=oGTeTzLkY8?b_ng52Nd zX(Ns_2X7-m-`hYAWFTA9^)h{+BjNmP?s+QQGCUB&is)4JVYSvY`zZ$>)!)D}FkA<4 z0#o$n0=~wkD==br>9gY4;5`I!g0_K_npLj=)u=49Yaqw!j+EyhsIdAqkegyy9AFOD z$mxZF!La6uM?{SN{X9_!R-lLMwjFq<3!pJ^10=K+o{s)afl#w~J19X80M>)|Pc zBJPNod&9@R|E~ML@X>et`I2r!s35`+7o2nHPjN#`u2KQuw3X2P*?8Mj+p5HRI!l+G zyDRM|9CDJT(W?d9a4JP8PEw6NhBAgz@E6RPf(BCS&*0l|gbN4Kn9!WiEnqo=Mrc;A zM5HPSD1()|z&dd#_W1yTRPgZQJB5}%nwy(}C=`mhU8&`$GHMl9R)9mx6vnT$Sa^JC z;qiwTMnhOETrs3r!3r@kXg4&BaXg4gbi?`R7#yxtAp%)_fei zEm3wRWuqpL&;`Q>9^_q^u|UN(E;PhOn1pwV8Nj+T-#qpu%f|Dp$T+Z{Gp(YHUF~7G zrm2Sa^eBj_rZ*X>3Rd;&lU%F=;U4zvX*f#D*&0Mk?T10z_6!~PJE2Zb-`aQWTbt3 zD7W&i!%z`J;TL1g1|>fq^Wm92`2M)~v$Zi8MFbhcYgqnn4;2O7nSapKSTV~`y&WU= zG6wAeT9>lhY%u>5ABVK7a~+td=qzbig?1-Q9ScLpq5$;h&I1^P?G+xg; zy1%+M?{{gA6G?SCHa6*2%XF;VSabAzbICbjO^h~=ie%u76yymAOh*{^MDxKc4erq< zY?&abe_Gs$<_m)tXKC$>Yf4UTt0xSmM$;oAFlNw3N`dK5$(|s>pOhVsI*vllNShQP7pd!qfp0y@bU+poVWZ(e=h z;%Gj1BW}QdT>O1I9o&k`Y|y36^+!R|(5paG7L6Ilp|`P!iyv#2or7zd@WVaLOJADr zTqPg^eoRVPH(I?$lH>E{_>7mt)9b|?1(kt1f<4CCr|FDXU4bbMRj*Aoo3FQ}T>Yj0 z#aLXrJLgM^mqR@Yp(y|pivaUw$abFK#tB)2$~0I z^h1Oa4j+8|{;c_5$1MJS^|t}TU>Mf;@+Y$9?T?89Y{3m%e(REPC@h+PT{=%6d}GOj zm4Oop5nlf4B|~8GnmcLgman#B^1*L^DQn)$jAD>J`25l_ETYsyOD7}8dFRrWeDHTm z=FiUEa0O${#i>yicz#(Y?{stxjY3Wl@c?oVl{SFl12p@aH{^>z`Zmpq`a>vwf5}LO zP-?!lq~1~p{9wuRY3KJlOnA^(*citsDA2HTl7_vsUP~|^f(l)Uf07NM zVKtxq++h#?0fHHn2m*{AzZs~Hnrq{AP!s2Bs5?B07wt14Hvs+eHk!dAbXzAmXl~_)Y%GR;uR(a3dZD_tBmnnDw&(ILEm20r`J98*cr~YCY*ni3_x)1 zb8*v5;E71R#mO$4rLb2&w?jnlNy4Lah47(=VqjYmK*V4C5etz!)JZVDT`o+7qzpyhEO0=APdZPgp`c9Ss{ z@Xc*aES=|Z_tk&5jpxwDrFv)RU@e|L^MljPT5d*UAfU%JOqT8ngWxu8Q)T3Jj3)}7 zqHmkyY7CZnF@CUeRrRd&a}_}!X+Dd?C+QYu7^{MfU2|iRK`Jy+J&SOdZg=$~zI%Ha zFWKY?DTL;nqW6#QxMBpPD?Cps2_ELnZFe(6^y$Tn z6FB@R>S-(Y;kKxhQ3WsFlINzI0ub^1mr^E*u~?mpx(^j8@d*3wgmW;>Fb$LMTGPKN zjm4!luh>#-z#c9~;Kq{v2=Su)=XIXGnIJ3kbfZqd_#7S@=B3+Ok?|y&v22!VQbzLWZWYs$+*`f?T94!>F zc|uUf21diUVA~NY;R%9604Ah(OGp(4{u7$a+l3coC5O1^7GxzglSq_0=e26K34Wh~ zx3rvPq-%roL8OCOvE9TEeFqGSA+0UGXS6};<|}0}c8yolN-p|RSO>mM^&PDu0hfu7 z^g9U%o-ScL`p!s~0_R~HhJT}s0CO@%K+%EgjBS7sAk9ao2NKvu>`D=qpeSrA?f?gi zaJA@l#(B|jk2Jj9_pmT8h~_Uhg~xFX7A^|#Ip(V#Dis)uhspUdlYvhv`N|jvAp<&% z+9Rd|ui7iZC5FeRI5ms^&CDiSf8aFx;@4ZJS@;iOMjf~aw2}{MT>mL*GzOd6iVz=q zsUnrlp&fql3(;Ka?D`K|7554FnB;J*YU|?)cU$tE5oOR0&y!&s-_r%QF$-R6*g@ZHzV{c3)egJG zQD`a^YAUue=-3@e&Q3iYXIa*K;Ny`@1+L7Bkk#US7zRZo=Rk8yi8)w&39A5m3xga3I?lYAHY0M9MGptU>CNk`{qnU8YmPVl1NGd?@hmAP$7@ zNb`n|A|%s>3JkO8zIh^_4vOjYCnX$qil!lDNywmDaXx}-dDyRT0EHgKjWrQf ztMfpvb8NJ^^W}v)MY~@;Nl-J7r`eN*>?a3Bx#T2B$}n=^Il5;T{1bPPd$%BK^TUVA z!9ON9)+}5`jXO*5o$op7>zLQ?{pcZ{=!RSl*LkPzjgTBOeO!D{9K&9L3#l`Y0yI9a zj=>%qyG-E^OX1NfQ##Sm6=lNa?6MYx^wOgOQxO#x>KXjU3?K61Za!6(RvL3Ysyl2{ z*~80+%Ck^hmV-dOBbv7ojsyM6kH;Ai7U3CTNf3Wah%riGKJVh8c@d&?@ZIIMC*?T9 z(am+-O{t`#3iFm=R=#_SH$$O3gtdpMeTf=?lv!D~KSu5T_%`=*;VFggrFwifx!{!| zW6h6#L@y36mWOYWZ`?JqkaNE~B+swW7dHp|W$A*|Y)iXPslcGPr)ox+gZP4O zCPTGPlmUSN4g5QYQyQ2>jj;ixX$-jjspuh;HXf8F6+mfWGz_TBPcUtK38nE}N*jM9 zN)!L9gXWkR63|#8-5N}jhB{D?TUe4;(oh6I&Qnc?l##2Ses-8``WDpp2_V7pWTbLA}9RsI;nvTT8cemKod0N%sm4(Ji zMQ15^7zV*b&~_Fd1_9YT5Lfl4T0L^Mn^OF6n>r~>oJxK=>vWU~&0C;Nu2Grx*PA_M9LbGD; zsA>*mek^TxcL^=8hx5=7UeE~yj z@Z*bc~njA%PUUKL3)3xPJn4M?1mSjY(ti} zW~{mG{Ux&uefInJ_~1_#AAI(G#Kbip|LwL!*1U@nUcy&X{i~25n#8BmDem;H_%ZK3 zzmiGZNu)qm@L$COGDtCfU0Ws)n;@gV8@PdfW@jl z2xTkTh~)`c#<5anS$$Pk@Sycmuzb^qF&u8aJMlm#OwX&Exbr6~t|sAmyis*8k08<{ zm27*94c(1o10xRPj;n)H@T)gI2QuuRo4oF-E&-7Uy`L^tUriZ&eO!2Zu}e4Ge7xd@}}R&CD|)L#J(142alX zNHk~>=4~QIoK41|TI2-HJ*RG`#`N%EOb@^ZT+o-#qcKkH5DM-OxCI2tZaclu;u^?~ z9C*+|cPw?=-P&@9A+rh7&#=@ap$H@;q~yVeSRfowAi2l+%6XEBx$1J2C^tSIk<3#9 zznR$HOkS#4$q$!Qj@9jcHpfrW+!9#QY}`)dBUx5SG69;jPvKSU3m9j}0mN+ENOSPR z9gh7yDet%1%*lD5DH-0ZD`^AY`B9JYMlRJ}^l5O$PUyesWEnsBG|4h^*>s;n=z5BX+{A^i1Z4 z^j+UYjZhH-AEC)Kx_*(GvQkiKLrbB31BmA4C9Ph+v{fSY)97Q^vhqjlLm$~-q!`4^ z0vI!Cr5$z*QwYq7`PRi?#zLnb7`{022}C}e7|nrt#2x|(Up9}y#` zTO^Mc}C&l#6|6c|SPMH(`KLQ0^;TQI`g7E^Ml?u4Vrssoeh z8%Mh*yRXQ@Hft90>P+mm*-&W|X|l4^7A%gyc*Gud1@XZ7+?V+@S~YK0!n8Z2<4b|J z>lBfk9i1zl8~P?p`WMwUgEW!U0FB)Z22pLOUhbaCN!2g%T9U0^iAMc}yeO_#Yi5vV zrpb8{HA%xbBEv{}SuqQuBUtX}cg_d-Gt`p)_+|GmOn@m-7tmzv< zkZ)oK0Cb0QZ0m(yz=UZr*tG!@f6sPL?iDW{4gb6BwE5Uk1dWF^!lte}SM^IlQQoc| zBqqCUEOu@q=kjF6A|`4}`{Sy-CKs)`gC+Rja0&Rf>%YGOfBRop0U`Z61a2ltHcKq* z;7~`wiZ@|W$C8{#Vxj!1xn<9n!`#j$gSbH%*HJaP(gk+#fppIdhhB=T1E_K?tB{1* zkloor7mySDqA-Kq#0qE|AaysmnS*c;G2Q|_gxckg(~>o9o+)UMRj;leaq)s-A;=Vs zp;=kADXQNh*H*Y@2ylHo%h6^D;#WV0QiLSs=dmEBE6$2kH^;hDl=WrUFOhp>%}v;l zSo(As)1PWVqy*w6vYL zgM1|BAgIS?;O$kmO-WGWqw!om$YUi#t zEF%5xq}2~R8?HYkUEfhIP$-H#mXRA+V~3!{!Qmn&l#@VQyzk~I1HwXrRFM|ZzM2Og z8}25Dl-42uzyuQiO#o8YE))Od^WU=S7h#GZ9q2H}%7c9cCrwci(sA*93paT*s<_tE zv|01&-wY&&L4Sml9@y8_EBK>E0f$Z>r^%vO0$6mskVV_7HhqDnEx>+Aw|xAE_+iMj2Ao+neQFVmx*Fa0hdn6FCo!5=G(T< zcEx`Jj(s!}alJT=0BT@VA_kOR}q>8!uJIq==YpGSAHc!<4Dy`0b*^CF;cIiA1GPDk>UXPP<$8OVm?ypR9R zNIPRO%I0-9$$hT8 zjoL(COVNk}xI20L{e}=l*{f=$j7Px`r2xPFW?&#{FUr%~Z z$2@`=K8&&g8QR6*gfUILiEQXYOqXoZ06R^(QH`dT+^7cFtR-DsN3H?`Az3i2EdiKr zWTSB&^&h!@6172Xp4Nh`bXn9yq|M(EUEFCwIAkv2sRqq%kT_Gx;kb!CbLHFI{tlg> z@?dz0CT|=jJ3$%9;o6$CjI6zr3W2~#F(qW8A*#8JDtYC@V|R5uB2eixiEy|N8FviwwvLh^3Ii!-R=t_`kuh7wCAir$tl{zt52QFh4Zn3T|u zsGpM25moOgt>BmtvIihqyybsLT3f-a4+FeSxS$P*fk$L}*#x3xr&!ld_9z z7Af)yRab(#o^-{cA~efTzsFrp4`kh-Np?b4g()?xh2QS%=-Y}wh_DBCIitHi8^+JG zhiIt}DDlIcEl7=nAX{-%jiJP=GrA304PWi&?0&fl(z8VXKj@A*R#%EF&GAq#kp))? z+%y?KnA*eVBxKrYG1Qpbe{EVN4w^Kr1jqjPq0>UIbXrppJ*0<_ZrW+_>c2Ft^-K$} zT}4Q=lRi0nJuQifH}F}H%`NQv;~#wfYdx+Ayo~4Ifh*0cxs* z@L#9x*H1A?{N=)GDgeg+p!n(+MhD@yedR%cs`P8s_EcvRJ31-espD@Mcw{#b zI$c{F;2bTi@@sJd1g44?eTUxtG|XF~a}MOE&h_{+vzWnmU+TD^(i5ie?!^plW(Mai z)@kfKrx^j82e3w z0%_VeMFDpj9Pup_xb4sa5ELyeqkt1iyd?GT@i*nouYV4G4{|?k6&i69#iI95^X`p* zd&oQPL21s{m)>Ib5rVm+bngRqx_gCYqi z2crn58HNMqDEpG)-y0NvC@n}7=U`QW3ojFD-u%`7u>>_){tcc0B|`w=en5=_NvjT2 zZ!FD&MdR&)KXT=Hw`s=61->BPaedQB7vL5rBuhb>0o!fnze6*fpc#BG;NI9Jfqpj~ z+UHHtC)(M=2Yom(wu8Ry&<1Xc24L4TkXXWZsQf2}CZE2a1uq_XkmOx={c`x7=CYrSZc*JbERMccl(UwdXD8vNfL$C+ z?qKxPHGlf&5h2v={$!fRIP-{Y5XOs@!2p~4V_831ETVDaS;o^S>#x=3jb(SRy9!|X-^ z&}M~`@Ki_zB=mh>mxER#SI1y|nFeA)?jpgB5DB$VRD!y=reEG}^Zd4c=!|>?-n^{K zyZgn}S4q@!^>v{pReR^^U+tGy_eaTuk6bCQX=~vLsYkD(!M!}_f_dFD^89Kh7eff2 zajaHkNNf@2M7{g)+PUm`La6y}yFMUPyRxh+d@}j%1Mot^m*aQEknegMc-lR+^c+#X zcd@tB0yB;sp(xrf=ZY6}_SVH+beLcDzPF8p)XMl@*G7!3Thc)E!ugl98^b7mlIaX# zI=~tR!gSL#SONkjO#lfl#=uVw`d-qgv+ALhQtiBex}HWg%feP1tSVR`^kxJ|tgTaa zS7W>zSEBMb@RqcK_DE7Ap}o@L={d#Y4Nb-Q{-h9{F8GavWZ{RPspBR1cUO;X*5?Ab&%qd^3x zrk6W*#O`6I|3-TyXzXyIZCecm+>bf|8r@rERvrByPYM1&Rf^~jzO4oA*8nZz%BSQW z63m}q%mN`8U?)b|FEN96q+FQx|6=^azuz{*p6)Rz17!tj~USRb;yHh8VQ9 z`8a|dKWL|_HtQ29OWJSy8hK*gH%EOcAHBe0x!tmQMP8k&>k2ks4o}Y=NTahfW1`8m zGzq29`vIW1hAKgFYIrw}FcL7|k?{WRqWU*P9C*mQg&rgSL8Re?c9n|mql=lt5aJRxE%)i=@x407c!vuUIueT_}zoEI6SPcJ-Z)y!Iz@ zHetB-d?Ei=f*cbZH~e2AtfuWXm~Tysd6NyaBMa zccl_*DBNT7a2;_RE)CCEXuV3D8NyY&4)29Z7vse!hT*oWs(LQX63D;d@@;)OKL>$Dsw8$kbeJs;JHD?$!~eh?fcV~Q;B zwhm?~b_#vOc8%Yh-!r@jfUMxfv@?P>z0?BwVUP9pe=_ku;JlyhJ69A6gDyqR zfoUyy*F!4z7hBz8BF=viXB~qeIn`f632Te<32*ZA6h3#7ib(WbTf8S4cWoxmV;kE+ zLp{=t?+{&NOk7c&!~4?C48<8MDvtc`jAssM4o6>C=%p69W$brOFU@lfV zKnpff-8=?+zk6($XArlMc~D)=yktZcZ*c=bpr`G*JpUq3H}d%5g$RA0fYH`>?Q{`_RAzENF^HR#&iQU*Q5_( zb;U^pj~^_csA)fPh(&=iL{$Pr5~^OGhgdL|7;CO1ad#o|C2~)Kg6H&|EM=t1hE;4x zrzl-gy|ExOO9|8~so+7X0oWF+j2LH#m;v1^ zsUV9QU7OPX3Zfkx$fm_=j>ZzTSyiKQlxqc5;e2@TWq=7VjKwh(y^o#?iQ2)6p!6kU zCy?Hh#X+1tPExLIyn}=T6swnj0;W;W3r%rJn+(KGo@gfzYZTU6rlP2;6oq-iwU~jo z4Z_hSkbfVh0UDE%vMfW;b`ZA%Ff%i97$Smd2jE(eT>w@Ra#-A=|B@hsj1pqrkf98P z?-WXZ%e5|&L`~))hY4*8DH1UGe(MMy$Ylb*eghOflD_W)8Jw>a>!tKywYxq`LL+&;UJ{7-|oXg6*lc}k(5`EN%Ls(FBD3?S% z>?~1hH`b%AS}Ti1nd~HH1UP6Qt1i-kF3VszV=Qk6z|e9_eqO2HDqhPTHJ zA_E2W-on#gir>XrO&#J*)OmX=h=cdUZ^c+Cl?LkqPopJ%g;HD^OX=oaFsFBr9?zl= zD}|n8DHeQDFBfXDx`PR);r|%DJTq{g0lj0u|Ip15vh6Tv!dF9<7t{eV7naPOWL7w2A*e|HLYrYW`&o&y3$K+C9V&SkGYDYQ8gXm5ooNVH#yE2> zqKN5@F$b@NHZ!A_pVp-HhtL<-UESK$S!rUEAr+9BR&cGS7)l6=!)s6^7_Wp-1{v)i@Xs>8W0j|R;49yW;Owp{C$xNS0waGv2ekaoU; z-=9P6aqtEH5YNu)mqSm&MeI#v?f))ZMP`idx8&3jOJd=}^BTAQf@Y0Q9QjnVxIWzh z7#B#i$|Qio%2)x2Vc~TIOQFY@|Aqw)521l<##3p zRQ=qoxlG;_al}BLtsvcC@GRdXL60j4&XC&UQ57Q5N>ec&lRO0b>vn%NNhbJFM3&mo z`poR?=09Xyq$$pEX5AP1ZTRJwa@FHm_|EvTqDirKmQ!4EG>-fvD#z?uXFYz2#}tHA z3GDF{a@&N@q$q5!Zuc<{^BS?MCA4Y}LB0mg`kz~tq=i7>VF@vL{?Dz}S0vue=ptf( zxv@meI=$(LRlXBxF&JkrlcNI)Pco`u$A~+uZ-c^U=ZA71 zVN3AWK|)r))h3jeNx1l($gzyKkIv&^KLddI*{eXE2z*m7VpD`6KFnKLagyw7l+F@8r zJAZoVF%GfbX%pt!?LN&RwkM7Y_rvY&< zJJdh+|GVMjL)(Uj5%-_jOH%U#rz&RNz^S@d{iznokH@zPjE~3V+PRI%b^dfoe)Ma@ zjK)6s-b2}QR|zTHfz@4L^!vh@`G4o6-p-1>Lq0N?5P%{!K6R1V1;De5;d_J1YL?)=hYwUIR&O3xa%7Ds zVQXj;oD)lV)$a@@NQU@lTW1caTvfelM2mI_Ab3(|?JU3Z^y+_k+9;!iv);h>Zg(#O zeI$SQ^0@0d20Qzijq)Jla+c_>i4Dw6;G>qFW3)?s0a+p3?7UW@kArO^BO zl^pJY>e`+Ju!sKuTHp!i=36iU4Y^$wZu#m{lT;^IrsjdzT%E-P`M^w$aR=T`#|~w*|q)A@O_U#{-N$0 zlHLcM!Xr0EWJI7=IhVZvWK4%ABlm*&c5%xQK`_xHnMV^z8(?V@Y-z&1xK(3amNm23 z0caCgX=XlA*K@ZcM(+S|SqiC^jc+Wj;H;q2XHUSpeZh&z{Y3cCIX_0wM~dzonx?r5 zc+J<2Y!TgTZ_BV_E+y0w%2_IF>F3>XRh&Xh(|`#E75JtuuX@g^euoMejYO0(g*a7F zY^qBx)MLBZIgV)*4d*z?vy595p#VR%%nN=u}9HNj3 zJ&!wLNn_S8gFeT9jtOexWYr%Tu?T)3HE07m`WEB|StQtV1-7R(Hr1VUS6~2}Ri*L= za>Gc*dJ~7QLcd7sV7soJKG2RZO5toQD^8&C`Tg|u{-XN~cUD?uiY*}_1pF9iEK?tm zJ;OphpRUv!nj>x1u~xr_LDp>p$8(*j-CN5rItT093q?ngThEz6&?!jZG%%DeMis`< z=1E2v%nj?F{8FK7#QW2d$CaCs`%`W0ajS(o!Z&@zxs*7mW+KF8wz7La z7Axsu=J%5U1_1CcFK3gEQ!gXT3kVXyysf{S-tqf52sx2V3-@seZgurSZXkfd&2Iu!A-1K6mo03=I<3{8{~RDHQbHj@2^BJ*!9~Q3t3SkthU?|{^8C$4i4!=$aA?q#{O1Q~ix2@-RXREm zcY1Ww7#)&pL7yOxDPW7Ola%kL^~?Qp`E~t?xz66|UXH#Y0G~Tuh*`*9mZdSKH1yk3 z!!RcHs7=qtc(B`Wy10;1W7BzYbJML6@_JH+S0hN&aOvSgCY6>=!wknan>*W@C!9>- zviZy>vXj9`hRy*Sz?}qHQLPVGtuEbn+?q3w2xpQ~ee}0)#v(}pX0iSBeo6pGE`=iu zkC{Z|WLCWZ{21(t-~_|b^<;QMlEc{=-buT~4j!I1HSdu)Qf(3` zZ7l5r*=mC8V55mEBZ^|S-O!DV9vNR@OwN8m5gEU@;3{gGv;elAHY((4S_{KG%}N5T>R}FHnC1=qe~6T&f7JKT^fa_7Nl_uWzlK4L_q7tn_HuAo%3q2ikWBpFVt+ zWf!ix?ZMHz5@CT5ClVt99(#cK17C)o+bcg6;EDTsBOqOoVIw4uNjE#km)vD4Ul}o! ztAkvDoxUtD3`#C${V%ZKVFyf+gCiNoR&(u+G;vwi)yx_FJ^k;RXUU6(MwbA&DtwGv zw5F;TgiYntJ8xj%opy@Oi?MvDAbg+DAV9x|)B^jx-IL}Pv5c#h)Rm|?st6;OgQ?WO zH(eGX0s3RNyA_v_+W}ts;q3XW3Q6ru4FCra1yq3K4Lpt`?K~bPlFKc$B!?XX8I*mf zY}*(XR&e7;9%is>t1hOT!?uXpOM6gj;zq6)53^3Fsy;6_`g$&xt$Yiv%bkA%8nhM&+lVzM2nZ6CVOA=j+3_Q*BZVQbMb z30!P&P?Jl_$bf1>{Pr&y*yn!q(7%C5AGn6t1<5id{+65}MeVo5-klG5GO=jFhQUjB z-t!v;*LVA4({5hykjTRkECw@_MX!jZ5eJq^@)ljmO)2B`u`mKlLGyNmet1rRrowU> zhY;B0M(5{^#wRO`#)JtKK6p)xitvT7N&|N&FY+_8Qk%pWiD^JPv>Q_ti>!k#WF{cS zh>?y3f4bc(vKBfC7>~prI(c4X%qkP$)k{Q4AcU2MBFEt4@qW-HKkJU`DmenOAD9h#yXH`qvgg+~=ec z0V;(c;ILY3Z3lo-kpPIZQA!SnLsAI<9;nIW`ZRk4=OvZu>$9WS;OPRlwVAbeeV8c$ zU%UT}kzz>imO`yCV~xJ$-yoK+gTl&-#6u3X+t5~N+hh`38{^Z+pEld?ziaSbm#bgr+c zCCI}^7F!w4*FiWWv&HlE5fpB+J%Ev->DgrYZ1UjtY}lfV+PIjJHjWkWo;=$DT;3s_Tlq0-_?q{VCj$im0jeEyAP zZ?ZYaUtA%{3zT?(o&W~7h=v--;#hwKL>wDBb4L1sc<7QtqEtW+8GmfbL78{VmDeRT zn`VvI2P*Uo8vvWt4rx9;?qjgG@#t-DzW(<+B$6TYw+LPvXpgOO>j-2t?Mn7b^Bx%0 zX_N&6DEK#03KOLAX^0N@+6%_VK%|xtH^}ty#7~wd`7>I23+0roNw6huK+$SI;&bH^ ziaYJb)gP?cVuv+Rk9H~zr_GQOwi%r8&|d41-st(!+_rzO|6ymbs>}d=UUXqBdVsow zy3=LO6Y1N0?L~9kIg&rKY`*iMpl;bfOX1hJ+Z09NMogaFELtW#41eFqWky`)zRJU0 z8{EI@WdXaa`H9nQ5&Bwe6E!oBT-fk$4@wR7+mB`>NNU{p4w8j52Rk-yGb+BD1+t`v z(fg&Gv?CFFfsD`Bw3B!X#*f=d9f9fSPR`f)5qB#3Q4gaRK(;Su+xdscUIVoef<{6u zkZR2;uLX$nbY3g}$z?R4TO`)T*4;9unF2y4G?B=hxk*$;I$l?E1tEAT^t&u;d^Nq{a^{kq!+P=m-K_*SC?&BsJ;?7hZ0}UbFR%@ zo!3Em2$#reH~6*L!5>(J^dlz4P=`Zv3=A)YO)u@)ws_h#%)0{T@m#R&qjrT%->-CA z(=YCrd&sEUy;q;lbB4n5oRqBre<;1yX0vCzPF>asghEMvQunp2k`wR&(o^FyaE%GH zGYR)CccKG1=Dfc;8A&H{#l9)jqdrAZ<8Ya@0W3zEL{L4Crv|W~Zo9?~2_^GsF11!R z(Qeum>|6l$4J0hkioLaUAKa8q*QQZnwFTO=gEiyDj6y}3g852JUxYSsG&PuIKzIy? zX7h;yU>iaPz){Dvizt#fq`(R8Rc1C!8y)7|98A<^RcHt6hR`_B-TdWG$M5D(eIXos?hiFA zK*HKI3wfY51Iw#-xSvd#n!Mqp8fxiBCy3Jxr_?NyfVNtQ^rRA+J0*Rf+xlxm3q3$( zj=thZv9Phylgh&dTbVo z>PskIaLcxyIW zPKB{%rV#{%S!+LT&Iz?Dw&{T`VnPK@$H0qDGeCvWQtE2AnNjpv+IC$b8QqC=t7G+n zuR}mGkCW6y<1tv-eDdYa3@_+OG6NJJSD?COJ-zqJT_%=>HYkPx0LEO$By1%1(b8aJ?p5v)Qi^fQ5BgnK~n3x~R z6^3w1gr)|`R)`B1fj`7qmfVcNpA)uKH;_9xAS3~RLT4*kSeg^iDZwS^_X$%T))TZu z4fZFKW!;ISF)ksg&ajLFEU}=?uaFh5Zi^Myp0}#Ys_zmdKoDZX{Bue_!n!chSP4-= z9`Aq$nSEJ67USpT8ELUum7_eEU!Yz~`5x43eiiZ7_%ITo?0fnODc0MR=~ z`2XV5x;bGdY2~VK6WZNi-Xo;Zv_iTv?u^s$p$*gXR~DGs(w?KZ-n!qy0UrFm4NN`> zsz~rz(d-~&AR&7#?U5cv48(u^=1~y?C(7Uzs|lnxB&APuY~hPHNpy*6Qf5RJ6R+d3 z(TP%8eCYMB-r~}L+@#-8fHkjJaXNp;PLJeL;EMyGpXzv~M22i;)Z)ShZlYKJB_=uJ z-MbHfR|7&}@xpAB4#l!T8&GunJh|3O9P;onT>rC93^z`SUMEhJFrA2_gsD9#CoLdc zlsVB6(UMQfCwHBkdlwcvqK8&xD1*u*BrisyBDInhZ<8o4&;V@?ns{O~A;7YRNNrI` zR5bv#{RJC7keMRW9$%)V5!?WxIW}|zToQq{K8(b%@qbi8}RhWh>k+G4B&3@FzQXB!Qz5(OnXst0I5mTsSM53ac2T7 z%&mGm8jxHTw=W!mlj$RlvETFlih(?J5jHds?MbTLrM0Rwu062wjj zfl;QwKXf8(z7=fRm##h2Q`wItAEUbnPR~L;0ab|vU>0(*w8$xNfqK-m8+@`P4+3q1 z7h!j@zC%;fUUBwmM-aiutds~ejd9{7<(=mD9i}%2A@ZXz@xfq0#C-@uVu+wyrcutu zg4M=$F%4U65kVygR0x~_6QWiqW;l;%669oLFsi4v2WsUjzY}~VYxaXIN$^KC#NW@x zeoS*skJ+}IZM;{2N(c}oXCl#lA(18~kT3)n3a?=N8{>8=02996dKAby4@QE|%faZ6 z3IJ%o6SPUw6%PNE0bB-@drSZZh;>g^vv)&^n8^LV_!_9u4K1|# z@C7?^HDLtQY>{SdTy%=(mTnXDxk(r3v-R&3kw1P41Tn(0Irz~jV!ox<2z$Rkz{x{9@8tsPD$xV_&{w?pSa2Mpq% zJxhQ=t`K%6%P4B~L9XXA8z3Sa>PFZ2m`?dGOu8dmGbr2-a5C^cq%YXgtl)4LlM68q z@cQFWh3MT&gv2)&$h%oOP~GQpRpm}XDqA9iiZ>qgtv!#1Wg905fJO4)QyNQ_fkH1z zG@2$OFs;VV29Vo0JrL>2rFYd<%9L6NXe=^Dd{N%ncT#qAkgwukke)c zg_H%FqBYN%PaZ(+m5e4UXBnhZNYJ7Xp|k6=$DjfRs<1rMn8ji>j^5~x!o02CIHur% z)M?IfrXc3-U5_t%$x8nYUW}G0L%!4^DRgcNo&FItpoR&Pn`X#FVwqOLr%bBJd()z? zS}Rjz8`Ensaj#-^UFM8LYTKDjB6oG~7=P8hM-{U)M(JCMO*DoGLt4in$z*`k%jeeM z$)P?df=G>JXB2iOpGOMFHGxNJ#K?s((r*d->`~QQJN2UgV1IS;!P?#8fAyo7VjcHQ zf+pi6cnl^q8h)c-1H7;1$%P|J5FGBs370vbd2)&o!I2%yu36+O?K(svH9Gw+z~J0d z_4AIG)@4zn&3kVlHWN#PU#w-^x`HD@IRfVkHMi+&9e1`>zh%TlaZ+|XAKaLhb`I}B z1^>TTTPS9Av#?KGA@ChIY?>aOiYwaqaZAxpidTXUw&!v+AqM1JgdC5SfhW4DYrUvq zdW})3A{iVEIZ|@X9+&VzVWE0LrC|iaa(h!P-aEk>Vdr6&{xZ)W@-sNJ5_!z?A(y!( zupVSc$( zl@_Q&NNM#T={85j`yoE`3968VgSU0uP%!eOY#Q(t5_(`$?Nz0n=5=2;9G5UH=1=A% zv{-$`F785S*U1?N_kyA!8IS_*f0P|zArSRDD)fQ%_cJcd;|{(2tUi)}HJkJ&FZi1@ z>!Ri?cWd>*w}_2hq6$n>gYY0sBwBMTz$4KirjHCx0eSf=#UJ9~H9>VRlsT ziGl~MR@T)#(a44G0uT_CRyX!}oV5|lT>JNy49alVH8@`Glf7aom5gamR0*lZb;tx;{HTh0_lS$w%-7W(h?Eg%#DW71NW63$`^#CX};N z%<$mrk8cGLqd3KzB%#vP>e+*F)QsbuKj62H$K!+==nR4+3X#(VXVL7+e6g_=^=xe0 zT-}VR@OTN$pha$OY3}9}>X?osTEz7318q=Sme*HUp^w*s5j zlgbY+D0!itDXC!;C!@P&3W08KsuiGM1C7qtZMefseT-|!ej!vP(Tvu|D0U;uYboKl z-wJqEGN`cfGF4SM<*V9L#P88=G`E+EGOwEVpz;Ftgv>te)HAz!Gr{c`*=izFqVi%2Wd z_p%I}%hZq+qbY!vb!7D1tA?|Z zF>y1!lj5>Z+~{eKyQuzp1bz`=jqSuhn)^v`JJ#IC-x$ZV=*1+JabOr(*zg}Vcdet$ z0=eIglVrGiSTo{&aBgjJU*4anUds)Vu!(pmZ{!%}>mbeE1Y>}Y%&6!9qEbM&b(ug7 zV1E1v0MU{b`*`eJN1kFSu*X;ZMWIIwO(lkTlf(STrz8XO{6PnV;iK2^AN$YM&o=km zSh8YY&f$Ea-NaLt>hQ_TJbW@UOeO`hSorArD2sS?*HOHn+ovEBCaRxKu6T*IQ%?u0 zCcYh9MObNLgfh8?f&XuWDdH<(L+HII+>wm1(|qXbvWD9N(&ow&uUL4^$LWfMoWo{B ziMAyq)lx*N6CO>es+#7U53DzPOByTilEoUo-f7GL@WKFL{>Y&D|i40hU&Sy zvuk^gXC235rT(uLui+iDoJ;o!(<8lJW0|da4hf(KQ7{2U(3m8+|)$4NxYnB;vbkUF8U_KR~RYzt3^{*ki7PcwiXxD5+OHAe*nZI>ne+*0d! zE!*LQ1w4qxj&Nm;KpZ|XmI&~AF=$2sF1qJz1?`4ZWy4u}ZZ`#XY>5bGR z5&-Rl^2h+n)MxP@O@;xt=?I8mctCr3^R}N92|zk_QjiWciWpG;QMt2unc4`eRfs?7 za7CRV9gbj0$Lb>@on)tZ>xaamgMqbh?N0N_1^6t?B0xfp&}mQpPitlwZE>_2N?@}M z^xr5j9t|Xq-n9vUn0)84C_AXlkK^YxyL&ai5GFl7j@Z`gw}|-Yv&6HN#Bu3d5PDajUpGTqwC(Y<6({rtx(?})j}#zAQ)Pxe0`pF z_Vl?z8EFNe=(R{lQPw>-#*RQ*WYudqO9s0M??8e2sdS!X=EcrcvhjjQ3IKA1ry-B# zftdAJ5h}2cSL}7=y+GHsu$aX1SdKt|YIiS-`D=*Trt#`joCZct> zJuH&RUfP^0S}tVTr&jC7ZmU++?o`nUr|{7s>Sjw&R|oDm@>w822jjBtmQ{eh&G>vT zc07a~@;3&VpXKNw;3I*?^7?VHPO-SH9f{Pv2Qi^~38jvy?;dbM`!|5Y2P6XCIPl;& zds$i}F-fdI;nP;_>X#>HtyF8p5u|#^+8jl{M=e>bSin>t>J3~=7_}ZZp`Hf!6hK(^ zh-g|3@bPnaly)#kjaE$WDwkl=lnyuHvU!qX-!0q<5qDJGg zE+{Z6CX6QGw!A*3dW|9mAM0u%JySmhoeORc?XL(WuQeN33X~EQ<5&!t+d{5nz?MVl zgYKEqOmqFhf{tYzr7Dx!d6iO8&EL^2(@w{R4mDI%vy_6!#MVXB8EZFogJ-91>aLxeM( z(<>uu#9@ZHQB2}6NmqdWJm17453iRc0`h`3#=RU4;Bxr)ep&r>SXl3A{v9=sChQ&!@&3dd zeyKP&!A50pK6LG8!TH8-XYS*~PN5O0kO11G8@uAGPiHmU5%3(17CxaytXaFyg^wtb z`?-IOTyHEgvIdY<^UZn0VKH1E_xXdPP=t%A z@)75^>JA5kNzsYc=92M;fzB1z89tIuYzJO2wKxw2eos^&DQkS~P-^Yo*Y>m%L2o=!LMqr(b1`UG5eAg-fy=%G?Vti#MZUf_^P+D%KkFmhS%(RFfxsYQ(KIo z`V9b4Pd}yLg&;zSilxU1_9S}yHaxt+go~!@@n@_;7?2+x@vq(v$}zksPuE=ODAL3h z>Adri3q*`ZBrF9+FI~XKsE5E>UHuEdLMF;Ih~B|KtkJZqom{KeE(Sd<+$PW6)r=>q z#(!}2PFFE&zQwn0F93^LO>Y#=clCiTeHh*6u?yN>N6;6Y2&y=O2P1et`YQqfWj$7I z)MX3jE5LyHwY#p1LtT^BH5Fk9AGn4s)OzWH0aXxDaRc96T&^$;Qy)yy3411KDfkc= z2SbTrBBof=stExmIN4JJvv5g*+f&vSx@^!HGR&iK9?7khEv0DX_LN{0)WEA=iit~b z(XFn)#jM3eag+YcXb2jfzBA>?45X&RkG(#xe!Z(kfD86#)zwlbDZ6Yfin{WN2+#z6 z@77d46=z^Q6mij2`<{QnCC6wz=E@@-&?-J#^4cj#u!lL-N>7!9IMIY-Zg5A}5R@>^e|{k84a%OXfx79hQW0?eWLEfVo2 zeMh>Cq*i#rdIfEZT^U&^+@rD=h#H*5rit)M_vC0R7hI$(#)%R-24-E!jvx#2a>EnA zuyuw?JwqK!sO9HcXGBC{wZermQQb0TUVRn6o4OIVOYdH3E9pJ8C(HwzTr04;dbP*D z2E^dJ&({3#-30G&2~JVy$;iQYH(i=lF{#!bS(|EZr3$M5^d=nB)9xIP^P!=H^FY=? zf5`*Z&lJhr%cYT?cZG*Ln^WQaYyK$%eQ+)N8n3>oyNJ0!VxEj&S+1nPuYW&uV!(Ss zY}mt0dmy5iiY#~O$3uOksgdTd5-zJ$;gK#;0#QTKSs1nx|E|;h384{+#&Fv<#kgc4 z)I?M=D-nE@bti##JUqSoM+IArO|G$F2@+BwbATC^fuaXh;89__6|;l?qK|&3Ievaw zmFJ_QBO_%oI@*c3yj#;p5o)Ly1gb_?dYpeV5l>5P**?ygq^*0i9^k}MObbUB5?}6ACwqZ+Qv6lAHbpStj$mj!`_LFs?eWH<07C94>mG7 zbgpLn#qACj4|y5;$PjDMLv9CWS)WXWbg>y4gru(O;9e~82<0YEiF(UhVaV5Zps)C(_==D1IpjICv1W#T`*X8_p=N# z%e1u@t(U%V>!n-yviXJWmuGL;yuBIx_~pxY zUzzRMa>->E?B26u*Om(|+PZ7Yg?zg*yL88%dUO4fU0e5T{^jjk>ctm3F57bHsl#Hs zFW$BF()kN6*>Z`Mc3i%v-toe^{q@4lTeokysNS=q-n@PLjte*M*-{^SdHu^*?%A?? zNvSiM=bw4*>Gg%%H($PcOTFV#dcAbVrRz7p=taA>yvRB`FW*AbXI{GJXLek6W%iu- z`}|Y4?B26$$CcSRmv7&*^|I|(W>M;b9hdU;@=LdGo!`QjH1z(lyZiOUn|Id?aZA1D z;?0-R%a;1GU0W~Nyz9z(e#@2F3wg8kMVH3+fZmIC?YR813pVfCwfV{b=PzGy_>)6k zwgoTWzIF4Z7g6Pfdv>oTXFew?~%$7N?m{jC>W zkv)5hi+U#CF1zrG?2^q_Wan(TeHV6%ya4|9J})gPvp)n@McyayWt^Bxf z^QB_uB|H8PdG8$+J)%E+GduMi6vKDxr?|I+v zk8ejab9*`W+;h)8=iE`eqkVfgFBxu4v}wfY=nr=!!5y8d(xi&T);-YG3IqsFPmYb`)sckG>5hj%gap{p z2Cnv`BC7gg8@m$S{fsSBggKU)Nqvdlp1ywO85k~2=uYKn?@J^)JCgn3&P1#oFbs6} zYgB6O*qE8jn?i{&^Dh}@D(ESy%W6-R1*8G5RLT@jZt5B6j01WCKuAp>XsgWM_JQs; z-9*U%&^IOM4|6jqEo|!n1Ge?6CTVbAojBL(XGga|Z)ST(cke*I61vpV-_ex-qDp8- z=cb-yzd!nMu-6|}ncYjE7~vl3>hnUA;lwsNu6h%FNqKwoyM=*k5r{A-%pK$OTWowF zOQ(jh@y27&kXSNdd|=%`r{`{HjI64Sgf)pVvAr@xG2<3|&=swXbq*wIq{_kb9vaxM z!0@I-f3rB71W1gz_O!7vR_HaXEb#0_^efWgvdZCbO>Z(s%6U{8Ba-c8S)3;j6q`jaTj@}qksb8(E zZfdTsqxjUa!g4Uc)YwGJK$cirf9H0+EX4XY4#-3UNL~6JX{Zi^f3lKo?dabWW*KEZ z@4ySmmg3`KpvoF5nT95=TT@drTsnwr!^So;#1ri?s9qQvF~I64(^ONd4SC5^WyT2z zG^}DIuBF8*64khdBXGKPvUK|C!(QQPb*z(F6zlHk0GVhjXo9O+9

)(o>u<`n8?u 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 mW_H2e4cY_R3)%t(9| literal 0 HcmV?d00001 From f5ea1ce250cb02fbc583c6cb3f52a923912d0178 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 5 Mar 2026 13:53:19 -0600 Subject: [PATCH 0737/1854] feat: add copy-to-clipboard button next to download in file toolbar --- src/lib/components/chat/FileNav.svelte | 27 ++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/lib/components/chat/FileNav.svelte b/src/lib/components/chat/FileNav.svelte index 3897a3c40c..141f4c68bc 100644 --- a/src/lib/components/chat/FileNav.svelte +++ b/src/lib/components/chat/FileNav.svelte @@ -762,6 +762,33 @@ {/if} {/if} + {#if fileContent !== null} + + + + {/if}

- {#if queryError} -
{queryError}
- {/if}
{#if queryColumns.length > 0} @@ -327,4 +330,10 @@ :global(.dark) .sqlite-null { color: #6b7280 !important; } + .query-editor::placeholder { + color: #9ca3af; + } + :global(.dark) .query-editor::placeholder { + color: #6b7280; + } From aaa49bdd6d6e5c10e8be554039d3cac673008fc2 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 5 Mar 2026 14:52:50 -0600 Subject: [PATCH 0741/1854] refac --- .../chat/FileNav/FilePreview.svelte | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/lib/components/chat/FileNav/FilePreview.svelte b/src/lib/components/chat/FileNav/FilePreview.svelte index cd68692495..c4b73e5108 100644 --- a/src/lib/components/chat/FileNav/FilePreview.svelte +++ b/src/lib/components/chat/FileNav/FilePreview.svelte @@ -5,6 +5,7 @@ import DOMPurify from 'dompurify'; import { settings } from '$lib/stores'; import { isCodeFile, highlightCode } from '$lib/utils/codeHighlight'; + import { initMermaid, renderMermaidDiagram } from '$lib/utils'; import Spinner from '../../common/Spinner.svelte'; import PDFViewer from '../../common/PDFViewer.svelte'; import JsonTreeView from './JsonTreeView.svelte'; @@ -92,6 +93,41 @@ ? DOMPurify.sanitize(marked.parse(fileContent, { async: false }) as string) : ''; + let markdownEl: HTMLDivElement; + let mermaidInstance: any = null; + + const renderMermaidBlocks = async (el: HTMLDivElement) => { + if (!el) return; + const codeEls = el.querySelectorAll('code.language-mermaid'); + if (codeEls.length === 0) return; + + if (!mermaidInstance) { + mermaidInstance = await initMermaid(); + } + + for (const codeEl of codeEls) { + const pre = codeEl.parentElement; + if (!pre || pre.tagName !== 'PRE' || pre.dataset.mermaidRendered) continue; + pre.dataset.mermaidRendered = 'true'; + + try { + const svg = await renderMermaidDiagram(mermaidInstance, codeEl.textContent ?? ''); + if (svg) { + const wrapper = document.createElement('div'); + wrapper.className = 'mermaid-diagram flex justify-center py-2'; + wrapper.innerHTML = svg; + pre.replaceWith(wrapper); + } + } catch (e) { + console.error('Mermaid render error:', e); + } + } + }; + + $: if (renderedHtml && markdownEl) { + tick().then(() => renderMermaidBlocks(markdownEl)); + } + // Simple CSV parser that handles quoted fields const parseCsv = (text: string, delimiter: string): string[][] => { const rows: string[][] = []; @@ -341,7 +377,7 @@ title="HTML Preview" /> {:else if isMarkdown && !showRaw} -
+
{@html renderedHtml}
{:else if isCsv && !showRaw && csvRows.length > 0} From 8cd2157564c6e8a531e6d2f32c4a34ac13a3cd83 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Thu, 5 Mar 2026 23:02:00 +0100 Subject: [PATCH 0742/1854] Perf: precompile katex unicode regex (#22196) * perf: pre-compile KaTeX Unicode regex at module load time The katexStart() function was creating a new RegExp with Unicode property escapes (\p{Script=Han}, \p{Script=Hiragana}, etc.) on every invocation. Unicode property escapes are extremely expensive to compile as the regex engine must build character class tables covering tens of thousands of code points. Since marked calls the start() function at every character position while scanning source text, this meant hundreds of regex compilations per marked.lexer() call, and lexer runs ~60 times/sec during streaming. Profiling showed KaTeX regex consuming 87% (320ms/365ms) of total markdown rendering time. Changes: - Pre-compile SURROUNDING_CHARS_REGEX once at module load time - Use .test() instead of .match() to avoid array allocations - Fix delimiter search to find earliest match, not last match * perf: replace katexStart with single-pass character scan The katexStart() function was the dominant cost in marked's lexer, consuming 55-58% of total markdown rendering time per profiling. It was called at every character position by marked and each call: - Looped through 3-5 delimiters, each doing indexOf() on the full remaining source (3-5 x O(n) string scans per call) - Ran the complex ruleReg regex with Unicode lookaheads for validation - On failed validation, created substrings and looped again Replace with a single linear character scan using charCodeAt that: - Checks only for $ (charCode 36) or backslash (charCode 92) - Filters backslash hits by next character to avoid false positives - Preserves the surrounding-character validation - Returns immediately on first valid candidate - Lets the tokenizer handle full validation (it already does this) This reduces start() from O(n * delimiters * retries) to O(n) with a very small constant factor per call. * Update katex-extension.ts --- src/lib/utils/marked/katex-extension.ts | 61 ++++++++++--------------- 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/src/lib/utils/marked/katex-extension.ts b/src/lib/utils/marked/katex-extension.ts index dd755066ce..13860fab30 100644 --- a/src/lib/utils/marked/katex-extension.ts +++ b/src/lib/utils/marked/katex-extension.ts @@ -13,6 +13,12 @@ const ALLOWED_SURROUNDING_CHARS = '\\s。,、、;;„“‘’“”()「」『』[]《》【】‹›«»…⋯::?!~⇒?!-\\/:-@\\[-`{-~\\p{Script=Han}\\p{Script=Hiragana}\\p{Script=Katakana}\\p{Script=Hangul}'; // Modified to fit more formats in different languages. Originally: '\\s?。,、;!-\\/:-@\\[-`{-~\\p{Script=Han}\\p{Script=Hiragana}\\p{Script=Katakana}\\p{Script=Hangul}'; +// Pre-compile the surrounding character regex once at module load time. +// This regex uses Unicode property escapes (\p{Script=Han}, etc.) which are +// extremely expensive to compile - doing so on every call caused ~87% of +// markdown rendering time to be spent in KaTeX regex compilation. +const ALLOWED_SURROUNDING_CHARS_REGEX = new RegExp(`[${ALLOWED_SURROUNDING_CHARS}]`, 'u'); + // const DELIMITER_LIST = [ // { left: '$$', right: '$$', display: false }, // { left: '$', right: '$', display: false }, @@ -67,48 +73,31 @@ export default function (options = {}) { } function katexStart(src, displayMode: boolean) { - const ruleReg = displayMode ? blockRule : inlineRule; + for (let i = 0; i < src.length; i++) { + const ch = src.charCodeAt(i); - let indexSrc = src; - - while (indexSrc) { - let index = -1; - let startIndex = -1; - let startDelimiter = ''; - let endDelimiter = ''; - for (const delimiter of DELIMITER_LIST) { - if (delimiter.display !== displayMode) { + if (ch === 36 /* $ */) { + // Display mode requires $$, skip single $ for display + if (displayMode && src.charAt(i + 1) !== '$') { continue; } - - startIndex = indexSrc.indexOf(delimiter.left); - if (startIndex === -1) { - continue; + if (i === 0 || ALLOWED_SURROUNDING_CHARS_REGEX.test(src.charAt(i - 1))) { + return i; } - - index = startIndex; - startDelimiter = delimiter.left; - endDelimiter = delimiter.right; - } - - if (index === -1) { - return; - } - - // Check if the delimiter is preceded by a special character. - // If it does, then it's potentially a math formula. - const f = - index === 0 || - indexSrc.charAt(index - 1).match(new RegExp(`[${ALLOWED_SURROUNDING_CHARS}]`, 'u')); - if (f) { - const possibleKatex = indexSrc.substring(index); - - if (possibleKatex.match(ruleReg)) { - return index; + } else if (ch === 92 /* \ */) { + const next = src.charAt(i + 1); + // Only consider \ if followed by a valid math delimiter start + if (displayMode) { + // Display: \[ or \begin{equation} + if (next !== '[' && next !== 'b') continue; + } else { + // Inline: \( or \ce{ or \pu{ + if (next !== '(' && next !== 'c' && next !== 'p') continue; + } + if (i === 0 || ALLOWED_SURROUNDING_CHARS_REGEX.test(src.charAt(i - 1))) { + return i; } } - - indexSrc = indexSrc.substring(index + startDelimiter.length).replace(endDelimiter, ''); } } From 4b3ed3e802d6f2ec8ee7caf358af810b7d09f789 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 5 Mar 2026 16:08:11 -0600 Subject: [PATCH 0743/1854] feat: notebook per-cell execution via open-terminal REST endpoints - Add notebook API functions (createNotebookSession, executeNotebookCell, stopNotebookSession) - Create CellEditor component with CodeMirror for cell editing - Rewrite NotebookView with session-based execution, Run All, Restart, Stop - Kernel status indicator with tooltips - Wire baseUrl/apiKey through FilePreview and FileNav --- src/lib/apis/terminal/index.ts | 78 ++++ src/lib/components/chat/FileNav.svelte | 2 + .../components/chat/FileNav/CellEditor.svelte | 109 ++++++ .../chat/FileNav/FilePreview.svelte | 6 +- .../chat/FileNav/NotebookView.svelte | 361 ++++++++++++++++-- 5 files changed, 523 insertions(+), 33 deletions(-) create mode 100644 src/lib/components/chat/FileNav/CellEditor.svelte diff --git a/src/lib/apis/terminal/index.ts b/src/lib/apis/terminal/index.ts index b1a0e7acf9..748ada33a0 100644 --- a/src/lib/apis/terminal/index.ts +++ b/src/lib/apis/terminal/index.ts @@ -258,3 +258,81 @@ export const getListeningPorts = async ( export const getPortProxyUrl = (baseUrl: string, port: number, path: string = ''): string => { return `${baseUrl.replace(/\/$/, '')}/proxy/${port}/${path}`; }; + +// --------------------------------------------------------------------------- +// Notebook execution +// --------------------------------------------------------------------------- + +export const createNotebookSession = async ( + baseUrl: string, + apiKey: string, + path: string +): Promise<{ id: string; kernel: string; status: string } | { error: string }> => { + const url = `${baseUrl.replace(/\/$/, '')}/notebooks`; + const res = await fetch(url, { + method: 'POST', + headers: { + Authorization: `Bearer ${apiKey}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ path }) + }) + .then(async (res) => { + if (!res.ok) { + const body = await res.json().catch(() => ({})); + return { error: body?.detail ?? `HTTP ${res.status}` }; + } + return res.json(); + }) + .catch((err) => { + console.error('open-terminal createNotebookSession error:', err); + return { error: 'Connection failed' }; + }); + return res; +}; + +export const executeNotebookCell = async ( + baseUrl: string, + apiKey: string, + sessionId: string, + cellIndex: number, + source?: string +): Promise<{ status: string; execution_count?: number; outputs: any[] } | { error: string }> => { + const url = `${baseUrl.replace(/\/$/, '')}/notebooks/${sessionId}/execute`; + const body: Record = { cell_index: cellIndex }; + if (source !== undefined) body.source = source; + + const res = await fetch(url, { + method: 'POST', + headers: { + Authorization: `Bearer ${apiKey}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify(body) + }) + .then(async (res) => { + if (!res.ok) { + const body = await res.json().catch(() => ({})); + return { error: body?.detail ?? `HTTP ${res.status}` }; + } + return res.json(); + }) + .catch((err) => { + console.error('open-terminal executeNotebookCell error:', err); + return { error: 'Connection failed' }; + }); + return res; +}; + +export const stopNotebookSession = async ( + baseUrl: string, + apiKey: string, + sessionId: string +): Promise => { + const url = `${baseUrl.replace(/\/$/, '')}/notebooks/${sessionId}`; + const res = await fetch(url, { + method: 'DELETE', + headers: { Authorization: `Bearer ${apiKey}` } + }).catch(() => null); + return res?.ok ?? false; +}; diff --git a/src/lib/components/chat/FileNav.svelte b/src/lib/components/chat/FileNav.svelte index 7e9e977e67..12d0c9daf3 100644 --- a/src/lib/components/chat/FileNav.svelte +++ b/src/lib/components/chat/FileNav.svelte @@ -845,6 +845,8 @@ const result = await excelToTable(excelWorkbook.Sheets[sheet]); fileOfficeHtml = result.html; }} + baseUrl={selectedTerminal?.url ?? ''} + apiKey={selectedTerminal?.key ?? ''} {overlay} onSave={async (content) => { const terminal = selectedTerminal; diff --git a/src/lib/components/chat/FileNav/CellEditor.svelte b/src/lib/components/chat/FileNav/CellEditor.svelte new file mode 100644 index 0000000000..f39b3bba33 --- /dev/null +++ b/src/lib/components/chat/FileNav/CellEditor.svelte @@ -0,0 +1,109 @@ + + +
+ + diff --git a/src/lib/components/chat/FileNav/FilePreview.svelte b/src/lib/components/chat/FileNav/FilePreview.svelte index c4b73e5108..5b23dc4df2 100644 --- a/src/lib/components/chat/FileNav/FilePreview.svelte +++ b/src/lib/components/chat/FileNav/FilePreview.svelte @@ -25,6 +25,10 @@ export let fileSqliteData: ArrayBuffer | null = null; export let fileContent: string | null = null; + // Terminal connection for notebook execution + export let baseUrl: string = ''; + export let apiKey: string = ''; + // Office preview props export let fileOfficeHtml: string | null = null; export let fileOfficeSlides: string[] | null = null; @@ -409,7 +413,7 @@
{:else if isNotebook && !showRaw && parsedNotebook}
- +
{:else if isJson && !showRaw && parsedJson !== undefined}
diff --git a/src/lib/components/chat/FileNav/NotebookView.svelte b/src/lib/components/chat/FileNav/NotebookView.svelte index 5c88abd0c4..a3ea8279ce 100644 --- a/src/lib/components/chat/FileNav/NotebookView.svelte +++ b/src/lib/components/chat/FileNav/NotebookView.svelte @@ -1,12 +1,23 @@
+ + {#if baseUrl && apiKey && filePath} +
+ + {#if kernelReady} + + + {/if} + +
+ +
+ {#if kernelStarting} + + {:else if runningCell !== null} + + {:else if kernelReady} + + {:else} + + {/if} +
+
+ + {#if kernelError} +
+ {kernelError} +
+ {/if} + {/if} + + {#each cells as cell, i}
{#if cell.cell_type === 'markdown'} -
- {@html renderMarkdown(toStr(cell.source))} -
+ {#if editingCell[i]} + + {:else} + +
startEditing(i)} + > + {@html renderMarkdown(toStr(cell.source))} +
+ {/if} {:else if cell.cell_type === 'code'}
-
- {#if cell.execution_count !== undefined && cell.execution_count !== null} - [{cell.execution_count}] - {:else} - [ ] +
+ {#if runningCell === i} +
+ {:else if baseUrl && apiKey && filePath} + {/if} +
+ {#if cell.execution_count !== undefined && cell.execution_count !== null} + [{cell.execution_count}] + {:else} + [ ] + {/if} +
- {#if highlightedCells[i]} -
- {@html highlightedCells[i]} -
+ {#if editingCell[i]} + { editedSources[i] = e.detail; }} + on:run={() => runCell(i)} + on:cancel={() => cancelEditing(i)} + /> {:else} -
{toStr(cell.source)}
+ +
startEditing(i)} + > + {#if highlightedCells[i]} +
+ {@html highlightedCells[i]} +
+ {:else} +
{toStr(cell.source)}
+ {/if} +
{/if} {#if cell.outputs && cell.outputs.length > 0} @@ -153,9 +363,37 @@ diff --git a/src/lib/components/chat/FileNav/FilePreview.svelte b/src/lib/components/chat/FileNav/FilePreview.svelte index 5b23dc4df2..0230017814 100644 --- a/src/lib/components/chat/FileNav/FilePreview.svelte +++ b/src/lib/components/chat/FileNav/FilePreview.svelte @@ -4,15 +4,17 @@ import { marked } from 'marked'; import DOMPurify from 'dompurify'; import { settings } from '$lib/stores'; - import { isCodeFile, highlightCode } from '$lib/utils/codeHighlight'; + import { isCodeFile } from '$lib/utils/codeHighlight'; import { initMermaid, renderMermaidDiagram } from '$lib/utils'; import Spinner from '../../common/Spinner.svelte'; import PDFViewer from '../../common/PDFViewer.svelte'; import JsonTreeView from './JsonTreeView.svelte'; import NotebookView from './NotebookView.svelte'; import SqliteView from './SqliteView.svelte'; + import FileCodeEditor from './FileCodeEditor.svelte'; let pdfViewerRef: PDFViewer; + let fileCodeEditorRef: FileCodeEditor; const i18n = getContext('i18n'); @@ -76,6 +78,15 @@ editContent = ''; }; + /** Save code file directly from CodeMirror */ + export const saveCodeFile = async () => { + if (!onSave) return; + saving = true; + const content = fileCodeEditorRef?.getValue() ?? ''; + await onSave(content); + saving = false; + }; + $: isTextFile = fileContent !== null && fileImageUrl === null && filePdfData === null; const MD_EXTS = new Set(['md', 'markdown', 'mdx']); @@ -175,24 +186,21 @@ $: csvHeader = csvRows.length > 0 ? csvRows[0] : []; $: csvBody = csvRows.length > 1 ? csvRows.slice(1) : []; - // ── Shiki code highlighting ───────────────────────────────────────── + // ── Shiki code highlighting (SVG only) ────────────────────────────── let highlightedHtml: string | null = null; - let highlightingFile: string | null = null; // track which file we're highlighting + let highlightingFile: string | null = null; - $: if ((isCode || isSvg) && fileContent !== null && selectedFile) { + $: if (isSvg && fileContent !== null && selectedFile) { const currentFile = selectedFile; highlightingFile = currentFile; - const lang = isSvg ? 'xml' : undefined; - (lang - ? import('shiki').then(({ codeToHtml }) => - codeToHtml(fileContent!, { - lang: 'xml', - themes: { light: 'github-light', dark: 'github-dark' }, - defaultColor: 'light' - }) - ) - : highlightCode(fileContent!, selectedFile!) - ) + import('shiki') + .then(({ codeToHtml }) => + codeToHtml(fileContent!, { + lang: 'xml', + themes: { light: 'github-light', dark: 'github-dark' }, + defaultColor: 'light' + }) + ) .then((html) => { if (highlightingFile === currentFile) highlightedHtml = html; }) @@ -428,7 +436,16 @@
{@html DOMPurify.sanitize(fileContent, { USE_PROFILES: { svg: true, svgFilters: true }, ADD_TAGS: ['use'] })}
- {:else if (isCode || isSvg) && highlightedHtml && !showRaw} + {:else if isCode && !showRaw} +
+ +
+ {:else if isSvg && highlightedHtml && !showRaw}
{@html highlightedHtml}
From 80376a3fdc06b15541264f1229cde7542ec2619f Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Fri, 6 Mar 2026 15:05:36 -0600 Subject: [PATCH 0767/1854] revert --- backend/open_webui/routers/retrieval.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/backend/open_webui/routers/retrieval.py b/backend/open_webui/routers/retrieval.py index a6f7cb32dd..46725ea901 100644 --- a/backend/open_webui/routers/retrieval.py +++ b/backend/open_webui/routers/retrieval.py @@ -1055,10 +1055,27 @@ async def update_rag_config( ) # File upload settings - request.app.state.config.FILE_MAX_SIZE = form_data.FILE_MAX_SIZE - request.app.state.config.FILE_MAX_COUNT = form_data.FILE_MAX_COUNT - request.app.state.config.FILE_IMAGE_COMPRESSION_WIDTH = form_data.FILE_IMAGE_COMPRESSION_WIDTH - request.app.state.config.FILE_IMAGE_COMPRESSION_HEIGHT = form_data.FILE_IMAGE_COMPRESSION_HEIGHT + request.app.state.config.FILE_MAX_SIZE = ( + form_data.FILE_MAX_SIZE + if form_data.FILE_MAX_SIZE is not None + else request.app.state.config.FILE_MAX_SIZE + ) + request.app.state.config.FILE_MAX_COUNT = ( + form_data.FILE_MAX_COUNT + if form_data.FILE_MAX_COUNT is not None + else request.app.state.config.FILE_MAX_COUNT + ) + request.app.state.config.FILE_IMAGE_COMPRESSION_WIDTH = ( + form_data.FILE_IMAGE_COMPRESSION_WIDTH + if form_data.FILE_IMAGE_COMPRESSION_WIDTH is not None + else request.app.state.config.FILE_IMAGE_COMPRESSION_WIDTH + ) + request.app.state.config.FILE_IMAGE_COMPRESSION_HEIGHT = ( + form_data.FILE_IMAGE_COMPRESSION_HEIGHT + if form_data.FILE_IMAGE_COMPRESSION_HEIGHT is not None + else request.app.state.config.FILE_IMAGE_COMPRESSION_HEIGHT + ) + request.app.state.config.ALLOWED_FILE_EXTENSIONS = ( form_data.ALLOWED_FILE_EXTENSIONS if form_data.ALLOWED_FILE_EXTENSIONS is not None From 73b69ae408431c925c765178ebd647d2ae20fc98 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Fri, 6 Mar 2026 15:13:21 -0600 Subject: [PATCH 0768/1854] refac --- backend/open_webui/routers/retrieval.py | 46 +++++++++---------- .../admin/Settings/Documents.svelte | 6 +++ 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/backend/open_webui/routers/retrieval.py b/backend/open_webui/routers/retrieval.py index 46725ea901..3aec9c274e 100644 --- a/backend/open_webui/routers/retrieval.py +++ b/backend/open_webui/routers/retrieval.py @@ -729,10 +729,10 @@ class ConfigForm(BaseModel): CHUNK_OVERLAP: Optional[int] = None # File upload settings - FILE_MAX_SIZE: Optional[int] = None - FILE_MAX_COUNT: Optional[int] = None - FILE_IMAGE_COMPRESSION_WIDTH: Optional[int] = None - FILE_IMAGE_COMPRESSION_HEIGHT: Optional[int] = None + FILE_MAX_SIZE: Optional[Union[int, str]] = None + FILE_MAX_COUNT: Optional[Union[int, str]] = None + FILE_IMAGE_COMPRESSION_WIDTH: Optional[Union[int, str]] = None + FILE_IMAGE_COMPRESSION_HEIGHT: Optional[Union[int, str]] = None ALLOWED_FILE_EXTENSIONS: Optional[List[str]] = None # Integration settings @@ -1055,26 +1055,24 @@ async def update_rag_config( ) # File upload settings - request.app.state.config.FILE_MAX_SIZE = ( - form_data.FILE_MAX_SIZE - if form_data.FILE_MAX_SIZE is not None - else request.app.state.config.FILE_MAX_SIZE - ) - request.app.state.config.FILE_MAX_COUNT = ( - form_data.FILE_MAX_COUNT - if form_data.FILE_MAX_COUNT is not None - else request.app.state.config.FILE_MAX_COUNT - ) - request.app.state.config.FILE_IMAGE_COMPRESSION_WIDTH = ( - form_data.FILE_IMAGE_COMPRESSION_WIDTH - if form_data.FILE_IMAGE_COMPRESSION_WIDTH is not None - else request.app.state.config.FILE_IMAGE_COMPRESSION_WIDTH - ) - request.app.state.config.FILE_IMAGE_COMPRESSION_HEIGHT = ( - form_data.FILE_IMAGE_COMPRESSION_HEIGHT - if form_data.FILE_IMAGE_COMPRESSION_HEIGHT is not None - else request.app.state.config.FILE_IMAGE_COMPRESSION_HEIGHT - ) + # Empty string means "clear to None" (unlimited/no compression), + # None means "don't change", int means "set to this value" + if form_data.FILE_MAX_SIZE is not None: + request.app.state.config.FILE_MAX_SIZE = ( + None if form_data.FILE_MAX_SIZE == '' else form_data.FILE_MAX_SIZE + ) + if form_data.FILE_MAX_COUNT is not None: + request.app.state.config.FILE_MAX_COUNT = ( + None if form_data.FILE_MAX_COUNT == '' else form_data.FILE_MAX_COUNT + ) + if form_data.FILE_IMAGE_COMPRESSION_WIDTH is not None: + request.app.state.config.FILE_IMAGE_COMPRESSION_WIDTH = ( + None if form_data.FILE_IMAGE_COMPRESSION_WIDTH == '' else form_data.FILE_IMAGE_COMPRESSION_WIDTH + ) + if form_data.FILE_IMAGE_COMPRESSION_HEIGHT is not None: + request.app.state.config.FILE_IMAGE_COMPRESSION_HEIGHT = ( + None if form_data.FILE_IMAGE_COMPRESSION_HEIGHT == '' else form_data.FILE_IMAGE_COMPRESSION_HEIGHT + ) request.app.state.config.ALLOWED_FILE_EXTENSIONS = ( form_data.ALLOWED_FILE_EXTENSIONS diff --git a/src/lib/components/admin/Settings/Documents.svelte b/src/lib/components/admin/Settings/Documents.svelte index 78e300ae04..ece64afd54 100644 --- a/src/lib/components/admin/Settings/Documents.svelte +++ b/src/lib/components/admin/Settings/Documents.svelte @@ -221,6 +221,12 @@ const res = await updateRAGConfig(localStorage.token, { ...RAGConfig, + // Convert null (from cleared number inputs) to empty string so the backend + // can distinguish "clear this field" from "don't change this field" + FILE_MAX_SIZE: RAGConfig.FILE_MAX_SIZE ?? '', + FILE_MAX_COUNT: RAGConfig.FILE_MAX_COUNT ?? '', + FILE_IMAGE_COMPRESSION_WIDTH: RAGConfig.FILE_IMAGE_COMPRESSION_WIDTH ?? '', + FILE_IMAGE_COMPRESSION_HEIGHT: RAGConfig.FILE_IMAGE_COMPRESSION_HEIGHT ?? '', ALLOWED_FILE_EXTENSIONS: RAGConfig.ALLOWED_FILE_EXTENSIONS.split(',') .map((ext) => ext.trim()) .filter((ext) => ext !== ''), From 016928722c7a601ea8de003d91b28f5942515292 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Fri, 6 Mar 2026 15:23:29 -0600 Subject: [PATCH 0769/1854] refac --- src/lib/components/chat/ChatControls.svelte | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/components/chat/ChatControls.svelte b/src/lib/components/chat/ChatControls.svelte index 2f5aec4b09..0abefe2aae 100644 --- a/src/lib/components/chat/ChatControls.svelte +++ b/src/lib/components/chat/ChatControls.svelte @@ -342,7 +342,7 @@ ? 'h-full' : activeTab === 'controls' ? 'overflow-y-auto px-3 pt-1' - : 'overflow-y-auto'}" + : ''}" > {#if activeTab === 'overview'} {#if $showCallOverlay} @@ -483,7 +483,7 @@ ? 'h-full' : activeTab === 'controls' ? 'overflow-y-auto px-3 pt-1' - : 'overflow-y-auto'}" + : ''}" > {#if activeTab === 'overview'} Date: Fri, 6 Mar 2026 15:29:38 -0600 Subject: [PATCH 0770/1854] refac --- .../layout/Sidebar/PinnedModelList.svelte | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/lib/components/layout/Sidebar/PinnedModelList.svelte b/src/lib/components/layout/Sidebar/PinnedModelList.svelte index da35a3df3d..235dda9034 100644 --- a/src/lib/components/layout/Sidebar/PinnedModelList.svelte +++ b/src/lib/components/layout/Sidebar/PinnedModelList.svelte @@ -37,6 +37,20 @@ let unsubscribeSettings; + const cleanupStalePinnedModels = async (modelIds) => { + const validModels = modelIds.filter((id) => { + const model = $models.find((m) => m.id === id); + // Remove if model not found (deleted) or if hidden + return model && !(model?.info?.meta?.hidden ?? false); + }); + + if (validModels.length !== modelIds.length) { + pinnedModels = validModels; + settings.set({ ...$settings, pinnedModels: validModels }); + await updateUserSettings(localStorage.token, { ui: $settings }); + } + }; + onMount(async () => { pinnedModels = $settings?.pinnedModels ?? []; @@ -48,6 +62,11 @@ await updateUserSettings(localStorage.token, { ui: $settings }); } + // Auto-unpin hidden or deleted models + if (pinnedModels.length > 0) { + await cleanupStalePinnedModels(pinnedModels); + } + unsubscribeSettings = settings.subscribe((value) => { pinnedModels = value?.pinnedModels ?? []; }); From 576ee9243890e612652886d46c464e86b4f1a6f4 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Fri, 6 Mar 2026 22:36:13 +0100 Subject: [PATCH 0771/1854] perf: rewrite createMessagesList from recursive to iterative (#22194) Replace the recursive spread-based implementation with an iterative push+reverse approach. The recursive version created a new array at each level of recursion via spread, resulting in O(d^2) array copies where d is the conversation depth. The iterative version walks from the target message to the root, pushes each message, and reverses once at the end for O(d) total work. No behavioral change - same input produces the same output array. --- src/lib/utils/index.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index 4a1cf2e919..18c5c6b674 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -1181,19 +1181,19 @@ export const getWeekday = () => { }; export const createMessagesList = (history, messageId) => { - if (messageId === null) { - return []; + const list = []; + let currentId = messageId; + + while (currentId !== null && currentId !== undefined) { + const message = history.messages[currentId]; + if (message === undefined) { + break; + } + list.push(message); + currentId = message.parentId; } - const message = history.messages[messageId]; - if (message === undefined) { - return []; - } - if (message?.parentId) { - return [...createMessagesList(history, message.parentId), message]; - } else { - return [message]; - } + return list.reverse(); }; export const formatFileSize = (size) => { From 4ab831b2596f92fc247c8d788f584ae82d63a88d Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Fri, 6 Mar 2026 15:42:13 -0600 Subject: [PATCH 0772/1854] refac --- backend/open_webui/utils/middleware.py | 35 +++++++++++++------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 53d1a54859..27323742a4 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -4163,25 +4163,26 @@ async def streaming_chat_response_handler(response, ctx): tool_args = tool_call.get("function", {}).get("arguments", "{}") tool_function_params = {} - try: - # json.loads cannot be used because some models do not produce valid JSON - tool_function_params = ast.literal_eval(tool_args) - except Exception as e: - log.debug(e) - # Fallback to JSON parsing + if tool_args and tool_args.strip(): try: - tool_function_params = json.loads(tool_args) + # json.loads cannot be used because some models do not produce valid JSON + tool_function_params = ast.literal_eval(tool_args) except Exception as e: - log.error( - f"Error parsing tool call arguments: {tool_args}" - ) - results.append( - { - "tool_call_id": tool_call_id, - "content": f"Error: Tool call arguments could not be parsed. The model generated malformed or incomplete JSON for `{tool_function_name}`. Please try again.", - } - ) - continue + log.debug(e) + # Fallback to JSON parsing + try: + tool_function_params = json.loads(tool_args) + except Exception as e: + log.error( + f"Error parsing tool call arguments: {tool_args}" + ) + results.append( + { + "tool_call_id": tool_call_id, + "content": f"Error: Tool call arguments could not be parsed. The model generated malformed or incomplete JSON for `{tool_function_name}`. Please try again.", + } + ) + continue # Ensure arguments are valid JSON for downstream LLM integrations log.debug( From 200fb093b10af0dc02c185b29b686d9c780608ee Mon Sep 17 00:00:00 2001 From: Shirasawa <764798966@qq.com> Date: Sat, 7 Mar 2026 05:48:44 +0800 Subject: [PATCH 0773/1854] fix: Use toBlob on first mobile export to avoid black canvas image on Android (#22317) --- src/lib/utils/index.ts | 53 +++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index 18c5c6b674..3b8a6a3d72 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -275,11 +275,50 @@ export const canvasPixelTest = () => { return true; }; + +let resizeImageWarmupDone = false; +/** + * Draws an image to a canvas at the given dimensions and returns a data URL. + * On mobile, the first export uses toBlob (avoids black image on Android); later exports use toDataURL. + */ +async function resizeImageToDataURL( + img: HTMLImageElement, + width: number, + height: number, + mimeType = 'image/jpeg', +): Promise { + const canvas = document.createElement('canvas'); + canvas.width = width; + canvas.height = height; + canvas.getContext('2d')?.drawImage(img, 0, 0, width, height); + + const toDataURL = () => canvas.toDataURL(mimeType); + + if (!resizeImageWarmupDone && canvas.toBlob && /android|iphone|ipad|ipod/i.test(navigator?.userAgent)) { + resizeImageWarmupDone = true; + return new Promise((resolve) => { + canvas.toBlob( + (blob) => { + if (!blob) { + resolve(toDataURL()); + return; + } + const reader = new FileReader(); + reader.onload = () => resolve(String(reader.result)); + reader.onerror = () => resolve(toDataURL()); + reader.readAsDataURL(blob); + }, + mimeType, + ); + }); + } + return Promise.resolve(toDataURL()); +} + export const compressImage = async (imageUrl, maxWidth, maxHeight) => { return new Promise((resolve, reject) => { const img = new Image(); img.onload = () => { - const canvas = document.createElement('canvas'); let width = img.width; let height = img.height; @@ -322,16 +361,8 @@ export const compressImage = async (imageUrl, maxWidth, maxHeight) => { height = maxHeight; } - canvas.width = width; - canvas.height = height; - - const context = canvas.getContext('2d'); - context.drawImage(img, 0, 0, width, height); - - // Get compressed image URL - const mimeType = imageUrl.match(/^data:([^;]+);/)?.[1]; - const compressedUrl = canvas.toDataURL(mimeType); - resolve(compressedUrl); + const mimeType = imageUrl.match(/^data:([^;]+);/)?.[1] ?? 'image/jpeg'; + resolve(await resizeImageToDataURL(img, width, height, mimeType)); }; img.onerror = (error) => reject(error); img.src = imageUrl; From d93cb3658dae98499af10946444de54b572e8e71 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Fri, 6 Mar 2026 22:56:01 +0100 Subject: [PATCH 0774/1854] perf(models): batch-fetch function valves to eliminate N+1 queries (#22301) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf(models): batch-fetch function valves to eliminate N+1 queries get_action_priority() called Functions.get_function_valves_by_id() individually for every action on every model — an N+1 query pattern that issued one DB round-trip per (action x model) pair. Add Functions.get_function_valves_by_ids() that fetches all valves in a single WHERE IN query, then look up each action's valves from the pre-fetched dict inside get_action_priority(). No functional change — same priority resolution, same sort order. * Update models.py * Update models.py --- backend/open_webui/models/functions.py | 25 +++++++++++++++++++++++++ backend/open_webui/utils/models.py | 8 +++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/backend/open_webui/models/functions.py b/backend/open_webui/models/functions.py index fdbfac5e7c..bca1223b72 100644 --- a/backend/open_webui/models/functions.py +++ b/backend/open_webui/models/functions.py @@ -308,6 +308,31 @@ class FunctionsTable: log.exception(f"Error getting function valves by id {id}: {e}") return None + def get_function_valves_by_ids( + self, ids: list[str], db: Optional[Session] = None + ) -> dict[str, dict]: + """ + Batch fetch valves for multiple functions in a single query. + Returns a dict mapping function_id -> valves dict. + Functions without valves are mapped to {}. + """ + if not ids: + return {} + try: + with get_db_context(db) as db: + functions = ( + db.query(Function.id, Function.valves) + .filter(Function.id.in_(ids)) + .all() + ) + return { + f.id: (f.valves if f.valves else {}) for f in functions + } + except Exception as e: + log.exception(f"Error batch-fetching function valves: {e}") + return {} + + def update_function_valves_by_id( self, id: str, valves: dict, db: Optional[Session] = None ) -> Optional[FunctionValves]: diff --git a/backend/open_webui/utils/models.py b/backend/open_webui/utils/models.py index 6c82b4aa98..ebf855d2cc 100644 --- a/backend/open_webui/utils/models.py +++ b/backend/open_webui/utils/models.py @@ -331,11 +331,17 @@ async def get_all_models(request, refresh: bool = False, user: UserModel = None) elif meta.get(key) is None: meta[key] = copy.deepcopy(value) + # Batch-fetch all function valves in one query to avoid N+1 DB hits + # inside get_action_priority (previously called per action × per model). + all_function_valves = Functions.get_function_valves_by_ids( + list(all_function_ids) + ) + def get_action_priority(action_id): try: function_module = request.app.state.FUNCTIONS.get(action_id) if function_module and hasattr(function_module, "Valves"): - valves_db = Functions.get_function_valves_by_id(action_id) + valves_db = all_function_valves.get(action_id) valves = function_module.Valves(**(valves_db if valves_db else {})) return getattr(valves, "priority", 0) except Exception: From d8bb8c58d04ba57d34bc0543ca9de194b5f44711 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Fri, 6 Mar 2026 16:21:42 -0600 Subject: [PATCH 0775/1854] refac --- .github/pull_request_template.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 9a19bfa6b4..8726cb9990 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -88,9 +88,12 @@ This is to ensure large feature PRs are discussed with the community first, befo 🚨 DO NOT DELETE THE TEXT BELOW 🚨 Keep the "Contributor License Agreement" confirmation text intact. Deleting it will trigger the CLA-Bot to INVALIDATE your PR. + +Your PR will NOT be reviewed or merged until you check the box below confirming that you have read and agree to the terms of the CLA. --> -By submitting this pull request, I confirm that I have read and fully agree to the [Contributor License Agreement (CLA)](https://github.com/open-webui/open-webui/blob/main/CONTRIBUTOR_LICENSE_AGREEMENT), and I am providing my contributions under its terms. +- [ ] By submitting this pull request, I confirm that I have read and fully agree to the [Contributor License Agreement (CLA)](./CLA.md), and I am providing my contributions under its terms. + > [!NOTE] > Deleting the CLA section will lead to immediate closure of your PR and it will not be merged in. From b3622474d7b8de618ad0f24ed6946a96e5e333a2 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Fri, 6 Mar 2026 16:25:00 -0600 Subject: [PATCH 0776/1854] refac --- src/lib/utils/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index 3b8a6a3d72..455594b65c 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -318,7 +318,7 @@ async function resizeImageToDataURL( export const compressImage = async (imageUrl, maxWidth, maxHeight) => { return new Promise((resolve, reject) => { const img = new Image(); - img.onload = () => { + img.onload = async () => { let width = img.width; let height = img.height; From 7806cd5aef9fb0505b2c642ef70599a403cf14ba Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Fri, 6 Mar 2026 20:00:12 -0600 Subject: [PATCH 0777/1854] feat: use CodeMirror editor for HTML source view, hide save in preview mode - HTML preview (iframe) no longer shows Edit/Save toolbar buttons - Clicking Source toggle opens CodeMirror editor with syntax highlighting - Save button appears only in source mode, using saveCodeFile() - Ctrl+S saving supported via CodeMirror keybinding --- src/lib/components/chat/FileNav.svelte | 55 +++++++++++++------ .../chat/FileNav/FilePreview.svelte | 9 +++ 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/src/lib/components/chat/FileNav.svelte b/src/lib/components/chat/FileNav.svelte index fbc7568f80..80285c976b 100644 --- a/src/lib/components/chat/FileNav.svelte +++ b/src/lib/components/chat/FileNav.svelte @@ -709,24 +709,43 @@ {/if} {#if isTextFile} - {#if isCode} - - - - {:else if editing} + {#if isHtml && showRaw} + + + + {:else if isHtml} + + {:else if isCode} + + + + {:else if editing} - - {:else if isHtml} - - {:else if isCode} - - - - {:else if editing} + {#if isHtml && showRaw} + + + + {:else if isHtml} + + {:else if isCode} + + + + {:else if editing}
{:else if fileOfficeSlides !== null && fileOfficeSlides.length > 0}
-
+
Slide {currentSlide + 1}
{#if fileOfficeSlides.length > 1} -
+
{currentSlide + 1} / {fileOfficeSlides.length}
@@ -402,8 +425,8 @@ {@html renderedHtml}
{:else if isCsv && !showRaw && csvRows.length > 0} -
- +
+
@@ -439,11 +462,15 @@ {:else if isJson && !showRaw && jsonError}
JSON parse error: {jsonError}
-
{fileContent}
+
{fileContent}
{:else if isSvg && !showRaw && fileContent}
- {@html DOMPurify.sanitize(fileContent, { USE_PROFILES: { svg: true, svgFilters: true }, ADD_TAGS: ['use'] })} + {@html DOMPurify.sanitize(fileContent, { + USE_PROFILES: { svg: true, svgFilters: true }, + ADD_TAGS: ['use'] + })}
{:else if isCode && !showRaw}
@@ -631,12 +658,29 @@ max-width: 100%; height: auto; } - :global(.office-preview h1) { font-size: 1.5rem; font-weight: 700; margin: 0.75em 0 0.5em; } - :global(.office-preview h2) { font-size: 1.25rem; font-weight: 600; margin: 0.75em 0 0.5em; } - :global(.office-preview h3) { font-size: 1.1rem; font-weight: 600; margin: 0.5em 0 0.25em; } - :global(.office-preview p) { margin: 0.25em 0; } + :global(.office-preview h1) { + font-size: 1.5rem; + font-weight: 700; + margin: 0.75em 0 0.5em; + } + :global(.office-preview h2) { + font-size: 1.25rem; + font-weight: 600; + margin: 0.75em 0 0.5em; + } + :global(.office-preview h3) { + font-size: 1.1rem; + font-weight: 600; + margin: 0.5em 0 0.25em; + } + :global(.office-preview p) { + margin: 0.25em 0; + } :global(.office-preview ul), - :global(.office-preview ol) { padding-left: 1.5em; margin: 0.5em 0; } + :global(.office-preview ol) { + padding-left: 1.5em; + margin: 0.5em 0; + } /* ── Shiki code highlighting ─────────────────────────────────── */ .shiki-preview :global(pre.shiki) { margin: 0; @@ -679,4 +723,3 @@ text-decoration: var(--shiki-dark-text-decoration) !important; } - diff --git a/src/lib/components/chat/FileNav/JsonTreeView.svelte b/src/lib/components/chat/FileNav/JsonTreeView.svelte index a76f4f06e2..47e94564d6 100644 --- a/src/lib/components/chat/FileNav/JsonTreeView.svelte +++ b/src/lib/components/chat/FileNav/JsonTreeView.svelte @@ -39,7 +39,13 @@
{#each entries as [k, v], i}
- + {#if i < entries.length - 1},{/if}
{/each} diff --git a/src/lib/components/chat/FileNav/NotebookView.svelte b/src/lib/components/chat/FileNav/NotebookView.svelte index a3ea8279ce..7fcff1b8c1 100644 --- a/src/lib/components/chat/FileNav/NotebookView.svelte +++ b/src/lib/components/chat/FileNav/NotebookView.svelte @@ -38,11 +38,12 @@ $: cells = (notebook?.cells as NotebookCell[]) ?? []; $: lang = (notebook?.metadata as Record)?.kernelspec - ? ((notebook.metadata as Record>).kernelspec?.language ?? 'python') + ? ((notebook.metadata as Record>).kernelspec?.language ?? + 'python') : 'python'; const toStr = (s: string[] | string | undefined): string => - Array.isArray(s) ? s.join('') : s ?? ''; + Array.isArray(s) ? s.join('') : (s ?? ''); // ── Syntax highlighting ────────────────────────────────────────────── let highlightedCells: Record = {}; @@ -75,8 +76,7 @@ const renderMarkdown = (src: string): string => DOMPurify.sanitize(marked.parse(src, { async: false }) as string); - const stripAnsi = (s: string): string => - s.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, ''); + const stripAnsi = (s: string): string => s.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, ''); const getOutputImages = (output: NotebookOutput): string[] => { if (!output.data) return []; @@ -173,12 +173,14 @@ const result = await executeNotebookCell(baseUrl, apiKey, sessionId!, index, source); if ('error' in result) { - cells[index].outputs = [{ - output_type: 'error', - ename: 'ExecutionError', - evalue: result.error, - traceback: [result.error] - }]; + cells[index].outputs = [ + { + output_type: 'error', + ename: 'ExecutionError', + evalue: result.error, + traceback: [result.error] + } + ]; } else { cells[index].outputs = result.outputs; if (result.execution_count !== undefined) { @@ -225,7 +227,13 @@ {$i18n.t('Run All')} {#if kernelReady} -
{#if kernelError} -
+
{kernelError}
{/if} @@ -265,7 +284,9 @@ bind:value={editedSources[i]} on:input={autoResize} on:blur={() => cancelEditing(i)} - on:keydown={(e) => { if (e.key === 'Escape') cancelEditing(i); }} + on:keydown={(e) => { + if (e.key === 'Escape') cancelEditing(i); + }} > {:else} @@ -290,8 +311,19 @@ disabled={runningCell !== null} title="Run cell (⌘+Enter)" > - - + + {/if} @@ -308,7 +340,9 @@ { editedSources[i] = e.detail; }} + on:change={(e) => { + editedSources[i] = e.detail; + }} on:run={() => runCell(i)} on:cancel={() => cancelEditing(i)} /> @@ -334,7 +368,9 @@
{#each cell.outputs as output} {#if output.output_type === 'error'} -
{stripAnsi((output.traceback ?? []).join('\n') || `${output.ename}: ${output.evalue}`)}
+
{stripAnsi(
+												(output.traceback ?? []).join('\n') || `${output.ename}: ${output.evalue}`
+											)}
{:else} {@const html = getOutputHtml(output)} {@const images = getOutputImages(output)} @@ -401,10 +437,18 @@ padding-top: 0.5rem; padding-bottom: 0.5rem; } - .nb-markdown :global(h1) { font-size: 1.4rem; } - .nb-markdown :global(h2) { font-size: 1.2rem; } - .nb-markdown :global(h3) { font-size: 1.05rem; } - .nb-markdown :global(p) { margin: 0.4em 0; } + .nb-markdown :global(h1) { + font-size: 1.4rem; + } + .nb-markdown :global(h2) { + font-size: 1.2rem; + } + .nb-markdown :global(h3) { + font-size: 1.05rem; + } + .nb-markdown :global(p) { + margin: 0.4em 0; + } .nb-markdown :global(pre) { background: rgba(128, 128, 128, 0.06); padding: 0.5rem 0.75rem; @@ -495,7 +539,8 @@ background: #161b22; color: #e6edf3; } - .nb-code-textarea, .nb-edit-textarea { + .nb-code-textarea, + .nb-edit-textarea { width: 100%; padding: 0.5rem 0.75rem; font-size: 0.75rem; diff --git a/src/lib/components/chat/FileNav/PortList.svelte b/src/lib/components/chat/FileNav/PortList.svelte index 557b8150f1..8a5dfb3cd2 100644 --- a/src/lib/components/chat/FileNav/PortList.svelte +++ b/src/lib/components/chat/FileNav/PortList.svelte @@ -67,33 +67,33 @@ {$i18n.t('Ports')} - {#if ports.length > 0} - - {ports.length} - - {/if} - - - + {ports.length} + + {/if} + + + @@ -112,9 +112,7 @@ :{port.port} - + {port.process ?? ''} 0) { rows = result[0].values.map((r: any[]) => r.map((v: any) => formatValue(v))); } else { @@ -119,7 +117,9 @@ onDestroy(() => { if (db) { - try { db.close(); } catch {} + try { + db.close(); + } catch {} db = null; } }); @@ -132,7 +132,9 @@
{error}
{:else} -
+
{#each tables as table} @@ -172,9 +176,13 @@ } }} > -
+
{#if queryError} - {queryError} + {queryError} {:else} ⌘+Enter {/if} @@ -242,24 +250,50 @@ {#if totalPages > 1} -
+
{page + 1} / {totalPages} ({totalRows.toLocaleString()} rows)
diff --git a/src/lib/components/chat/Messages/ContentRenderer.svelte b/src/lib/components/chat/Messages/ContentRenderer.svelte index 8b157c8886..663fafd71c 100644 --- a/src/lib/components/chat/Messages/ContentRenderer.svelte +++ b/src/lib/components/chat/Messages/ContentRenderer.svelte @@ -205,7 +205,7 @@ ? model?.id : (selectedModels ?? []).length > 0 ? selectedModels.at(0) - : model?.id ?? null} + : (model?.id ?? null)} messages={createMessagesList(history, messageId)} onAdd={({ modelId, parentId, messages }) => { console.log(modelId, parentId, messages); diff --git a/src/lib/components/common/FileItemModal.svelte b/src/lib/components/common/FileItemModal.svelte index f61f3e1aa3..ea161a5c28 100644 --- a/src/lib/components/common/FileItemModal.svelte +++ b/src/lib/components/common/FileItemModal.svelte @@ -587,7 +587,9 @@ {#if docxError}
{docxError}
{:else if docxHtml} -
+
{@html docxHtml}
{:else} @@ -611,20 +613,39 @@ {pptxCurrentSlide + 1} / {pptxSlides.length}
diff --git a/src/lib/i18n/locales/ar-BH/translation.json b/src/lib/i18n/locales/ar-BH/translation.json index 24df9be05f..3adfdfc6d5 100644 --- a/src/lib/i18n/locales/ar-BH/translation.json +++ b/src/lib/i18n/locales/ar-BH/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "المحادثة", + "Chat archived.": "", "Chat Background Image": "", "Chat Bubble UI": "UI الدردشة", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "فشل في قراءة محتويات الحافظة", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "لا توجد نتائج", "No results found": "لا توجد نتايج", "No search query generated": "لم يتم إنشاء استعلام بحث", + "No servers detected": "", "No skills found": "", "No source available": "لا يوجد مصدر متاح", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "موقف ايجابي", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "", "RESULT": "النتيجة", "Retrieval": "", @@ -1587,6 +1595,7 @@ "Role": "منصب", "RTL": "من اليمين إلى اليسار", "Run": "", + "Run All": "", "Running": "", "Running...": "جارٍ التنفيذ...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1777,6 +1786,7 @@ "Start a new conversation": "", "Start of the channel": "بداية القناة", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2121,6 +2131,8 @@ "You're now logged in.": "لقد قمت الآن بتسجيل الدخول.", "Your Account": "", "Your account status is currently pending activation.": "", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/ar/translation.json b/src/lib/i18n/locales/ar/translation.json index d3a392666a..4d6927b51c 100644 --- a/src/lib/i18n/locales/ar/translation.json +++ b/src/lib/i18n/locales/ar/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "حد الأحرف لمدخل توليد الإكمال التلقائي", "Chart new frontiers": "رسم آفاق جديدة", "Chat": "محادثة", + "Chat archived.": "", "Chat Background Image": "صورة خلفية المحادثة", "Chat Bubble UI": "واجهة فقاعات المحادثة", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "فشل في إضافة الملف.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "فشل في قراءة محتويات الحافظة", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "لم يتم العثور على محتوى HTML أو CSS أو JavaScript.", "No inference engine with management support found": "لم يتم العثور على محرك استدلال يدعم الإدارة", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "لم يتم العثور على معرفة", "No memories to clear": "لا توجد ذاكرة لمسحها", @@ -1320,6 +1325,7 @@ "No results": "لا توجد نتائج", "No results found": "لا توجد نتايج", "No search query generated": "لم يتم إنشاء استعلام بحث", + "No servers detected": "", "No skills found": "", "No source available": "لا يوجد مصدر متاح", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "المنفذ", + "Ports": "", "Positive attitude": "موقف ايجابي", "Prefer not to say": "", "Prefix ID": "معرف البادئة", @@ -1571,6 +1578,7 @@ "Response splitting": "تقسيم الرد", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "النتيجة", "RESULT": "النتيجة", "Retrieval": "الاسترجاع", @@ -1587,6 +1595,7 @@ "Role": "منصب", "RTL": "من اليمين إلى اليسار", "Run": "تنفيذ", + "Run All": "", "Running": "جارٍ التنفيذ", "Running...": "جارٍ التنفيذ...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1777,6 +1786,7 @@ "Start a new conversation": "", "Start of the channel": "بداية القناة", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2121,6 +2131,8 @@ "You're now logged in.": "لقد قمت الآن بتسجيل الدخول.", "Your Account": "", "Your account status is currently pending activation.": "حالة حسابك حالياً بانتظار التفعيل.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "سيتم توجيه كامل مساهمتك مباشرة إلى مطور المكون الإضافي؛ لا تأخذ Open WebUI أي نسبة. ومع ذلك، قد تفرض منصة التمويل المختارة رسومًا خاصة بها.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/bg-BG/translation.json b/src/lib/i18n/locales/bg-BG/translation.json index 31a13b8893..f6792cb8fd 100644 --- a/src/lib/i18n/locales/bg-BG/translation.json +++ b/src/lib/i18n/locales/bg-BG/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Ограничение на символите за входа на генериране на автоматично довършване", "Chart new frontiers": "Начертайте нови граници", "Chat": "Чат", + "Chat archived.": "", "Chat Background Image": "Фоново изображение на чата", "Chat Bubble UI": "Потребителски интерфейс за чат балон", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "Неуспешно добавяне на файл.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Грешка при четене на съдържанието от клипборда", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "Не е намерено HTML, CSS или JavaScript съдържание.", "No inference engine with management support found": "Не е намерен механизъм за извод с поддръжка на управлението", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Не са намерени знания", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "Няма намерени резултати", "No results found": "Няма намерени резултати", "No search query generated": "Не е генерирана заявка за търсене", + "No servers detected": "", "No skills found": "", "No source available": "Няма наличен източник", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "Порт", + "Ports": "", "Positive attitude": "Позитивно отношение", "Prefer not to say": "", "Prefix ID": "Префикс ID", @@ -1571,6 +1578,7 @@ "Response splitting": "Разделяне на отговора", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "Резултат", "RESULT": "Резултат", "Retrieval": "Извличане", @@ -1583,6 +1591,7 @@ "Role": "Роля", "RTL": "RTL", "Run": "Изпълни", + "Run All": "", "Running": "Изпълнява се", "Running...": "Изпълнява се...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "Начало на канала", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "Сега вие влязохте в системата.", "Your Account": "", "Your account status is currently pending activation.": "Статусът на вашия акаунт в момента очаква активиране.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Цялата ви вноска ще отиде директно при разработчика на плъгина; Open WebUI не взима никакъв процент. Въпреки това, избраната платформа за финансиране може да има свои собствени такси.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/bn-BD/translation.json b/src/lib/i18n/locales/bn-BD/translation.json index 1c4808b5de..a348795018 100644 --- a/src/lib/i18n/locales/bn-BD/translation.json +++ b/src/lib/i18n/locales/bn-BD/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "চ্যাট", + "Chat archived.": "", "Chat Background Image": "", "Chat Bubble UI": "চ্যাট বাবল UI", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "ক্লিপবোর্ডের বিষয়বস্তু পড়া সম্ভব হয়নি", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "কোন ফলাফল পাওয়া যায়নি", "No results found": "কোন ফলাফল পাওয়া যায়নি", "No search query generated": "কোনও অনুসন্ধান ক্যোয়ারী উত্পন্ন হয়নি", + "No servers detected": "", "No skills found": "", "No source available": "কোন উৎস পাওয়া যায়নি", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "পজিটিভ আক্রমণ", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "", "RESULT": "ফলাফল", "Retrieval": "", @@ -1583,6 +1591,7 @@ "Role": "পদবি", "RTL": "RTL", "Run": "", + "Run All": "", "Running": "", "Running...": "চলমান...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "চ্যানেলের শুরু", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "আপনি এখন লগইন করা অবস্থায় আছেন", "Your Account": "", "Your account status is currently pending activation.": "", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/bo-TB/translation.json b/src/lib/i18n/locales/bo-TB/translation.json index 22991d9e4e..8288ca9fcc 100644 --- a/src/lib/i18n/locales/bo-TB/translation.json +++ b/src/lib/i18n/locales/bo-TB/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "རང་འཚང་བཟོ་སྐྲུན་ནང་འཇུག་གི་ཡིག་འབྲུ་ཚད་བཀག", "Chart new frontiers": "ས་མཚམས་གསར་པ་འགོད་པ།", "Chat": "ཁ་བརྡ།", + "Chat archived.": "", "Chat Background Image": "ཁ་བརྡའི་རྒྱབ་ལྗོངས་པར།", "Chat Bubble UI": "ཁ་བརྡའི་ལྦུ་བའི་ UI", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "ཡིག་ཆ་སྣོན་པར་མ་ཐུབ།", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "{{URL}} OpenAPI ལག་ཆའི་སར་བར་ལ་སྦྲེལ་མཐུད་བྱེད་མ་ཐུབ།", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "སྦྱར་སྡེར་གྱི་ནང་དོན་ཀློག་མ་ཐུབ།", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "HTML, CSS, ཡང་ན་ JavaScript གི་ནང་དོན་མ་རྙེད།", "No inference engine with management support found": "དོ་དམ་རྒྱབ་སྐྱོར་ཡོད་པའི་དཔོག་རྩིས་འཕྲུལ་འཁོར་མ་རྙེད།", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "ཤེས་བྱ་མ་རྙེད།", "No memories to clear": "གཙང་སེལ་བྱེད་རྒྱུའི་དྲན་ཤེས་མེད།", @@ -1320,6 +1325,7 @@ "No results": "འབྲས་བུ་མ་རྙེད།", "No results found": "འབྲས་བུ་མ་རྙེད།", "No search query generated": "འཚོལ་བཤེར་འདྲི་བ་བཟོས་མེད།", + "No servers detected": "", "No skills found": "", "No source available": "འབྱུང་ཁུངས་མེད།", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "Port", + "Ports": "", "Positive attitude": "ལྟ་སྟངས་དགེ་མཚན།", "Prefer not to say": "", "Prefix ID": "སྔོན་སྦྱོར་ ID", @@ -1571,6 +1578,7 @@ "Response splitting": "ལན་བགོ་བ།", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "འབྲས་བུ།", "RESULT": "འབྲས་བུ།", "Retrieval": "ལེན་ཚུར་སྒྲུབ།", @@ -1582,6 +1590,7 @@ "Role": "གནས་ཚད།", "RTL": "RTL", "Run": "ལག་བསྟར།", + "Run All": "", "Running": "ལག་བསྟར་བྱེད་བཞིན་པ།", "Running...": "ལག་བསྟར་བྱེད་བཞིན་པ།...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1772,6 +1781,7 @@ "Start a new conversation": "", "Start of the channel": "རྒྱས་ལམ་འགོ་རིམ་", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2116,6 +2126,8 @@ "You're now logged in.": "ཁྱེད་ད་ལྟ་ནང་འཛུལ་བྱས་ཟིན།", "Your Account": "", "Your account status is currently pending activation.": "ཁྱེད་ཀྱི་རྩིས་ཁྲའི་གནས་སྟངས་ད་ལྟ་སྒུལ་བསྐྱོད་སྒུག་བཞིན་པ།", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "ཁྱེད་ཀྱི་ཞལ་འདེབས་ཆ་ཚང་ཐད་ཀར་ plugin གསར་སྤེལ་བ་ལ་འགྲོ་ངེས། Open WebUI ཡིས་བརྒྱ་ཆ་གང་ཡང་མི་ལེན། འོན་ཀྱང་། གདམ་ཟིན་པའི་མ་དངུལ་གཏོང་བའི་སྟེགས་བུ་ལ་དེའི་རང་གི་འགྲོ་གྲོན་ཡོད་སྲིད།", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/bs-BA/translation.json b/src/lib/i18n/locales/bs-BA/translation.json index 7ad5248c05..bc8773f0d1 100644 --- a/src/lib/i18n/locales/bs-BA/translation.json +++ b/src/lib/i18n/locales/bs-BA/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "Razgovor", + "Chat archived.": "", "Chat Background Image": "", "Chat Bubble UI": "Razgovor - Bubble UI", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Neuspješno čitanje sadržaja međuspremnika", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "Nema rezultata", "No results found": "Nema rezultata", "No search query generated": "Nije generiran upit za pretraživanje", + "No servers detected": "", "No skills found": "", "No source available": "Nema dostupnog izvora", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "Pozitivan stav", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "", "RESULT": "REZULTAT", "Retrieval": "", @@ -1584,6 +1592,7 @@ "Role": "Uloga", "RTL": "RTL", "Run": "", + "Run All": "", "Running": "Pokrenuto", "Running...": "Pokrenuto...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1774,6 +1783,7 @@ "Start a new conversation": "", "Start of the channel": "Početak kanala", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2118,6 +2128,8 @@ "You're now logged in.": "Sada ste prijavljeni.", "Your Account": "", "Your account status is currently pending activation.": "Status vašeg računa trenutno čeka aktivaciju.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/ca-ES/translation.json b/src/lib/i18n/locales/ca-ES/translation.json index 2c2609e1d2..b1b621ebfe 100644 --- a/src/lib/i18n/locales/ca-ES/translation.json +++ b/src/lib/i18n/locales/ca-ES/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Límit de caràcters per a l'entrada de generació automàtica", "Chart new frontiers": "Traça noves fronteres", "Chat": "Xat", + "Chat archived.": "", "Chat Background Image": "Imatge de fons del xat", "Chat Bubble UI": "Chat Bubble UI", "Chat Completions": "Completacions de xat", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "Efecte de fos a negre per al text en streaming", "Failed to add file.": "No s'ha pogut afegir l'arxiu.", "Failed to add members": "No s'han pogut afegir el membres", + "Failed to archive chat.": "", "Failed to attach file": "No s'ha pogut adjuntar l'arxiu", "Failed to clear status": "No s'ha pogut esborar l'estat", "Failed to connect to {{URL}} OpenAPI tool server": "No s'ha pogut connecta al servidor d'eines OpenAPI {{URL}}", @@ -836,9 +838,11 @@ "Failed to generate title": "No s'ha pogut generar el títol", "Failed to import models": "No s'han pogut importar el models", "Failed to load chat preview": "No s'ha pogut carregar la previsualització del xat", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "No s'ha pogut carregar el fitxer Excel/CSV. Si us plau, prova de descarregar-lo.", "Failed to load file content.": "No s'ha pogut carregar el contingut del fitxer", "Failed to load Interface settings": "No s'ha pogut carregar la configuració de la interficie", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "No s'ha pogut moure el xat", "Failed to process URL: {{url}}": "No s'ha pogut processar la URL: {{url}}", "Failed to read clipboard contents": "No s'ha pogut llegir el contingut del porta-retalls", @@ -1305,6 +1309,7 @@ "No history available": "No hi ha historial disponible", "No HTML, CSS, or JavaScript content found.": "No s'ha trobat contingut HTML, CSS o JavaScript.", "No inference engine with management support found": "No s'ha trobat un motor d'inferència amb suport de gestió", + "No kernel": "", "No knowledge bases found.": "No s'han trobat bases de coneixement.", "No knowledge found": "No s'ha trobat Coneixement", "No memories to clear": "No hi ha memòries per netejar", @@ -1320,6 +1325,7 @@ "No results": "No s'han trobat resultats", "No results found": "No s'han trobat resultats", "No search query generated": "No s'ha generat cap consulta", + "No servers detected": "", "No skills found": "No s'han trobat habilitats", "No source available": "Sense font disponible", "No sources found": "No s'han trobat fonts", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "Selecciona com a mínim un usuari per al canal de missatge directe.", "Please wait until all files are uploaded.": "Si us plau, espera fins que s'hagin carregat tots els fitxers.", "Port": "Port", + "Ports": "", "Positive attitude": "Actitud positiva", "Prefer not to say": "Prefereixo no dir-ho", "Prefix ID": "Identificador del prefix", @@ -1571,6 +1578,7 @@ "Response splitting": "Divisió de la resposta", "Response Watermark": "Marca d'aigua de la resposta", "Responses": "Respostes", + "Restart": "", "Result": "Resultat", "RESULT": "Resultat", "Retrieval": "Retrieval", @@ -1584,6 +1592,7 @@ "Role": "Rol", "RTL": "RTL", "Run": "Executar", + "Run All": "", "Running": "S'està executant", "Running...": "S'està executant...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "Executa tasques d'incrustació simultàniament per accelerar el processament. Desactiva-ho si els límits de velocitat es converteixen en un problema.", @@ -1774,6 +1783,7 @@ "Start a new conversation": "Iniciar una nova conversa", "Start of the channel": "Inici del canal", "Start Tag": "Etiqueta d'inici", + "Starting kernel...": "", "Status": "Estat", "Status cleared successfully": "S'ha eliminat correctament el teu estat", "Status updated successfully": "S'ha actualitzat correctament el teu estat", @@ -2118,6 +2128,8 @@ "You're now logged in.": "Ara estàs connectat.", "Your Account": "El teu compte", "Your account status is currently pending activation.": "El compte està actualment pendent d'activació", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Tota la teva contribució anirà directament al desenvolupador del complement; Open WebUI no se'n queda cap percentatge. Tanmateix, la plataforma de finançament escollida pot tenir les seves pròpies comissions.", "Your message text or inputs": "El text o les entrades del teu missatge", "Your usage stats have been successfully synced.": "Les teves estadístiques d'ús s'han sincronitzat correctament.", diff --git a/src/lib/i18n/locales/ceb-PH/translation.json b/src/lib/i18n/locales/ceb-PH/translation.json index e094ff8360..098776cc6d 100644 --- a/src/lib/i18n/locales/ceb-PH/translation.json +++ b/src/lib/i18n/locales/ceb-PH/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "Panaghisgot", + "Chat archived.": "", "Chat Background Image": "", "Chat Bubble UI": "", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Napakyas sa pagbasa sa sulod sa clipboard", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "Walay resulta", "No results found": "", "No search query generated": "", + "No servers detected": "", "No skills found": "", "No source available": "Walay tinubdan nga anaa", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "", "RESULT": "RESULTA", "Retrieval": "", @@ -1583,6 +1591,7 @@ "Role": "Papel", "RTL": "", "Run": "", + "Run All": "", "Running": "", "Running...": "Nagdagan...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "Sinugdan sa channel", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "Konektado ka na karon.", "Your Account": "", "Your account status is currently pending activation.": "", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/cs-CZ/translation.json b/src/lib/i18n/locales/cs-CZ/translation.json index eae230e54a..e3d2f4ba85 100644 --- a/src/lib/i18n/locales/cs-CZ/translation.json +++ b/src/lib/i18n/locales/cs-CZ/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Limit znaků pro vstup generování automatického dokončování", "Chart new frontiers": "Objevujte nové hranice", "Chat": "Konverzace", + "Chat archived.": "", "Chat Background Image": "Obrázek pozadí konverzace", "Chat Bubble UI": "Uživatelské rozhraní s bublinami konverzace", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "Efekt prolínání pro streamovaný text", "Failed to add file.": "Nepodařilo se přidat soubor.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "Nepodařilo se připojit k serveru nástrojů OpenAPI {{URL}}", @@ -836,9 +838,11 @@ "Failed to generate title": "Nepodařilo se vygenerovat název", "Failed to import models": "", "Failed to load chat preview": "Nepodařilo se načíst náhled konverzace", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "Nepodařilo se načíst obsah souboru.", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Nepodařilo se přečíst obsah schránky", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "Nebyl nalezen žádný obsah HTML, CSS ani JavaScriptu.", "No inference engine with management support found": "Nebyl nalezeno žádné inferenční jádro s podporou správy", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Nebyly nalezeny žádné znalosti", "No memories to clear": "Žádné vzpomínky k vymazání", @@ -1320,6 +1325,7 @@ "No results": "Nebyly nalezeny žádné výsledky", "No results found": "Nebyly nalezeny žádné výsledky", "No search query generated": "Nebyl vygenerován žádný vyhledávací dotaz.", + "No servers detected": "", "No skills found": "", "No source available": "Není k dispozici žádný zdroj.", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "Prosím počkejte dokud nebudou všechny soubory nahrány.", "Port": "Port", + "Ports": "", "Positive attitude": "Pozitivní přístup", "Prefer not to say": "Raději nevyberu", "Prefix ID": "Prefix ID", @@ -1571,6 +1578,7 @@ "Response splitting": "Dělení odpovědi", "Response Watermark": "Vodoznak odpovědi", "Responses": "", + "Restart": "", "Result": "Výsledek", "RESULT": "Výsledek", "Retrieval": "Vyhledávání", @@ -1585,6 +1593,7 @@ "Role": "Role", "RTL": "RTL", "Run": "Spustit", + "Run All": "", "Running": "Běží", "Running...": "Běží...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1775,6 +1784,7 @@ "Start a new conversation": "", "Start of the channel": "Začátek kanálu", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2119,6 +2129,8 @@ "You're now logged in.": "Nyní jste přihlášeni.", "Your Account": "Váš účet", "Your account status is currently pending activation.": "Stav vašeho účtu aktuálně čeká na aktivaci.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Celý váš příspěvek půjde přímo vývojáři pluginu; Open WebUI si nebere žádné procento. Zvolená platforma pro financování však může mít vlastní poplatky.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/da-DK/translation.json b/src/lib/i18n/locales/da-DK/translation.json index 3ec07a868a..ecb07cafa5 100644 --- a/src/lib/i18n/locales/da-DK/translation.json +++ b/src/lib/i18n/locales/da-DK/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Karaktergrænse for genereret autofuldførsel", "Chart new frontiers": "Udforsk nye grænser", "Chat": "Chat", + "Chat archived.": "", "Chat Background Image": "Chat baggrundsbillede", "Chat Bubble UI": "Chat Bubble UI", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "Fade-effekt for streaming tekst", "Failed to add file.": "Kunne ikke tilføje fil.", "Failed to add members": "Kunne ikke tilføje medlemmer", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "Kunne ikke fjerne status", "Failed to connect to {{URL}} OpenAPI tool server": "Kunne ikke forbinde til {{URL}} OpenAPI tool server", @@ -836,9 +838,11 @@ "Failed to generate title": "Kunne ikke generere titel", "Failed to import models": "Kunne ikke importere modeller", "Failed to load chat preview": "Kunne ikke indlæse chat forhåndsvisning", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "Kunne ikke indlæse filindhold.", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "Kunne ikke flytte chat", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Kunne ikke læse indholdet af udklipsholderen", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "Intet HTML-, CSS- eller JavaScript-indhold fundet.", "No inference engine with management support found": "Ingen inference-engine med støtte til administration fundet", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Ingen viden fundet", "No memories to clear": "Ingen hukommelser at ryde", @@ -1320,6 +1325,7 @@ "No results": "Ingen resultater fundet", "No results found": "Ingen resultater fundet", "No search query generated": "Ingen søgeforespørgsel genereret", + "No servers detected": "", "No skills found": "", "No source available": "Ingen kilde tilgængelig", "No sources found": "Ingen kilder fundet", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "Vælg mindst én bruger til direkte besked-kanal.", "Please wait until all files are uploaded.": "Vent venligst indtil alle filerne er uploadet.", "Port": "Port", + "Ports": "", "Positive attitude": "Positiv holdning", "Prefer not to say": "Foretrækker ikke at oplyse", "Prefix ID": "Prefix ID", @@ -1571,6 +1578,7 @@ "Response splitting": "Svaropdeling", "Response Watermark": "Vandmærke på svar", "Responses": "", + "Restart": "", "Result": "Resultat", "RESULT": "Resultat", "Retrieval": "Hentning", @@ -1583,6 +1591,7 @@ "Role": "Rolle", "RTL": "RTL", "Run": "Kør", + "Run All": "", "Running": "Kører", "Running...": "Kører...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "Kører embedding-opgaver sideløbende for at fremskynde behandlingen. Slå fra hvis hastighedsbegrænsninger bliver et problem.", @@ -1773,6 +1782,7 @@ "Start a new conversation": "Start en ny samtale", "Start of the channel": "Kanalens start", "Start Tag": "Start tag", + "Starting kernel...": "", "Status": "Status", "Status cleared successfully": "Status slettet", "Status updated successfully": "Status opdateret", @@ -2117,6 +2127,8 @@ "You're now logged in.": "Du er nu logget ind.", "Your Account": "Din bruger", "Your account status is currently pending activation.": "Din kontostatus afventer i øjeblikket aktivering.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Hele dit bidrag går direkte til plugin-udvikleren; Open WebUI tager ikke nogen procentdel. Den valgte finansieringsplatform kan dog have sine egne gebyrer.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/de-DE/translation.json b/src/lib/i18n/locales/de-DE/translation.json index e137bd9401..21e871c778 100644 --- a/src/lib/i18n/locales/de-DE/translation.json +++ b/src/lib/i18n/locales/de-DE/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Zeichenlimit für Eingabe der Autovervollständigung", "Chart new frontiers": "Neue Grenzen erkunden", "Chat": "Chat", + "Chat archived.": "", "Chat Background Image": "Hintergrundbild des Chats", "Chat Bubble UI": "Sprechblasen-Ansicht", "Chat Completions": "Chat Completions", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "Fade-Effekt für Text-Streaming", "Failed to add file.": "Hinzufügen der Datei fehlgeschlagen.", "Failed to add members": "Mitglieder konnten nicht hinzugefügt werden", + "Failed to archive chat.": "", "Failed to attach file": "Datei konnte nicht hinzugefügt werden", "Failed to clear status": "Status konnte nicht geleert werden", "Failed to connect to {{URL}} OpenAPI tool server": "Verbindung zum OpenAPI-Toolserver {{URL}} fehlgeschlagen", @@ -836,9 +838,11 @@ "Failed to generate title": "Titel konnte nicht generiert werden", "Failed to import models": "Modelle konnten nicht importiert werden", "Failed to load chat preview": "Chat-Vorschau konnte nicht geladen werden", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "Excel/CSV-Datei konnte nicht geladen werden. Bitte versuchen Sie stattdessen, sie herunterzuladen.", "Failed to load file content.": "Dateiinhalt konnte nicht geladen werden.", "Failed to load Interface settings": "Interface Einstellungen konnten nicht geladen werden", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "Chat konnte nicht verschoben werden", "Failed to process URL: {{url}}": "{{url}} konnte nicht verarbeitet werden", "Failed to read clipboard contents": "Zwischenablage konnte nicht gelesen werden", @@ -1305,6 +1309,7 @@ "No history available": "Keine History verfügbar", "No HTML, CSS, or JavaScript content found.": "Keine HTML-, CSS- oder JavaScript-Inhalte gefunden.", "No inference engine with management support found": "Keine Inferenz-Engine mit Verwaltungsunterstützung gefunden", + "No kernel": "", "No knowledge bases found.": "Keine Wissensspeicher gefunden.", "No knowledge found": "Kein Wissen gefunden", "No memories to clear": "Keine Erinnerungen zum Löschen", @@ -1320,6 +1325,7 @@ "No results": "Keine Ergebnisse", "No results found": "Keine Ergebnisse gefunden", "No search query generated": "Keine Suchanfrage generiert", + "No servers detected": "", "No skills found": "Keine Skills gefunden", "No source available": "Keine Quelle verfügbar", "No sources found": "Keine Quellen gefunden", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "Bitte wählen Sie mindestens einen Benutzer für den Direktnachrichten-Kanal aus.", "Please wait until all files are uploaded.": "Bitte warten Sie, bis alle Dateien hochgeladen sind.", "Port": "Port", + "Ports": "", "Positive attitude": "Positive Einstellung", "Prefer not to say": "Keine Angabe", "Prefix ID": "Präfix-ID", @@ -1571,6 +1578,7 @@ "Response splitting": "Antwortaufteilung", "Response Watermark": "Antwort-Wasserzeichen", "Responses": "Responses", + "Restart": "", "Result": "Ergebnis", "RESULT": "ERGEBNIS", "Retrieval": "Abruf", @@ -1583,6 +1591,7 @@ "Role": "Rolle", "RTL": "RTL", "Run": "Ausführen", + "Run All": "", "Running": "Läuft", "Running...": "Läuft...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "Führt Embedding-Aufgaben parallel aus, um die Verarbeitung zu beschleunigen. Deaktivieren Sie dies, falls Rate-Limits oder Ressourcenprobleme auftreten.", @@ -1773,6 +1782,7 @@ "Start a new conversation": "Neue Unterhaltung beginnen", "Start of the channel": "Beginn des Kanals", "Start Tag": "Start-Tag", + "Starting kernel...": "", "Status": "Status", "Status cleared successfully": "Status erfolgreich gelöscht", "Status updated successfully": "Status erfolgreich aktualisiert", @@ -2117,6 +2127,8 @@ "You're now logged in.": "Sie sind jetzt angemeldet.", "Your Account": "Ihr Konto", "Your account status is currently pending activation.": "Ihr Kontostatus wartet derzeit auf Aktivierung.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Ihr gesamter Beitrag geht direkt an den Plugin-Entwickler; Open WebUI behält keinen Anteil ein. Die gewählte Plattform kann jedoch eigene Gebühren erheben.", "Your message text or inputs": "Ihre Nachrichtentexte oder Eingaben", "Your usage stats have been successfully synced.": "Ihre Nutzungsstatistiken wurden erfolgreich synchronisiert.", diff --git a/src/lib/i18n/locales/dg-DG/translation.json b/src/lib/i18n/locales/dg-DG/translation.json index ff64e67a59..f530299954 100644 --- a/src/lib/i18n/locales/dg-DG/translation.json +++ b/src/lib/i18n/locales/dg-DG/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "Chat", + "Chat archived.": "", "Chat Background Image": "", "Chat Bubble UI": "", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Failed to read clipboard borks", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "No results, very empty", "No results found": "", "No search query generated": "", + "No servers detected": "", "No skills found": "", "No source available": "No source available", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "", "RESULT": "RESULT much", "Retrieval": "", @@ -1583,6 +1591,7 @@ "Role": "Role", "RTL": "", "Run": "", + "Run All": "", "Running": "", "Running...": "Running... wow", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "Start of channel", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "You're now logged in. Much logged.", "Your Account": "", "Your account status is currently pending activation.": "", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/el-GR/translation.json b/src/lib/i18n/locales/el-GR/translation.json index bcb3d60100..66db5bd86c 100644 --- a/src/lib/i18n/locales/el-GR/translation.json +++ b/src/lib/i18n/locales/el-GR/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Όριο χαρακτήρων για αυτόματη συμπλήρωση εισαγωγής", "Chart new frontiers": "Σχεδιάστε νέους ορίζοντες", "Chat": "Συνομιλία", + "Chat archived.": "", "Chat Background Image": "Εικόνα Φόντου Συνομιλίας", "Chat Bubble UI": "Διεπαφή Φούσκας Συνομιλίας", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "Αποτυχία προσθήκης αρχείου.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "Αποτυχία σύνδεσης στο διακομιστή εργαλείων OpenAPI {{URL}}", @@ -836,9 +838,11 @@ "Failed to generate title": "Αποτυχία δημιουργίας τίτλου", "Failed to import models": "Αποτυχία εισαγωγής μοντέλων", "Failed to load chat preview": "Αποτυχία φόρτωσης προεπισκόπησης συνομιλίας", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "Αποτυχία φόρτωσης περιεχομένου αρχείου", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "Αποτυχία μετακίνησης συνομιλίας", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Αποτυχία ανάγνωσης περιεχομένων πρόχειρου", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "Δεν βρέθηκε περιεχόμενο HTML, CSS ή JavaScript.", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Δεν βρέθηκε Knowledge", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "Δεν βρέθηκαν αποτελέσματα", "No results found": "Δεν βρέθηκαν αποτελέσματα", "No search query generated": "Δεν δημιουργήθηκε ερώτηση αναζήτησης", + "No servers detected": "", "No skills found": "", "No source available": "Δεν υπάρχει διαθέσιμη πηγή", "No sources found": "Δεν βρέθηκαν πηγές", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "Θύρα", + "Ports": "", "Positive attitude": "Θετική στάση", "Prefer not to say": "", "Prefix ID": "ID Προθέματος", @@ -1571,6 +1578,7 @@ "Response splitting": "Διαχωρισμός απάντησης", "Response Watermark": "Υδρογράφημα Απάντησης", "Responses": "", + "Restart": "", "Result": "Αποτέλεσμα", "RESULT": "Αποτέλεσμα", "Retrieval": "Ανάκτηση", @@ -1583,6 +1591,7 @@ "Role": "Ρόλος", "RTL": "RTL", "Run": "Εκτέλεση", + "Run All": "", "Running": "Εκτέλεση", "Running...": "Εκτέλεση...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "Αρχή του καναλιού", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "Τώρα είστε συνδεδεμένοι.", "Your Account": "Ο λογαριασμός σας", "Your account status is currently pending activation.": "Η κατάσταση του λογαριασμού σας είναι αυτή τη στιγμή σε εκκρεμότητα ενεργοποίησης.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Η ολόκληρη η συνεισφορά σας θα πάει απευθείας στον προγραμματιστή του plugin· το Open WebUI δεν παίρνει κανένα ποσοστό. Ωστόσο, η επιλεγμένη πλατφόρμα χρηματοδότησης μπορεί να έχει τα δικά της τέλη.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/en-GB/translation.json b/src/lib/i18n/locales/en-GB/translation.json index 392c88046d..4cc97d93cd 100644 --- a/src/lib/i18n/locales/en-GB/translation.json +++ b/src/lib/i18n/locales/en-GB/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "", + "Chat archived.": "", "Chat Background Image": "", "Chat Bubble UI": "", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "", "No results found": "", "No search query generated": "", + "No servers detected": "", "No skills found": "", "No source available": "", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "", "RESULT": "", "Retrieval": "", @@ -1583,6 +1591,7 @@ "Role": "", "RTL": "", "Run": "", + "Run All": "", "Running": "", "Running...": "", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "", "Your Account": "", "Your account status is currently pending activation.": "", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/en-US/translation.json b/src/lib/i18n/locales/en-US/translation.json index 83431383ef..dced0f6c92 100644 --- a/src/lib/i18n/locales/en-US/translation.json +++ b/src/lib/i18n/locales/en-US/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "", + "Chat archived.": "", "Chat Background Image": "", "Chat Bubble UI": "", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "", "No results found": "", "No search query generated": "", + "No servers detected": "", "No skills found": "", "No source available": "", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "", "RESULT": "", "Retrieval": "", @@ -1583,6 +1591,7 @@ "Role": "", "RTL": "", "Run": "", + "Run All": "", "Running": "", "Running...": "", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "", "Your Account": "", "Your account status is currently pending activation.": "", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/es-ES/translation.json b/src/lib/i18n/locales/es-ES/translation.json index 18a9624e6d..d9877b5d3b 100644 --- a/src/lib/i18n/locales/es-ES/translation.json +++ b/src/lib/i18n/locales/es-ES/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Límite de caracteres de entrada de la generación de autocompletado", "Chart new frontiers": "Trazar nuevas fronteras", "Chat": "Chat", + "Chat archived.": "", "Chat Background Image": "Imágen de Fondo del Chat", "Chat Bubble UI": "Interfaz del Chat en Burbuja", "Chat Completions": "Completación del Chat", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "Efecto de desvanecimiento para texto transmitido (streaming)", "Failed to add file.": "Fallo al añadir el archivo.", "Failed to add members": "Fallo al añadir miembros", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "Fallo al limpiar el estado", "Failed to connect to {{URL}} OpenAPI tool server": "Fallo al conectar al servidor de herramientas {{URL}}", @@ -836,9 +838,11 @@ "Failed to generate title": "Fallo al generar el título", "Failed to import models": "Fallo al importar modelos", "Failed to load chat preview": "Fallo al cargar la previsualización del chat", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "Fallo al cargar el archivo Excel/CSV. Por favor, en su lugar intente descargarlo.", "Failed to load file content.": "Fallo al cargar el contenido del archivo", "Failed to load Interface settings": "Fallo al cargar la configuración del Interface", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "Fallo al mover el chat", "Failed to process URL: {{url}}": "Fallo al procesar la URL", "Failed to read clipboard contents": "Fallo al leer el contenido del portapapeles", @@ -1305,6 +1309,7 @@ "No history available": "No hay historial disponible", "No HTML, CSS, or JavaScript content found.": "No se encontró contenido HTML, CSS, o JavaScript.", "No inference engine with management support found": "No se encontró un motor de inferencia que soporte gestión", + "No kernel": "", "No knowledge bases found.": "No se encontraron bases de conocimiento", "No knowledge found": "No se encontró ningún conocimiento", "No memories to clear": "No hay memorias para borrar", @@ -1320,6 +1325,7 @@ "No results": "No se encontraron resultados", "No results found": "No se encontraron resultados", "No search query generated": "No se generó ninguna consulta de búsqueda", + "No servers detected": "", "No skills found": "No se encontraron habilidades", "No source available": "No hay fuente disponible", "No sources found": "No se han encontrado fuentes", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "Por favor selecciona al menos un usuario para el canal de Mensajes Directos", "Please wait until all files are uploaded.": "Por favor, espera a que todos los archivos se acaben de subir", "Port": "Puerto", + "Ports": "", "Positive attitude": "Actitud Positiva", "Prefer not to say": "Prefiero no decirlo", "Prefix ID": "prefijo ID", @@ -1571,6 +1578,7 @@ "Response splitting": "Particionado de Respuesta", "Response Watermark": "Marca de Agua en Respuesta", "Responses": "Respuestas", + "Restart": "", "Result": "Resultado", "RESULT": "Resultado", "Retrieval": "Recuperación", @@ -1584,6 +1592,7 @@ "Role": "Rol", "RTL": "RTL", "Run": "Ejecutar", + "Run All": "", "Running": "Ejecutando", "Running...": "Ejecutando...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "Ejecuta tareas de incrustración concurrentes para acelerar el procesado. Desactivar si se generan problemas (por limitaciones de los motores de incrustracción en uso)", @@ -1774,6 +1783,7 @@ "Start a new conversation": "Comenzar una conversación nueva", "Start of the channel": "Inicio del canal", "Start Tag": "Etiqueta de Inicio", + "Starting kernel...": "", "Status": "Estado", "Status cleared successfully": "Estado limpiado correctamente", "Status updated successfully": "Estado actualizado correctamente", @@ -2118,6 +2128,8 @@ "You're now logged in.": "Has iniciado sesión.", "Your Account": "Tu Cuenta", "Your account status is currently pending activation.": "Tu cuenta está pendiente de activación.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Tu entera contribución irá directamente al desarrollador del complemento; Open-WebUI no recibe ningún porcentaje. Sin embargo, la plataforma de financiación elegida podría tener sus propias tarifas.", "Your message text or inputs": "Tu mensaje de texto o entrada", "Your usage stats have been successfully synced.": "Tu estadistica de uso ha sido sincronizada", diff --git a/src/lib/i18n/locales/et-EE/translation.json b/src/lib/i18n/locales/et-EE/translation.json index e5611c0be0..b133d638e7 100644 --- a/src/lib/i18n/locales/et-EE/translation.json +++ b/src/lib/i18n/locales/et-EE/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Märkide piirang automaattäitmise genereerimise sisendile", "Chart new frontiers": "Kaardista uusi piire", "Chat": "Vestlus", + "Chat archived.": "", "Chat Background Image": "Vestluse taustapilt", "Chat Bubble UI": "Vestlusmullide kasutajaliides", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "Hajuefekt voogteksti jaoks", "Failed to add file.": "Faili lisamine ebaõnnestus.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "Ebaõnnestus kuni connect kuni {{URL}} OpenAPI tööriist server", @@ -836,9 +838,11 @@ "Failed to generate title": "Ebaõnnestus kuni generate title", "Failed to import models": "Ebaõnnestus kuni impordi mudelid", "Failed to load chat preview": "Ebaõnnestus kuni load vestlus preview", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "Ebaõnnestus kuni load fail content.", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "Ebaõnnestus kuni teisalda vestlus", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Lõikelaua sisu lugemine ebaõnnestus", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "HTML, CSS ega JavaScript sisu ei leitud.", "No inference engine with management support found": "Järeldusmootorit haldamise toega ei leitud", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Teadmisi ei leitud", "No memories to clear": "Pole mälestusi, mida kustutada", @@ -1320,6 +1325,7 @@ "No results": "Tulemusi ei leitud", "No results found": "Tulemusi ei leitud", "No search query generated": "Otsingupäringut ei genereeritud", + "No servers detected": "", "No skills found": "", "No source available": "Allikas pole saadaval", "No sources found": "No allikad found", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "Please wait until all failid are uploaded.", "Port": "Port", + "Ports": "", "Positive attitude": "Positiivne suhtumine", "Prefer not to say": "Prefer not kuni say", "Prefix ID": "Prefiksi ID", @@ -1571,6 +1578,7 @@ "Response splitting": "Vastuse tükeldamine", "Response Watermark": "Vastus Watermark", "Responses": "", + "Restart": "", "Result": "Tulemus", "RESULT": "Tulemus", "Retrieval": "Taastamine", @@ -1583,6 +1591,7 @@ "Role": "Roll", "RTL": "RTL", "Run": "Käivita", + "Run All": "", "Running": "Töötab", "Running...": "Töötab...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "Käivita a new conversation", "Start of the channel": "Kanali algus", "Start Tag": "Käivita Silt", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "Olete nüüd sisse logitud.", "Your Account": "Your Konto", "Your account status is currently pending activation.": "Teie konto staatus on praegu ootel aktiveerimist.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Kogu teie toetus läheb otse pistikprogrammi arendajale; Open WebUI ei võta mingit protsenti. Kuid valitud rahastamisplatvormil võivad olla oma tasud.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/eu-ES/translation.json b/src/lib/i18n/locales/eu-ES/translation.json index f897c87d83..117a260c60 100644 --- a/src/lib/i18n/locales/eu-ES/translation.json +++ b/src/lib/i18n/locales/eu-ES/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "Esploratu muga berriak", "Chat": "Txata", + "Chat archived.": "", "Chat Background Image": "Txataren Atzeko Irudia", "Chat Bubble UI": "Txat Burbuilen Interfazea", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "Huts egin du fitxategia gehitzean.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Huts egin du arbelaren edukia irakurtzean", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "Ez da HTML, CSS, edo JavaScript edukirik aurkitu.", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Ez da ezagutzarik aurkitu", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "Ez da emaitzarik aurkitu", "No results found": "Ez da emaitzarik aurkitu", "No search query generated": "Ez da bilaketa kontsultarik sortu", + "No servers detected": "", "No skills found": "", "No source available": "Ez dago iturririk eskuragarri", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "Ataka", + "Ports": "", "Positive attitude": "Jarrera positiboa", "Prefer not to say": "", "Prefix ID": "Aurrizki ID", @@ -1571,6 +1578,7 @@ "Response splitting": "Erantzun banaketa", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "Emaitza", "RESULT": "Emaitza", "Retrieval": "", @@ -1583,6 +1591,7 @@ "Role": "Rola", "RTL": "RTL", "Run": "Exekutatu", + "Run All": "", "Running": "Exekutatzen", "Running...": "Exekutatzen...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "Kanalaren hasiera", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "Orain saioa hasita duzu.", "Your Account": "", "Your account status is currently pending activation.": "Zure kontuaren egoera aktibazio zain dago.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Zure ekarpen osoa zuzenean plugin garatzaileari joango zaio; Open WebUI-k ez du ehunekorik hartzen. Hala ere, aukeratutako finantzaketa plataformak bere komisioak izan ditzake.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/fa-IR/translation.json b/src/lib/i18n/locales/fa-IR/translation.json index fe356747aa..1bc4077445 100644 --- a/src/lib/i18n/locales/fa-IR/translation.json +++ b/src/lib/i18n/locales/fa-IR/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "محدودیت کاراکتر برای ورودی تولید تکمیل خودکار", "Chart new frontiers": "ترسیم مرزهای جدید", "Chat": "گفتگو", + "Chat archived.": "", "Chat Background Image": "تصویر پس\u200cزمینهٔ گفتگو", "Chat Bubble UI": "رابط کاربری حبابی گفتگو", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "جلوه محو شدن برای متن جریانی", "Failed to add file.": "خطا در افزودن پرونده", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "خطا در اتصال به سرور ابزار OpenAPI {{URL}}", @@ -836,9 +838,11 @@ "Failed to generate title": "تولید عنوان ناموفق بود", "Failed to import models": "وارد کردن مدل\u200cها ناموفق بود", "Failed to load chat preview": "بارگیری پیش\u200cنمایش چت ناموفق بود", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "بارگیری محتوای فایل ناموفق بود.", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "انتقال چت ناموفق بود", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "خواندن محتوای کلیپ بورد ناموفق بود", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "محتوای HTML، CSS یا JavaScript یافت نشد.", "No inference engine with management support found": "موتور استنتاج با پشتیبانی مدیریت یافت نشد", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "دانشی یافت نشد", "No memories to clear": "حافظه\u200cای برای پاک کردن وجود ندارد", @@ -1320,6 +1325,7 @@ "No results": "نتیجه\u200cای یافت نشد", "No results found": "نتیجه\u200cای یافت نشد", "No search query generated": "پرسوجوی جستجویی ایجاد نشده است", + "No servers detected": "", "No skills found": "", "No source available": "منبعی در دسترس نیست", "No sources found": "هیچ منبعی یافت نشد", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "لطفاً منتظر بمانید تا همه فایل\u200cها آپلود شوند.", "Port": "پورت", + "Ports": "", "Positive attitude": "نظرات مثبت", "Prefer not to say": "ترجیح می\u200cدهم نگویم", "Prefix ID": "شناسه پیشوند", @@ -1571,6 +1578,7 @@ "Response splitting": "تقسیم پاسخ", "Response Watermark": "واترمارک پاسخ", "Responses": "", + "Restart": "", "Result": "نتیجه", "RESULT": "نتیجه", "Retrieval": "بازیابی", @@ -1583,6 +1591,7 @@ "Role": "نقش", "RTL": "RTL", "Run": "اجرا", + "Run All": "", "Running": "در حال اجرا", "Running...": "در حال اجرا...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "شروع یک مکالمه جدید", "Start of the channel": "آغاز کانال", "Start Tag": "تگ شروع", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "شما اکنون وارد شده\u200cاید.", "Your Account": "حساب کاربری شما", "Your account status is currently pending activation.": "وضعیت حساب شما در حال حاضر در انتظار فعال\u200cسازی است.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "تمام مشارکت شما مستقیماً به توسعه\u200cدهنده افزونه می\u200cرسد؛ Open WebUI هیچ درصدی دریافت نمی\u200cکند. با این حال، پلتفرم تأمین مالی انتخاب شده ممکن است کارمزد خود را داشته باشد.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/fi-FI/translation.json b/src/lib/i18n/locales/fi-FI/translation.json index 9c88959965..78d02d0aa2 100644 --- a/src/lib/i18n/locales/fi-FI/translation.json +++ b/src/lib/i18n/locales/fi-FI/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Automaattisen täydennyksen syötteen merkkiraja", "Chart new frontiers": "Kartoita uusia rajapintoja", "Chat": "Keskustelu", + "Chat archived.": "", "Chat Background Image": "Keskustelun taustakuva", "Chat Bubble UI": "Keskustelu-pallojen käyttöliittymä", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "Häivytystehoste suoratoistetulle tekstille", "Failed to add file.": "Tiedoston lisääminen epäonnistui.", "Failed to add members": "Jäsenten lisääminen epäonnistui", + "Failed to archive chat.": "", "Failed to attach file": "Tiedoston liittäminen epäonnistui", "Failed to clear status": "Tilan tyhjentäminen epäonnistui", "Failed to connect to {{URL}} OpenAPI tool server": "Yhdistäminen {{URL}} OpenAPI työkalu palvelimeen epäonnistui", @@ -836,9 +838,11 @@ "Failed to generate title": "Otsikon luonti epäonnistui", "Failed to import models": "Mallien tuonti epäonnistui", "Failed to load chat preview": "Keskustelun esikatselun lataaminen epäonnistui", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "Excel/CSV tiedoston lataaminen epäonnistui. Yritä ladata se sen sijaan.", "Failed to load file content.": "Tiedoston sisällön lataaminen epäonnistui.", "Failed to load Interface settings": "Käyttöliittymän asetusten lataaminen epäonnistui", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "Keskustelun siirto epäonnistui", "Failed to process URL: {{url}}": "Verkko-osoitteen käsittely epäonnistui: {{url}}", "Failed to read clipboard contents": "Leikepöydän sisällön lukeminen epäonnistui", @@ -1305,6 +1309,7 @@ "No history available": "Historiaa ei saatavilla", "No HTML, CSS, or JavaScript content found.": "HTML-, CSS- tai JavaScript-sisältöä ei löytynyt.", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "Tietokantoja ei löytynyt.", "No knowledge found": "Tietoa ei löytynyt", "No memories to clear": "Ei muistia tyhjennettäväksi", @@ -1320,6 +1325,7 @@ "No results": "Ei tuloksia", "No results found": "Ei tuloksia", "No search query generated": "Hakukyselyä ei luotu", + "No servers detected": "", "No skills found": "Taitoja ei löytynyt", "No source available": "Lähdettä ei saatavilla", "No sources found": "Lähteitä ei löytynyt", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "Valitse vähintään yksi käyttäjä suoraviestikanavalle.", "Please wait until all files are uploaded.": "Odota kunnes kaikki tiedostot ovat ladattu.", "Port": "Portti", + "Ports": "", "Positive attitude": "Positiivinen asenne", "Prefer not to say": "En halua sanoa", "Prefix ID": "Etuliite-ID", @@ -1571,6 +1578,7 @@ "Response splitting": "Vastauksen jakaminen", "Response Watermark": "Vastauksen vesileima", "Responses": "", + "Restart": "", "Result": "Tulos", "RESULT": "Tulos", "Retrieval": "Haku", @@ -1583,6 +1591,7 @@ "Role": "Rooli", "RTL": "RTL", "Run": "Suorita", + "Run All": "", "Running": "Käynnissä", "Running...": "Käynnissä...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "Suorittaa upotustehtäviä samanaikaisesti käsittelyn nopeuttamiseksi. Poista käytöstä, jos kutsurajoituksesta tulee ongelma.", @@ -1773,6 +1782,7 @@ "Start a new conversation": "Aloita uusi keskustelu", "Start of the channel": "Kanavan alku", "Start Tag": "Aloitus tagi", + "Starting kernel...": "", "Status": "Tila", "Status cleared successfully": "Tila poistettu onnistuneesti", "Status updated successfully": "Tila päivitetty onnistuneesti", @@ -2117,6 +2127,8 @@ "You're now logged in.": "Olet nyt kirjautunut sisään.", "Your Account": "Tilisi", "Your account status is currently pending activation.": "Tilisi tila on tällä hetkellä odottaa aktivointia.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Koko panoksesi menee suoraan lisäosan kehittäjälle; Open WebUI ei pidätä prosenttiosuutta. Valittu rahoitusalusta voi kuitenkin periä omia maksujaan.", "Your message text or inputs": "Viestisi teksti tai syöteet", "Your usage stats have been successfully synced.": "Käyttötilastosi on synkronoitu onnistuneesti.", diff --git a/src/lib/i18n/locales/fr-CA/translation.json b/src/lib/i18n/locales/fr-CA/translation.json index 2aba6bacd3..d7a80ee90b 100644 --- a/src/lib/i18n/locales/fr-CA/translation.json +++ b/src/lib/i18n/locales/fr-CA/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Limite de caractères pour la génération des suggestions", "Chart new frontiers": "Tracer de nouvelles frontières", "Chat": "Conversation", + "Chat archived.": "", "Chat Background Image": "Image d'arrière-plan de la fenêtre de la conversation", "Chat Bubble UI": "Bulles de conversation", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "Échec de l'ajout du fichier.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "Échec de la connexion au serveur d'outils OpenAPI {{URL}}", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "Échec du chargement du contenu du fichier", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Échec de la lecture du contenu du presse-papiers", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "Aucun contenu HTML, CSS ou JavaScript trouvé.", "No inference engine with management support found": "Aucun moteur d'inférence avec support trouvé", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Aucune connaissance trouvée", "No memories to clear": "Aucun souvenir à effacer", @@ -1320,6 +1325,7 @@ "No results": "Aucun résultat trouvé", "No results found": "Aucun résultat trouvé", "No search query generated": "Aucune requête de recherche générée", + "No servers detected": "", "No skills found": "", "No source available": "Aucune source n'est disponible", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "Port", + "Ports": "", "Positive attitude": "Attitude positive", "Prefer not to say": "", "Prefix ID": "ID de préfixe", @@ -1571,6 +1578,7 @@ "Response splitting": "Fractionnement de la réponse", "Response Watermark": "Filigramme de la réponse", "Responses": "", + "Restart": "", "Result": "Résultat", "RESULT": "Résultat", "Retrieval": "Récupération", @@ -1584,6 +1592,7 @@ "Role": "Rôle", "RTL": "RTL", "Run": "Exécuter", + "Run All": "", "Running": "Exécution", "Running...": "Exécution...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1774,6 +1783,7 @@ "Start a new conversation": "", "Start of the channel": "Début du canal", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2118,6 +2128,8 @@ "You're now logged in.": "Vous êtes désormais connecté.", "Your Account": "", "Your account status is currently pending activation.": "Votre statut de compte est actuellement en attente d'activation.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "L'intégralité de votre contribution ira directement au développeur du plugin ; Open WebUI ne prend aucun pourcentage. Cependant, la plateforme de financement choisie peut avoir ses propres frais.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/fr-FR/translation.json b/src/lib/i18n/locales/fr-FR/translation.json index 3f24312660..c123b3d967 100644 --- a/src/lib/i18n/locales/fr-FR/translation.json +++ b/src/lib/i18n/locales/fr-FR/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Limite de caractères pour la génération des suggestions", "Chart new frontiers": "Tracer de nouvelles frontières", "Chat": "Conversation", + "Chat archived.": "", "Chat Background Image": "Image d'arrière-plan de la fenêtre de la conversation", "Chat Bubble UI": "Bulles de conversation", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "Effet de fondu pour le texte en streaming", "Failed to add file.": "Échec de l'ajout du fichier.", "Failed to add members": "Échec de l'ajout des membres", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "Échec de la connexion au serveur d'outils OpenAPI {{URL}}", @@ -836,9 +838,11 @@ "Failed to generate title": "Échec de la génération du titre", "Failed to import models": "Échec de l'importation des modèles", "Failed to load chat preview": "Échec du chargement de l'aperçu du chat", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "Échec du chargement du contenu du fichier", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "Échec du déplacement du chat", "Failed to process URL: {{url}}": "Échec du traitement de l'URL : {{url}}", "Failed to read clipboard contents": "Échec de la lecture du contenu du presse-papiers", @@ -1305,6 +1309,7 @@ "No history available": "Aucun historique disponible", "No HTML, CSS, or JavaScript content found.": "Aucun contenu HTML, CSS ou JavaScript trouvé.", "No inference engine with management support found": "Aucun moteur d'inférence avec support trouvé", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Aucune connaissance trouvée", "No memories to clear": "Aucun souvenir à effacer", @@ -1320,6 +1325,7 @@ "No results": "Aucun résultat trouvé", "No results found": "Aucun résultat trouvé", "No search query generated": "Aucune requête de recherche générée", + "No servers detected": "", "No skills found": "Aucun skill trouvé", "No source available": "Aucune source n'est disponible", "No sources found": "Aucune source trouvée", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "Veuillez sélectionner au moins un utilisateur pour un canal de message direct.", "Please wait until all files are uploaded.": "Veuillez patienter jusqu'à ce que tous les fichiers soient téléchargés.", "Port": "Port", + "Ports": "", "Positive attitude": "Attitude positive", "Prefer not to say": "Je préfère ne pas répondre", "Prefix ID": "ID de préfixe", @@ -1571,6 +1578,7 @@ "Response splitting": "Fractionnement de la réponse", "Response Watermark": "Filigramme de la réponse", "Responses": "", + "Restart": "", "Result": "Résultat", "RESULT": "Résultat", "Retrieval": "Récupération", @@ -1584,6 +1592,7 @@ "Role": "Rôle", "RTL": "RTL", "Run": "Exécuter", + "Run All": "", "Running": "Exécution", "Running...": "Exécution...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1774,6 +1783,7 @@ "Start a new conversation": "Démarrer une nouvelle conversation", "Start of the channel": "Début du canal", "Start Tag": "Balise de départ", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "Statut effacé avec succès", "Status updated successfully": "Statut mis à jour avec succès", @@ -1984,7 +1994,7 @@ "Upload Pipeline": "Pipeline de téléchargement", "Upload profile image": "", "Upload Progress": "Progression de l'envoi", - "Upload Progress: {{uploadedFiles}}/{{totalFiles}} ({{percentage}}%)": "Progression du téléchargement : {{uploadedFiles}}/{{totalFiles}} ({{percentage}}%)", + "Upload Progress: {{uploadedFiles}}/{{totalFiles}} ({{percentage}}%)": "Progression du téléchargement\u00a0: {{uploadedFiles}}/{{totalFiles}} ({{percentage}}%)", "Uploaded files or images": "Les fichiers ou images téléversés", "Uploading file...": "Téléversement du fichier en cours...", "Uploading...": "Téléversement en cours...", @@ -2017,7 +2027,7 @@ "Using Entire Document": "Utilisation du document entier", "Using Focused Retrieval": "Utilisation de la récupération ciblée", "Using the default arena model with all models. Click the plus button to add custom models.": "Utilisation du modèle d'arène par défaut avec tous les modèles. Cliquez sur le bouton plus pour ajouter des modèles personnalisés.", - "Valid time units:": "Unités de temps valides :", + "Valid time units:": "Unités de temps valides\u00a0:", "Validate certificate": "Valider le certificat", "Valves": "Vannes", "Valves updated": "Vannes mises à jour", @@ -2118,6 +2128,8 @@ "You're now logged in.": "Vous êtes désormais connecté.", "Your Account": "Votre compte", "Your account status is currently pending activation.": "Votre statut de compte est actuellement en attente d'activation.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "L'intégralité de votre contribution ira directement au développeur du plugin ; Open WebUI ne prend aucun pourcentage. Cependant, la plateforme de financement choisie peut avoir ses propres frais.", "Your message text or inputs": "Vos messages envoyés", "Your usage stats have been successfully synced.": "Vos statistiques d'utilisation ont été synchronisées avec succès.", diff --git a/src/lib/i18n/locales/gl-ES/translation.json b/src/lib/i18n/locales/gl-ES/translation.json index 28023e96de..27c9b3d58b 100644 --- a/src/lib/i18n/locales/gl-ES/translation.json +++ b/src/lib/i18n/locales/gl-ES/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Limite de caracteres para a entrada de xeneración do autocompletado", "Chart new frontiers": "Dibuxar novas fronteiras", "Chat": "Chat", + "Chat archived.": "", "Chat Background Image": "Imaxe de fondo do Chat", "Chat Bubble UI": "Burbuxa do chat UI", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "Non pudo agregarse o Arquivo.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Non pudo Lerse o contido do portapapeles", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "No se encontró contido HTML, CSS, o JavaScript.", "No inference engine with management support found": "No se encontró un motor de inferencia con soporte de gestión", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "No se encontrou ningún coñecemento", "No memories to clear": "Non hay memorias que limpar", @@ -1320,6 +1325,7 @@ "No results": "No se han encontrado resultados", "No results found": "No se han encontrado resultados", "No search query generated": "No se ha generado ninguna consulta de búsqueda", + "No servers detected": "", "No skills found": "", "No source available": "Non ten fuente disponible", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "Puerto", + "Ports": "", "Positive attitude": "Actitud positiva", "Prefer not to say": "", "Prefix ID": "ID de prefijo", @@ -1571,6 +1578,7 @@ "Response splitting": "División de respostas", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "Resultado", "RESULT": "Resultado", "Retrieval": "recuperación", @@ -1583,6 +1591,7 @@ "Role": "Rol", "RTL": "RTL", "Run": "Executar", + "Run All": "", "Running": "Executando", "Running...": "Executando...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "Inicio da canle", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "Vostede ahora está conectado.", "Your Account": "", "Your account status is currently pending activation.": "O estado da sua conta actualmente encontrase pendente de activación.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "A sua contribución completa irá directamente o desarrollador do plugin; Open WebUI non toma ningun porcentaxe. Sin embargo, a plataforma de financiación elegida podría ter as suas propias tarifas.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/he-IL/translation.json b/src/lib/i18n/locales/he-IL/translation.json index 5cf3acab1e..a6b061d054 100644 --- a/src/lib/i18n/locales/he-IL/translation.json +++ b/src/lib/i18n/locales/he-IL/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "צ'אט", + "Chat archived.": "", "Chat Background Image": "", "Chat Bubble UI": "UI של תיבת הדיבור", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "קריאת תוכן הלוח נכשלה", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "לא נמצאו תוצאות", "No results found": "לא נמצאו תוצאות", "No search query generated": "לא נוצרה שאילתת חיפוש", + "No servers detected": "", "No skills found": "", "No source available": "אין מקור זמין", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "גישה חיובית", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "", "RESULT": "תוצאה", "Retrieval": "", @@ -1584,6 +1592,7 @@ "Role": "תפקיד", "RTL": "RTL", "Run": "", + "Run All": "", "Running": "", "Running...": "פועל...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1774,6 +1783,7 @@ "Start a new conversation": "", "Start of the channel": "תחילת הערוץ", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2118,6 +2128,8 @@ "You're now logged in.": "כעת אתה מחובר.", "Your Account": "", "Your account status is currently pending activation.": "", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/hi-IN/translation.json b/src/lib/i18n/locales/hi-IN/translation.json index d8395b259d..d1576fca2d 100644 --- a/src/lib/i18n/locales/hi-IN/translation.json +++ b/src/lib/i18n/locales/hi-IN/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "चैट करें", + "Chat archived.": "", "Chat Background Image": "", "Chat Bubble UI": "चैट बॉली", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "क्लिपबोर्ड सामग्री पढ़ने में विफल", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "कोई परिणाम नहीं मिला", "No results found": "कोई परिणाम नहीं मिला", "No search query generated": "कोई खोज क्वेरी जनरेट नहीं हुई", + "No servers detected": "", "No skills found": "", "No source available": "कोई स्रोत उपलब्ध नहीं है", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "सकारात्मक रवैया", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "", "RESULT": "परिणाम", "Retrieval": "", @@ -1583,6 +1591,7 @@ "Role": "भूमिका", "RTL": "RTL", "Run": "", + "Run All": "", "Running": "", "Running...": "चल रहा है...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "चैनल की शुरुआत", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "अब आप लॉग इन हो गए हैं", "Your Account": "", "Your account status is currently pending activation.": "", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/hr-HR/translation.json b/src/lib/i18n/locales/hr-HR/translation.json index 476c684122..e6dadaba52 100644 --- a/src/lib/i18n/locales/hr-HR/translation.json +++ b/src/lib/i18n/locales/hr-HR/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "Razgovor", + "Chat archived.": "", "Chat Background Image": "", "Chat Bubble UI": "Razgovor - Bubble UI", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Neuspješno čitanje sadržaja međuspremnika", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "Nema rezultata", "No results found": "Nema rezultata", "No search query generated": "Nije generiran upit za pretraživanje", + "No servers detected": "", "No skills found": "", "No source available": "Nema dostupnog izvora", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "Pozitivan stav", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "", "RESULT": "REZULTAT", "Retrieval": "", @@ -1584,6 +1592,7 @@ "Role": "Uloga", "RTL": "RTL", "Run": "", + "Run All": "", "Running": "Pokrenuto", "Running...": "Pokrenuto...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1774,6 +1783,7 @@ "Start a new conversation": "", "Start of the channel": "Početak kanala", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2118,6 +2128,8 @@ "You're now logged in.": "Sada ste prijavljeni.", "Your Account": "", "Your account status is currently pending activation.": "Status vašeg računa trenutno čeka aktivaciju.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/hu-HU/translation.json b/src/lib/i18n/locales/hu-HU/translation.json index 74a5b75d55..0a210ed323 100644 --- a/src/lib/i18n/locales/hu-HU/translation.json +++ b/src/lib/i18n/locales/hu-HU/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Karakterlimit az automatikus kiegészítés bemenetéhez", "Chart new frontiers": "Új határok feltérképezése", "Chat": "Beszélgetés", + "Chat archived.": "", "Chat Background Image": "Beszélgetés háttérkép", "Chat Bubble UI": "Beszélgetés buborék felület", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "Nem sikerült hozzáadni a fájlt.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "Nem sikerült csatlakozni a {{URL}} OpenAPI eszköszerverhez", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Nem sikerült olvasni a vágólap tartalmát", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "Nem található HTML, CSS vagy JavaScript tartalom.", "No inference engine with management support found": "Nem található kezelést támogató következtetési motor", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Nem található tudásbázis", "No memories to clear": "Nincs törlendő memória", @@ -1320,6 +1325,7 @@ "No results": "Nincs találat", "No results found": "Nincs találat", "No search query generated": "Nem generálódott keresési lekérdezés", + "No servers detected": "", "No skills found": "", "No source available": "Nincs elérhető forrás", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "Port", + "Ports": "", "Positive attitude": "Pozitív hozzáállás", "Prefer not to say": "", "Prefix ID": "Előtag azonosító", @@ -1571,6 +1578,7 @@ "Response splitting": "Válasz felosztás", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "Eredmény", "RESULT": "Eredmény", "Retrieval": "Visszakeresés", @@ -1583,6 +1591,7 @@ "Role": "Szerep", "RTL": "RTL", "Run": "Futtatás", + "Run All": "", "Running": "Fut", "Running...": "Fut...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "A csatorna eleje", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "Sikeresen bejelentkezett.", "Your Account": "", "Your account status is currently pending activation.": "Fiókja jelenleg aktiválásra vár.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "A teljes hozzájárulása közvetlenül a bővítmény fejlesztőjéhez kerül; az Open WebUI nem vesz le százalékot. Azonban a választott támogatási platformnak lehetnek saját díjai.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/id-ID/translation.json b/src/lib/i18n/locales/id-ID/translation.json index 7dde9a33ad..6e78717c3f 100644 --- a/src/lib/i18n/locales/id-ID/translation.json +++ b/src/lib/i18n/locales/id-ID/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "Obrolan", + "Chat archived.": "", "Chat Background Image": "Gambar Latar Belakang Obrolan", "Chat Bubble UI": "UI Gelembung Obrolan", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Gagal membaca konten papan klip", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "Tidak ada hasil yang ditemukan", "No results found": "Tidak ada hasil yang ditemukan", "No search query generated": "Tidak ada permintaan pencarian yang dibuat", + "No servers detected": "", "No skills found": "", "No source available": "Tidak ada sumber yang tersedia", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "Sikap positif", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "", "RESULT": "HASIL", "Retrieval": "", @@ -1582,6 +1590,7 @@ "Role": "Peran", "RTL": "RTL", "Run": "", + "Run All": "", "Running": "Berjalan", "Running...": "Berjalan...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1772,6 +1781,7 @@ "Start a new conversation": "", "Start of the channel": "Awal saluran", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2116,6 +2126,8 @@ "You're now logged in.": "Anda sekarang sudah masuk.", "Your Account": "", "Your account status is currently pending activation.": "Status akun Anda saat ini sedang menunggu aktivasi.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/ie-GA/translation.json b/src/lib/i18n/locales/ie-GA/translation.json index f03feb1c42..d711c5fbe1 100644 --- a/src/lib/i18n/locales/ie-GA/translation.json +++ b/src/lib/i18n/locales/ie-GA/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Teorainn charachtair le haghaidh ionchur giniúna uathchríochnaithe", "Chart new frontiers": "Cairt teorainneacha nua", "Chat": "Comhrá", + "Chat archived.": "", "Chat Background Image": "Íomhá Cúlra Comhrá", "Chat Bubble UI": "Comhrá Bubble UI", "Chat Completions": "Críochnuithe Comhrá", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "Éifeacht Céimnithe le haghaidh Sruthú Téacs", "Failed to add file.": "Theip ar an gcomhad a chur leis.", "Failed to add members": "Theip ar bhaill a chur leis", + "Failed to archive chat.": "", "Failed to attach file": "Theip ar an gcomhad a cheangal", "Failed to clear status": "Theip ar an stádas a ghlanadh", "Failed to connect to {{URL}} OpenAPI tool server": "Theip ar nascadh le {{URL}} freastalaí uirlisí OpenAPI", @@ -836,9 +838,11 @@ "Failed to generate title": "Theip ar an teideal a ghiniúint", "Failed to import models": "Theip ar samhail a iompórtáil", "Failed to load chat preview": "Theip ar réamhamharc comhrá a lódáil", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "Theip ar an gcomhad Excel/CSV a lódáil. Déan iarracht é a íoslódáil ina ionad.", "Failed to load file content.": "Theip ar lódáil ábhar an chomhaid.", "Failed to load Interface settings": "Theip ar shocruithe an Chomhéadain a lódáil", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "Theip ar an gcomhrá a bhogadh", "Failed to process URL: {{url}}": "Theip ar phróiseáil an URL: {{url}}", "Failed to read clipboard contents": "Theip ar ábhar gearrthaisce a lé", @@ -1305,6 +1309,7 @@ "No history available": "Níl aon stair ar fáil", "No HTML, CSS, or JavaScript content found.": "Níor aimsíodh aon ábhar HTML, CSS nó JavaScript.", "No inference engine with management support found": "Níor aimsíodh aon inneall tátail le tacaíocht bhainistíochta", + "No kernel": "", "No knowledge bases found.": "Níor aimsíodh aon bhunachair eolais.", "No knowledge found": "Níor aimsíodh aon eolas", "No memories to clear": "Gan cuimhní cinn a ghlanadh", @@ -1320,6 +1325,7 @@ "No results": "Níl aon torthaí le fáil", "No results found": "Níl aon torthaí le fáil", "No search query generated": "Ní ghintear aon cheist cuardaigh", + "No servers detected": "", "No skills found": "Níor aimsíodh aon scileanna", "No source available": "Níl aon fhoinse ar fáil", "No sources found": "Níor aimsíodh aon fhoinsí", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "Roghnaigh úsáideoir amháin ar a laghad don chainéal Teachtaireachtaí Díreacha.", "Please wait until all files are uploaded.": "Fan go dtí go mbeidh na comhaid go léir uaslódáilte.", "Port": "Port", + "Ports": "", "Positive attitude": "Dearcadh dearfach", "Prefer not to say": "Is fearr liom gan a rá", "Prefix ID": "Aitheantas Réimír", @@ -1571,6 +1578,7 @@ "Response splitting": "Scoilt freagartha", "Response Watermark": "Comhartha Uisce Freagartha", "Responses": "Freagraí", + "Restart": "", "Result": "Toradh", "RESULT": "Toradh", "Retrieval": "Aisghabháil", @@ -1583,6 +1591,7 @@ "Role": "Ról", "RTL": "RTL", "Run": "Rith", + "Run All": "", "Running": "Ag rith", "Running...": "Ag rith...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "Ritheann sé tascanna leabaithe ag an am céanna chun luas a chur leis an bpróiseáil. Múch é má bhíonn teorainneacha ráta ina bhfadhb.", @@ -1773,6 +1782,7 @@ "Start a new conversation": "Tosaigh comhrá nua", "Start of the channel": "Tús an chainéil", "Start Tag": "Clib Tosaigh", + "Starting kernel...": "", "Status": "Stádas", "Status cleared successfully": "Glanadh an stádais go rathúil", "Status updated successfully": "Nuashonraíodh an stádas go rathúil", @@ -2117,6 +2127,8 @@ "You're now logged in.": "Tá tú logáilte isteach anois.", "Your Account": "Do Chuntas", "Your account status is currently pending activation.": "Tá stádas do chuntais ar feitheamh faoi ghníomhachtú.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Rachaidh do ranníocaíocht iomlán go díreach chuig an bhforbróir breiseán; Ní ghlacann Open WebUI aon chéatadán. Mar sin féin, d'fhéadfadh a tháillí féin a bheith ag an ardán maoinithe roghnaithe.", "Your message text or inputs": "Téacs nó ionchur do theachtaireachta", "Your usage stats have been successfully synced.": "Tá do staitisticí úsáide sioncronaithe go rathúil.", diff --git a/src/lib/i18n/locales/it-IT/translation.json b/src/lib/i18n/locales/it-IT/translation.json index 5c262434af..56cd7836b3 100644 --- a/src/lib/i18n/locales/it-IT/translation.json +++ b/src/lib/i18n/locales/it-IT/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Limite di caratteri per l'input di generazione dell'autocompletamento", "Chart new frontiers": "Traccia nuove frontiere", "Chat": "Chat", + "Chat archived.": "", "Chat Background Image": "Immagine di sfondo chat", "Chat Bubble UI": "UI bubble chat", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "Impossibile aggiungere il file.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "Impossibile connettersi al server dello strumento OpenAPI {{URL}}", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "Impossibile caricare il contenuto del file.", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Impossibile leggere il contenuto degli appunti", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "Nessun contenuto HTML, CSS o JavaScript trovato.", "No inference engine with management support found": "Nessun motore di inferenza con supporto per la gestione trovato", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Nessuna conoscenza trovata", "No memories to clear": "Nessun ricordo da cancellare", @@ -1320,6 +1325,7 @@ "No results": "Nessun risultato trovato", "No results found": "Nessun risultato trovato", "No search query generated": "Nessuna query di ricerca generata", + "No servers detected": "", "No skills found": "", "No source available": "Nessuna fonte disponibile", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "Porta", + "Ports": "", "Positive attitude": "Attitudine positiva", "Prefer not to say": "", "Prefix ID": "ID prefisso", @@ -1571,6 +1578,7 @@ "Response splitting": "Divisione della risposta", "Response Watermark": "Watermark della richiesta", "Responses": "", + "Restart": "", "Result": "Risultato", "RESULT": "Risultato", "Retrieval": "Recupero ricordo", @@ -1584,6 +1592,7 @@ "Role": "Ruolo", "RTL": "RTL", "Run": "Esegui", + "Run All": "", "Running": "In esecuzione", "Running...": "In esecuzione...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1774,6 +1783,7 @@ "Start a new conversation": "", "Start of the channel": "Inizio del canale", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2118,6 +2128,8 @@ "You're now logged in.": "Ora hai effettuato l'accesso.", "Your Account": "", "Your account status is currently pending activation.": "Lo stato del tuo account è attualmente in attesa di attivazione.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Il tuo intero contributo andrà direttamente allo sviluppatore del plugin; Open WebUI non prende alcuna percentuale. Tuttavia, la piattaforma di finanziamento scelta potrebbe avere le proprie commissioni.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/ja-JP/translation.json b/src/lib/i18n/locales/ja-JP/translation.json index 062f6c7b00..0532d958b8 100644 --- a/src/lib/i18n/locales/ja-JP/translation.json +++ b/src/lib/i18n/locales/ja-JP/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "オートコンプリート生成入力の文字数の制限", "Chart new frontiers": "新しいフロンティアを切り開く", "Chat": "チャット", + "Chat archived.": "", "Chat Background Image": "チャットの背景画像", "Chat Bubble UI": "チャットバブルUI", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "ストリームテキストのフェーディング効果", "Failed to add file.": "ファイルの追加に失敗しました。", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "{{URL}} OpenAPIツールサーバーへの接続に失敗しました。", @@ -836,9 +838,11 @@ "Failed to generate title": "タイトルの生成に失敗しました。", "Failed to import models": "", "Failed to load chat preview": "チャットプレビューを読み込めませんでした。", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "ファイルの内容を読み込めませんでした。", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "チャットの移動に失敗しました。", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "クリップボードの内容を読み取れませんでした。", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "HTML、CSS、またはJavaScriptの内容が見つかりません。", "No inference engine with management support found": "管理サポートのある推論エンジンが見つかりません。", + "No kernel": "", "No knowledge bases found.": "ナレッジベースが見つかりません", "No knowledge found": "ナレッジベースが見つかりません", "No memories to clear": "クリアするメモリがありません", @@ -1320,6 +1325,7 @@ "No results": "結果が見つかりません", "No results found": "結果が見つかりません", "No search query generated": "検索クエリは生成されません", + "No servers detected": "", "No skills found": "", "No source available": "使用可能なソースがありません", "No sources found": "ソースが見つかりません", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "ファイルがすべてアップロードされるまでお待ちください。", "Port": "ポート", + "Ports": "", "Positive attitude": "ポジティブな態度", "Prefer not to say": "回答しない", "Prefix ID": "Prefix ID", @@ -1571,6 +1578,7 @@ "Response splitting": "応答の分割", "Response Watermark": "応答のウォーターマーク", "Responses": "", + "Restart": "", "Result": "結果", "RESULT": "結果", "Retrieval": "検索", @@ -1582,6 +1590,7 @@ "Role": "ロール", "RTL": "RTL", "Run": "実行", + "Run All": "", "Running": "実行中", "Running...": "実行中...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1772,6 +1781,7 @@ "Start a new conversation": "新しい会話を開始", "Start of the channel": "チャンネルの開始", "Start Tag": "", + "Starting kernel...": "", "Status": "ステータス", "Status cleared successfully": "正常にステータスをクリアしました", "Status updated successfully": "正常にステータスを更新しました", @@ -2116,6 +2126,8 @@ "You're now logged in.": "ログインしました。", "Your Account": "あなたのアカウント", "Your account status is currently pending activation.": "あなたのアカウント状態は現在登録認証待ちです。", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "あなたの全ての寄付はプラグイン開発者へ直接送られます。Open WebUI は手数料を一切取りません。ただし、選択した資金提供プラットフォーム側に手数料が発生する場合があります。", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/ka-GE/translation.json b/src/lib/i18n/locales/ka-GE/translation.json index ce7cdb61f1..78cf199339 100644 --- a/src/lib/i18n/locales/ka-GE/translation.json +++ b/src/lib/i18n/locales/ka-GE/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "ახალი საზღვრების დახაზვა", "Chat": "ჩატი", + "Chat archived.": "", "Chat Background Image": "ჩატის ფონის გამოსახულება", "Chat Bubble UI": "ჩატის ბუშტის ინტერფეისი", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "ფაილის დამატების შეცდომა.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "სათაურის გენერაცია ჩავარდა", "Failed to import models": "მოდელების შემოტანა ჩავარდა", "Failed to load chat preview": "ვიდეოს მინიატურის ჩატვირთვა ჩავარდა", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "ფაილის შემცველობის ჩატვირთვა ჩავარდა.", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "ჩატის გადატანა ჩავარდა", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "ბუფერის შემცველობის წაკითხვა ჩავარდა", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "ცოდნა აღმოჩენილი არაა", "No memories to clear": "გასასუფთავებელი მოგონებების გარეშე", @@ -1320,6 +1325,7 @@ "No results": "შედეგების გარეშე", "No results found": "შედეგების გარეშე", "No search query generated": "ძებნის მოთხოვნა არ შექმნილა", + "No servers detected": "", "No skills found": "", "No source available": "წყარო ხელმისაწვდომი არაა", "No sources found": "წყაროები აღმოჩენილი არაა", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "პორტი", + "Ports": "", "Positive attitude": "პოზიტიური დამოკიდებულება", "Prefer not to say": "მირჩევნია, არ ვთქვა", "Prefix ID": "პრეფიქსის ID", @@ -1571,6 +1578,7 @@ "Response splitting": "", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "შედეგი", "RESULT": "შედეგი", "Retrieval": "მიღება", @@ -1583,6 +1591,7 @@ "Role": "როლი", "RTL": "RTL", "Run": "გაშვება", + "Run All": "", "Running": "გაშვებულია", "Running...": "გაშვებულია...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "არხის დასაწყისი", "Start Tag": "დაწყების ჭდე", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "ახლა შესული ბრძანდებით.", "Your Account": "თქვენი ანგარიში", "Your account status is currently pending activation.": "თქვენი ანგარიშის სტატუსი ამჟამად ელოდება აქტივაციას.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/kab-DZ/translation.json b/src/lib/i18n/locales/kab-DZ/translation.json index 887101bedb..ee36320599 100644 --- a/src/lib/i18n/locales/kab-DZ/translation.json +++ b/src/lib/i18n/locales/kab-DZ/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "Asqerdec", + "Chat archived.": "", "Chat Background Image": "Tugna n ugilal n udiwenni", "Chat Bubble UI": "Agrudem n tembulin n udiwenni", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "Tecceḍ tmerna n ufaylu.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "Ur yessaweḍ ara ad yeqqen ɣer {{URL}} n uqeddac n yifecka OpenAPI", @@ -836,9 +838,11 @@ "Failed to generate title": "Ur yessaweḍ ara ad d-yawi azwel", "Failed to import models": "", "Failed to load chat preview": "Yecceḍ usali n teskant n udiwenni", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "Ur yessaweḍ ara ad d-yessali agbur n yifuyla.", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "Tuccḍa deg unkaz n udiwenni", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Ur yessaweḍ ara ad iɣer agbur n tfelwit", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "Ulac agbur HTML, CSS neɣ JavaScript i d-yufraren.", "No inference engine with management support found": "Ulac amsedday n unalkam s tallelt n usefrek i yettwafen", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Ulac tamussni i yettwafen", "No memories to clear": "Ulac aktayen ibanen", @@ -1320,6 +1325,7 @@ "No results": "Ulac igmaḍ yettwafen", "No results found": "Ulac igmaḍ yettwafen", "No search query generated": "Ulac tuttra n unadi yettusirwen", + "No servers detected": "", "No skills found": "", "No source available": "Ulac aɣbalu yettwafen", "No sources found": "Ulac iɣbula yettwafen", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "Ttxil-k·m, ṛǧu alamma ulin-d akk ifuyla.", "Port": "Tawwurt", + "Ports": "", "Positive attitude": "", "Prefer not to say": "Smenyafeɣ ur d-qqareɣ ara", "Prefix ID": "Asulay ID n uzwir", @@ -1571,6 +1578,7 @@ "Response splitting": "Beṭṭu n tririt", "Response Watermark": "Ticreḍt tafrawant n tririt", "Responses": "", + "Restart": "", "Result": "Agmuḍ", "RESULT": "Agmuḍ", "Retrieval": "Anadi", @@ -1583,6 +1591,7 @@ "Role": "Tamlilt", "RTL": "RTL", "Run": "Selkem", + "Run All": "", "Running": "Aselkem", "Running...": "Aselkem...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "Tazwara n ubadu", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "Aql-ik teqqned imir-a.", "Your Account": "Amiḍan-ik·im", "Your account status is currently pending activation.": "Addad-nnem n umiḍan atan yettṛaju armad.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/ko-KR/translation.json b/src/lib/i18n/locales/ko-KR/translation.json index d15647355c..234638867c 100644 --- a/src/lib/i18n/locales/ko-KR/translation.json +++ b/src/lib/i18n/locales/ko-KR/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "자동 완성 생성 입력 문자 제한", "Chart new frontiers": "새로운 영역 개척", "Chat": "채팅", + "Chat archived.": "", "Chat Background Image": "채팅 배경 이미지", "Chat Bubble UI": "버블형 채팅 UI", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "스트리밍 텍스트에 대한 페이드 효과", "Failed to add file.": "파일추가에 실패했습니다", "Failed to add members": "멤버 추가에 실패했습니다", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "상태 초기화에 실패했습니다", "Failed to connect to {{URL}} OpenAPI tool server": "{{URL}} OpenAPI 도구 서버 연결 실패", @@ -836,9 +838,11 @@ "Failed to generate title": "제목 생성 실패", "Failed to import models": "모델 가져오기 실패", "Failed to load chat preview": "채팅 미리보기 로드 실패", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "파일 내용 로드 실패.", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "채팅 이동 실패", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "클립보드 내용 가져오기를 실패하였습니다", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "HTML, CSS, JavaScript이 발견되지 않았습니다", "No inference engine with management support found": "관리 지원이 포함된 추론 엔진을 찾을 수 없습니다", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "지식 기반을 찾을 수 없습니다", "No memories to clear": "메모리를 정리할 수 없습니다", @@ -1320,6 +1325,7 @@ "No results": "결과가 없습니다", "No results found": "결과를 찾을 수 없습니다", "No search query generated": "검색어가 생성되지 않았습니다", + "No servers detected": "", "No skills found": "", "No source available": "사용 가능한 소스가 없습니다.", "No sources found": "소스를 찾을 수 없습니다", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "1:1 메시지 채널에 참여할 사용자를 최소 한 명 선택해주세요.", "Please wait until all files are uploaded.": "모든 파일이 업로드될 때까지 기다려 주세요.", "Port": "포트", + "Ports": "", "Positive attitude": "긍정적인 자세", "Prefer not to say": "언급하고 싶지 않습니다.", "Prefix ID": "Prefix ID", @@ -1571,6 +1578,7 @@ "Response splitting": "응답 나누기", "Response Watermark": "응답 워터마크", "Responses": "", + "Restart": "", "Result": "결과", "RESULT": "결과", "Retrieval": "검색", @@ -1582,6 +1590,7 @@ "Role": "역할", "RTL": "RTL", "Run": "실행", + "Run All": "", "Running": "실행 중", "Running...": "실행 중...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1772,6 +1781,7 @@ "Start a new conversation": "새 대화 시작", "Start of the channel": "채널 시작", "Start Tag": "시작 태그", + "Starting kernel...": "", "Status": "상태", "Status cleared successfully": "상태 초기화에 성공했습니다", "Status updated successfully": "상태 업데이트에 성공했습니다", @@ -2116,6 +2126,8 @@ "You're now logged in.": "로그인되었습니다.", "Your Account": "계정", "Your account status is currently pending activation.": "현재 계정은 아직 활성화되지 않았습니다.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "당신의 모든 기여는 곧바로 플러그인 개발자에게 갑니다; Open WebUI는 수수료를 받지 않습니다. 다만, 선택한 후원 플랫폼은 수수료를 가져갈 수 있습니다.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/lt-LT/translation.json b/src/lib/i18n/locales/lt-LT/translation.json index e6354753bb..b6195ff803 100644 --- a/src/lib/i18n/locales/lt-LT/translation.json +++ b/src/lib/i18n/locales/lt-LT/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "Pokalbis", + "Chat archived.": "", "Chat Background Image": "Pokalbio galinė užsklanda", "Chat Bubble UI": "Pokalbio burbulo sąsaja", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Nepavyko perskaityti kopijuoklės", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "Rezultatų nerasta", "No results found": "Rezultatų nerasta", "No search query generated": "Paieškos užklausa nesugeneruota", + "No servers detected": "", "No skills found": "", "No source available": "Šaltinių nerasta", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "Pozityvus elgesys", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "", "RESULT": "REZULTATAS", "Retrieval": "", @@ -1585,6 +1593,7 @@ "Role": "Rolė", "RTL": "RTL", "Run": "", + "Run All": "", "Running": "Veikia", "Running...": "Veikia...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1775,6 +1784,7 @@ "Start a new conversation": "", "Start of the channel": "Kanalo pradžia", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2119,6 +2129,8 @@ "You're now logged in.": "Esate prisijungę.", "Your Account": "", "Your account status is currently pending activation.": "Jūsų paskyra laukia administratoriaus patvirtinimo.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Jūsų finansinis prisidėjimas tiesiogiai keliaus modulio kūrėjui.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/lv-LV/translation.json b/src/lib/i18n/locales/lv-LV/translation.json index 5b2210c835..1d1f4724ae 100644 --- a/src/lib/i18n/locales/lv-LV/translation.json +++ b/src/lib/i18n/locales/lv-LV/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Rakstzīmju ierobežojums automātiskās pabeigšanas ievadei", "Chart new frontiers": "Atklāj jaunas robežas", "Chat": "Tērzēšana", + "Chat archived.": "", "Chat Background Image": "Tērzēšanas fona attēls", "Chat Bubble UI": "Tērzēšanas burbuļa saskarne", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "Izbalēšanas efekts straumēšanas tekstam", "Failed to add file.": "Neizdevās pievienot failu.", "Failed to add members": "Neizdevās pievienot dalībniekus", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "Neizdevās notīrīt statusu", "Failed to connect to {{URL}} OpenAPI tool server": "Neizdevās savienoties ar {{URL}} OpenAPI rīku serveri", @@ -836,9 +838,11 @@ "Failed to generate title": "Neizdevās ģenerēt virsrakstu", "Failed to import models": "Neizdevās importēt modeļus", "Failed to load chat preview": "Neizdevās ielādēt tērzēšanas priekšskatījumu", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "Neizdevās ielādēt Excel/CSV failu. Lūdzu, mēģiniet to lejupielādēt.", "Failed to load file content.": "Neizdevās ielādēt faila saturu.", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "Neizdevās pārvietot tērzēšanu", "Failed to process URL: {{url}}": "Neizdevās apstrādāt URL: {{url}}", "Failed to read clipboard contents": "Neizdevās nolasīt starpliktuves saturu", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "HTML, CSS vai JavaScript saturs nav atrasts.", "No inference engine with management support found": "Nav atrasts secinājumu dzinējs ar pārvaldības atbalstu", + "No kernel": "", "No knowledge bases found.": "Zināšanu bāzes nav atrastas.", "No knowledge found": "Zināšanau bāze nav atrasta", "No memories to clear": "Nav atmiņu, ko notīrīt", @@ -1320,6 +1325,7 @@ "No results": "Nav rezultātu", "No results found": "Rezultāti nav atrasti", "No search query generated": "Meklēšanas vaicājums nav ģenerēts", + "No servers detected": "", "No skills found": "", "No source available": "Avots nav pieejams", "No sources found": "Avoti nav atrasti", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "Lūdzu, izvēlieties vismaz vienu lietotāju tiešo ziņojumu kanālam.", "Please wait until all files are uploaded.": "Lūdzu, pagaidiet, līdz visi faili ir augšupielādēti.", "Port": "Ports", + "Ports": "", "Positive attitude": "Pozitīva attieksme", "Prefer not to say": "Nevēlos atklāt", "Prefix ID": "Prefiksa ID", @@ -1571,6 +1578,7 @@ "Response splitting": "Atbilžu sadalīšana", "Response Watermark": "Atbildes ūdenszīme", "Responses": "", + "Restart": "", "Result": "Rezultāts", "RESULT": "REZULTĀTS", "Retrieval": "Izgūšana", @@ -1584,6 +1592,7 @@ "Role": "Loma", "RTL": "RTL", "Run": "Palaist", + "Run All": "", "Running": "Darbojas", "Running...": "Darbojas...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "Palaiž iegulšanas uzdevumus vienlaicīgi, lai paātrinātu apstrādi. Izslēdziet, ja rodas ātruma ierobežojumu problēmas.", @@ -1774,6 +1783,7 @@ "Start a new conversation": "Sākt jaunu sarunu", "Start of the channel": "Kanāla sākums", "Start Tag": "Sākuma tags", + "Starting kernel...": "", "Status": "Statuss", "Status cleared successfully": "Statuss veiksmīgi notīrīts", "Status updated successfully": "Statuss veiksmīgi atjaunināts", @@ -2118,6 +2128,8 @@ "You're now logged in.": "Jūs tagad esat pieteicies.", "Your Account": "Jūsu konts", "Your account status is currently pending activation.": "Jūsu konta statuss pašlaik gaida aktivizēšanu.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Visa jūsu iemaksa nonāks tieši pie spraudņa izstrādātāja; Open WebUI neņem nekādu procentu. Tomēr izvēlētajai finansējuma platformai var būt savas maksas.", "Your message text or inputs": "Jūsu ziņojuma teksts vai ievades", "Your usage stats have been successfully synced.": "Jūsu lietošanas statistika ir veiksmīgi sinhronizēta.", diff --git a/src/lib/i18n/locales/ms-MY/translation.json b/src/lib/i18n/locales/ms-MY/translation.json index 476fa44174..b6459c4817 100644 --- a/src/lib/i18n/locales/ms-MY/translation.json +++ b/src/lib/i18n/locales/ms-MY/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "Perbualan", + "Chat archived.": "", "Chat Background Image": "Imej Latar Belakang Perbualan", "Chat Bubble UI": "Antaramuka Buih Perbualan", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Gagal membaca konten papan klip", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "Tiada keputusan dijumpai", "No results found": "Tiada keputusan dijumpai", "No search query generated": "Tiada pertanyaan carian dijana", + "No servers detected": "", "No skills found": "", "No source available": "Tiada sumber tersedia", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "Sikap positif", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "", "RESULT": "KEPUTUSAN", "Retrieval": "", @@ -1582,6 +1590,7 @@ "Role": "Peranan", "RTL": "RTL", "Run": "Jalankan", + "Run All": "", "Running": "Sedang dijalankan", "Running...": "Sedang dijalankan...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1772,6 +1781,7 @@ "Start a new conversation": "", "Start of the channel": "Permulaan saluran", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2116,6 +2126,8 @@ "You're now logged in.": "Anda kini telah log masuk.", "Your Account": "", "Your account status is currently pending activation.": "Status akaun anda ialah sedang menunggu pengaktifan.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Seluruh sumbangan anda akan dihantar terus kepada pembangun 'plugin'; Open WebUI tidak mengambil sebarang peratusan keuntungan daripadanya. Walau bagaimanapun, platform pembiayaan yang dipilih mungkin mempunyai caj tersendiri.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/nb-NO/translation.json b/src/lib/i18n/locales/nb-NO/translation.json index 4516858509..d4ced2a235 100644 --- a/src/lib/i18n/locales/nb-NO/translation.json +++ b/src/lib/i18n/locales/nb-NO/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Begrensning av tegn for generering av autofullføring", "Chart new frontiers": "Kartlegg ny områder", "Chat": "Chat", + "Chat archived.": "", "Chat Background Image": "Bakgrunnsbilde for chat", "Chat Bubble UI": "Grensesnitt for chat-boble", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "Kan ikke legge til filen.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Kan ikke lese utklippstavlens innhold", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "Finner ikke noe HTML, CSS- eller JavaScript-innhold.", "No inference engine with management support found": "Fant ingen konklusjonsmotor med støtte for administrasjon", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Finner ingen kunnskaper", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "Finner ingen resultater", "No results found": "Finner ingen resultater", "No search query generated": "Ingen søkespørringer er generert", + "No servers detected": "", "No skills found": "", "No source available": "Ingen kilde tilgjengelig", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "Port", + "Ports": "", "Positive attitude": "Positiv holdning", "Prefer not to say": "", "Prefix ID": "Prefiks-ID", @@ -1571,6 +1578,7 @@ "Response splitting": "Oppdeling av svar", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "Resultat", "RESULT": "Resultat", "Retrieval": "", @@ -1583,6 +1591,7 @@ "Role": "Rolle", "RTL": "RTL", "Run": "Kjør", + "Run All": "", "Running": "Kjører", "Running...": "Kjører...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "Starten av kanalen", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "Du er nå logget inn.", "Your Account": "", "Your account status is currently pending activation.": "Status på kontoen din er for øyeblikket ventende på aktivering.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Hele beløpet går uavkortet til utvikleren av tillegget. Open WebUI mottar ikke deler av beløpet. Den valgte betalingsplattformen kan ha gebyrer.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/nl-NL/translation.json b/src/lib/i18n/locales/nl-NL/translation.json index 1475aa0ff9..886395fea4 100644 --- a/src/lib/i18n/locales/nl-NL/translation.json +++ b/src/lib/i18n/locales/nl-NL/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Karakterlimiet voor automatische generatieinvoer", "Chart new frontiers": "Verken nieuwe grenzen", "Chat": "Chat", + "Chat archived.": "", "Chat Background Image": "Chatachtergrond", "Chat Bubble UI": "Chatbubble-UI", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "Het is niet gelukt om het bestand toe te voegen.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "Kan geen verbinding maken met {{URL}} OpenAPI gereedschapserver", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Kan klembord inhoud niet lezen", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "Geen HTML, CSS, of JavaScript inhoud gevonden", "No inference engine with management support found": "Geen inferentie-engine met beheerondersteuning gevonden", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Geen kennis gevonden", "No memories to clear": "Geen herinneringen om op te ruimen", @@ -1320,6 +1325,7 @@ "No results": "Geen resultaten gevonden", "No results found": "Geen resultaten gevonden", "No search query generated": "Geen zoekopdracht gegenereerd", + "No servers detected": "", "No skills found": "", "No source available": "Geen bron beschikbaar", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "Poort", + "Ports": "", "Positive attitude": "Positieve houding", "Prefer not to say": "", "Prefix ID": "Voorvoegsel-ID", @@ -1571,6 +1578,7 @@ "Response splitting": "Antwoord splitsing", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "Resultaat", "RESULT": "Resultaat", "Retrieval": "Ophalen", @@ -1583,6 +1591,7 @@ "Role": "Rol", "RTL": "RNL", "Run": "Uitvoeren", + "Run All": "", "Running": "Aan het uitvoeren", "Running...": "Aan het uitvoeren...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "Begin van het kanaal", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "Je bent nu ingelogd.", "Your Account": "", "Your account status is currently pending activation.": "Je accountstatus wacht nu op activatie", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Je volledige bijdrage gaat direct naar de ontwikkelaar van de plugin; Open WebUI neemt hier geen deel van. Het gekozen financieringsplatform kan echter wel zijn eigen kosten hebben.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/pa-IN/translation.json b/src/lib/i18n/locales/pa-IN/translation.json index 5cb4cb5ed1..3edbf74bd8 100644 --- a/src/lib/i18n/locales/pa-IN/translation.json +++ b/src/lib/i18n/locales/pa-IN/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "ਗੱਲਬਾਤ", + "Chat archived.": "", "Chat Background Image": "", "Chat Bubble UI": "ਗੱਲਬਾਤ ਬਬਲ UI", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "ਕਲਿੱਪਬੋਰਡ ਸਮੱਗਰੀ ਪੜ੍ਹਣ ਵਿੱਚ ਅਸਫਲ", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "ਕੋਈ ਨਤੀਜੇ ਨਹੀਂ ਮਿਲੇ", "No results found": "ਕੋਈ ਨਤੀਜੇ ਨਹੀਂ ਮਿਲੇ", "No search query generated": "ਕੋਈ ਖੋਜ ਪੁੱਛਗਿੱਛ ਤਿਆਰ ਨਹੀਂ ਕੀਤੀ ਗਈ", + "No servers detected": "", "No skills found": "", "No source available": "ਕੋਈ ਸਰੋਤ ਉਪਲਬਧ ਨਹੀਂ", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "ਸਕਾਰਾਤਮਕ ਰਵੱਈਆ", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "", "RESULT": "ਨਤੀਜਾ", "Retrieval": "", @@ -1583,6 +1591,7 @@ "Role": "ਭੂਮਿਕਾ", "RTL": "RTL", "Run": "", + "Run All": "", "Running": "", "Running...": "ਚੱਲ ਰਿਹਾ ਹੈ...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "ਚੈਨਲ ਦੀ ਸ਼ੁਰੂਆਤ", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "ਤੁਸੀਂ ਹੁਣ ਲੌਗ ਇਨ ਹੋ ਗਏ ਹੋ।", "Your Account": "", "Your account status is currently pending activation.": "", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/pl-PL/translation.json b/src/lib/i18n/locales/pl-PL/translation.json index 5494b0ecb4..da19789867 100644 --- a/src/lib/i18n/locales/pl-PL/translation.json +++ b/src/lib/i18n/locales/pl-PL/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Limit znaków dla wejścia autouzupełniania", "Chart new frontiers": "Poznawaj nowe możliwości", "Chat": "Czat", + "Chat archived.": "", "Chat Background Image": "Tło czatu", "Chat Bubble UI": "Wygląd dymków czatu", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "Efekt zanikania generowanego tekstu", "Failed to add file.": "Nie udało się dodać pliku.", "Failed to add members": "Nie udało się dodać członków", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "Nie udało się wyczyścić statusu", "Failed to connect to {{URL}} OpenAPI tool server": "Nie udało się połączyć z serwerem narzędzi OpenAPI {{URL}}", @@ -836,9 +838,11 @@ "Failed to generate title": "Nie udało się wygenerować tytułu", "Failed to import models": "Nie udało się zaimportować modeli", "Failed to load chat preview": "Nie udało się załadować podglądu czatu", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "Nie udało się załadować pliku Excel/CSV. Spróbuj go pobrać.", "Failed to load file content.": "Nie udało się załadować zawartości pliku.", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "Nie udało się przenieść czatu", "Failed to process URL: {{url}}": "Nie udało się przetworzyć URL: {{url}}", "Failed to read clipboard contents": "Nie udało się odczytać schowka", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "Nie znaleziono treści HTML, CSS ani JS.", "No inference engine with management support found": "Nie znaleziono silnika wnioskowania ze wsparciem zarządzania", + "No kernel": "", "No knowledge bases found.": "Nie znaleziono baz wiedzy.", "No knowledge found": "Nie znaleziono wiedzy", "No memories to clear": "Brak danych w pamięci do wyczyszczenia", @@ -1320,6 +1325,7 @@ "No results": "Brak wyników", "No results found": "Brak wyników", "No search query generated": "Nie wygenerowano zapytania wyszukiwania", + "No servers detected": "", "No skills found": "", "No source available": "Brak dostępnego źródła", "No sources found": "Nie znaleziono źródeł", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "Wybierz co najmniej jednego użytkownika do czatu prywatnego.", "Please wait until all files are uploaded.": "Poczekaj na przesłanie wszystkich plików.", "Port": "Port", + "Ports": "", "Positive attitude": "Pozytywne nastawienie", "Prefer not to say": "Wolę nie mówić", "Prefix ID": "Prefix ID", @@ -1571,6 +1578,7 @@ "Response splitting": "Podział odpowiedzi", "Response Watermark": "Znak wodny odpowiedzi", "Responses": "", + "Restart": "", "Result": "Wynik", "RESULT": "WYNIK", "Retrieval": "Retrieval (Pobieranie)", @@ -1585,6 +1593,7 @@ "Role": "Rola", "RTL": "RTL (Od prawej)", "Run": "Uruchom", + "Run All": "", "Running": "Działa", "Running...": "Działa...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "Uruchamia zadania embeddingu współbieżnie. Wyłącz, jeśli masz limity API.", @@ -1775,6 +1784,7 @@ "Start a new conversation": "Rozpocznij nową rozmowę", "Start of the channel": "Początek kanału", "Start Tag": "Tag startowy", + "Starting kernel...": "", "Status": "Status", "Status cleared successfully": "Status wyczyszczony pomyślnie", "Status updated successfully": "Status zaktualizowany pomyślnie", @@ -2119,6 +2129,8 @@ "You're now logged in.": "Zalogowano pomyślnie.", "Your Account": "Twoje konto", "Your account status is currently pending activation.": "Twoje konto oczekuje na aktywację.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Cała wpłata trafia do twórcy pluginu; Open WebUI nie pobiera prowizji. Wybrana platforma płatnicza może jednak naliczać własne opłaty.", "Your message text or inputs": "Treść wiadomości lub dane wejściowe", "Your usage stats have been successfully synced.": "Twoje statystyki użycia zostały pomyślnie zsynchronizowane.", diff --git a/src/lib/i18n/locales/pt-BR/translation.json b/src/lib/i18n/locales/pt-BR/translation.json index daa7378fd1..74d0febaf7 100644 --- a/src/lib/i18n/locales/pt-BR/translation.json +++ b/src/lib/i18n/locales/pt-BR/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Limite de caracteres para entrada de geração de preenchimento automático", "Chart new frontiers": "Trace novas fronteiras", "Chat": "Chat", + "Chat archived.": "", "Chat Background Image": "Imagem de Fundo do Chat", "Chat Bubble UI": "Interface de Bolha de Chat", "Chat Completions": "Gerar Resposta", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "Efeito de Fade para texto em streaming", "Failed to add file.": "Falha ao adicionar arquivo.", "Failed to add members": "Falha ao adicionar membros", + "Failed to archive chat.": "", "Failed to attach file": "Falha ao anexar arquivo", "Failed to clear status": "Falha ao limpar o status", "Failed to connect to {{URL}} OpenAPI tool server": "Falha ao conectar ao servidor da ferramenta OpenAPI {{URL}}", @@ -836,9 +838,11 @@ "Failed to generate title": "Falha ao gerar título", "Failed to import models": "Falha ao importar modelos", "Failed to load chat preview": "Falha ao carregar a pré-visualização do chat", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "Não foi possível carregar o arquivo Excel/CSV. Tente baixá-lo em vez disso.", "Failed to load file content.": "Falha ao carregar o conteúdo do arquivo.", "Failed to load Interface settings": "Falha ao carregar configurações da Interface", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "Falha ao mover o chat", "Failed to process URL: {{url}}": "Falha ao processar URL: {{url}}", "Failed to read clipboard contents": "Falha ao ler o conteúdo da área de transferência", @@ -1305,6 +1309,7 @@ "No history available": "Não há histórico disponível.", "No HTML, CSS, or JavaScript content found.": "Nenhum conteúdo HTML, CSS ou JavaScript encontrado.", "No inference engine with management support found": "Nenhum mecanismo de inferência com suporte de gerenciamento encontrado", + "No kernel": "", "No knowledge bases found.": "Nenhuma base de conhecimento encontrada.", "No knowledge found": "Nenhum conhecimento encontrado", "No memories to clear": "Nenhuma memória para limpar", @@ -1320,6 +1325,7 @@ "No results": "Nenhum resultado encontrado", "No results found": "Nenhum resultado encontrado", "No search query generated": "Nenhuma consulta de pesquisa gerada", + "No servers detected": "", "No skills found": "Nenhuma skill encontrada", "No source available": "Nenhuma fonte disponível", "No sources found": "Nenhuma fonte encontrada", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "Por favor, selecione pelo menos um usuário para o canal de Mensagens Diretas.", "Please wait until all files are uploaded.": "Aguarde até que todos os arquivos sejam enviados.", "Port": "Porta", + "Ports": "", "Positive attitude": "Atitude positiva", "Prefer not to say": "Prefiro não dizer", "Prefix ID": "Prefixo ID", @@ -1571,6 +1578,7 @@ "Response splitting": "Divisão da Resposta", "Response Watermark": "Marca d'água de resposta", "Responses": "Respostas", + "Restart": "", "Result": "Resultado", "RESULT": "Resultado", "Retrieval": "Recuperação", @@ -1584,6 +1592,7 @@ "Role": "Função", "RTL": "Direita para Esquerda", "Run": "Executar", + "Run All": "", "Running": "Executando", "Running...": "Executando...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "Executa tarefas de incorporação simultaneamente para acelerar o processamento. Desative se os limites de taxa se tornarem um problema.", @@ -1774,6 +1783,7 @@ "Start a new conversation": "Iniciar uma nova conversa", "Start of the channel": "Início do canal", "Start Tag": "Tag inicial", + "Starting kernel...": "", "Status": "Status", "Status cleared successfully": "Status liberado com sucesso", "Status updated successfully": "Status atualizado com sucesso", @@ -2118,6 +2128,8 @@ "You're now logged in.": "Você agora está logado.", "Your Account": "Sua conta", "Your account status is currently pending activation.": "O status da sua conta está atualmente aguardando ativação.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Toda a sua contribuição irá diretamente para o desenvolvedor do plugin; o Open WebUI não retém nenhuma porcentagem. No entanto, a plataforma de financiamento escolhida pode ter suas próprias taxas.", "Your message text or inputs": "Seu texto de mensagem ou entradas", "Your usage stats have been successfully synced.": "Suas estatísticas de uso foram sincronizadas com sucesso.", diff --git a/src/lib/i18n/locales/pt-PT/translation.json b/src/lib/i18n/locales/pt-PT/translation.json index e1aa139957..dc7efc5700 100644 --- a/src/lib/i18n/locales/pt-PT/translation.json +++ b/src/lib/i18n/locales/pt-PT/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "Conversa", + "Chat archived.": "", "Chat Background Image": "", "Chat Bubble UI": "Bolha UI da Conversa", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Falha ao ler o conteúdo da área de transferência", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "Não foram encontrados resultados", "No results found": "Não foram encontrados resultados", "No search query generated": "Não foi gerada nenhuma consulta de pesquisa", + "No servers detected": "", "No skills found": "", "No source available": "Nenhuma fonte disponível", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "Atitude Positiva", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "", "RESULT": "RESULTADO", "Retrieval": "", @@ -1584,6 +1592,7 @@ "Role": "Função", "RTL": "RTL", "Run": "", + "Run All": "", "Running": "A correr", "Running...": "A correr...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1774,6 +1783,7 @@ "Start a new conversation": "", "Start of the channel": "Início do canal", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2118,6 +2128,8 @@ "You're now logged in.": "Você agora está conectado.", "Your Account": "", "Your account status is currently pending activation.": "O status da sua conta está atualmente com a ativação pendente.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/ro-RO/translation.json b/src/lib/i18n/locales/ro-RO/translation.json index 973e54d5af..2b953f16bb 100644 --- a/src/lib/i18n/locales/ro-RO/translation.json +++ b/src/lib/i18n/locales/ro-RO/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "Conversație", + "Chat archived.": "", "Chat Background Image": "Imagine de Fundal pentru Conversație", "Chat Bubble UI": "Interfață cu Bule de Conversație", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "Eșec la adăugarea fișierului.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Citirea conținutului clipboard-ului a eșuat", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "Niciun conținut HTML, CSS sau JavaScript găsit.", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Nu au fost găsite informații.", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "Nu au fost găsite rezultate", "No results found": "Nu au fost găsite rezultate", "No search query generated": "Nu a fost generată nicio interogare de căutare", + "No servers detected": "", "No skills found": "", "No source available": "Nicio sursă disponibilă", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "Atitudine pozitivă", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "Împărțirea răspunsurilor", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "Rezultat", "RESULT": "Rezultat", "Retrieval": "", @@ -1584,6 +1592,7 @@ "Role": "Rol", "RTL": "RTL", "Run": "Execută", + "Run All": "", "Running": "Rulează", "Running...": "Rulează...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1774,6 +1783,7 @@ "Start a new conversation": "", "Start of the channel": "Începutul canalului", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2118,6 +2128,8 @@ "You're now logged in.": "Acum ești autentificat.", "Your Account": "", "Your account status is currently pending activation.": "Statusul contului dvs. este în așteptare pentru activare.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Întreaga dvs. contribuție va merge direct la dezvoltatorul plugin-ului; Open WebUI nu ia niciun procent. Cu toate acestea, platforma de finanțare aleasă ar putea avea propriile taxe.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/ru-RU/translation.json b/src/lib/i18n/locales/ru-RU/translation.json index a966f6d728..7e36725824 100644 --- a/src/lib/i18n/locales/ru-RU/translation.json +++ b/src/lib/i18n/locales/ru-RU/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Ограничение количества символов для ввода при генерации автозаполнения", "Chart new frontiers": "Наметьте новые границы", "Chat": "Чат", + "Chat archived.": "", "Chat Background Image": "Фоновое изображение чата", "Chat Bubble UI": "Bubble UI чат", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "Эффект затухания для потокового текста", "Failed to add file.": "Не удалось добавить файл.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "Не удалось подключиться к серверу инструмента OpenAI {{URL}}", @@ -836,9 +838,11 @@ "Failed to generate title": "Не удалось сгенерировать заголовок", "Failed to import models": "", "Failed to load chat preview": "Не удалось загрузить предпросмотр чата", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "Не удалось загрузить содержимое файла.", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "Не удалось переместить чат", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Не удалось прочитать содержимое буфера обмена", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "Содержимое в формате HTML, CSS или JavaScript не найдено.", "No inference engine with management support found": "Механизм логического вывода с поддержкой управления не найден", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Знания не найдены", "No memories to clear": "Нет воспоминаний, которые нужно было бы очистить", @@ -1320,6 +1325,7 @@ "No results": "Результатов не найдено", "No results found": "Результатов не найдено", "No search query generated": "Поисковый запрос не сгенерирован", + "No servers detected": "", "No skills found": "", "No source available": "Нет доступных источников", "No sources found": "Источники не найдены", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "Пожалуйста, подождите, пока все файлы будут загружены.", "Port": "Порт", + "Ports": "", "Positive attitude": "Позитивный настрой", "Prefer not to say": "Предпочитаю не говорить", "Prefix ID": "ID префикса", @@ -1571,6 +1578,7 @@ "Response splitting": "Разделение ответов", "Response Watermark": "Водяной знак ответа", "Responses": "", + "Restart": "", "Result": "Результат", "RESULT": "Результат", "Retrieval": "Поиск", @@ -1585,6 +1593,7 @@ "Role": "Роль", "RTL": "RTL", "Run": "Запустить", + "Run All": "", "Running": "Выполняется", "Running...": "Выполняется...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1775,6 +1784,7 @@ "Start a new conversation": "", "Start of the channel": "Начало канала", "Start Tag": "Начальный тег", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2119,6 +2129,8 @@ "You're now logged in.": "Вы вошли в систему.", "Your Account": "Ваш аккаунт", "Your account status is currently pending activation.": "В настоящее время ваша учетная запись ожидает активации.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Весь ваш взнос будет направлен непосредственно разработчику плагина; Open WebUI не взимает никаких процентов. Однако выбранная платформа финансирования может иметь свои собственные сборы.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/sk-SK/translation.json b/src/lib/i18n/locales/sk-SK/translation.json index 14cce2feae..631818be15 100644 --- a/src/lib/i18n/locales/sk-SK/translation.json +++ b/src/lib/i18n/locales/sk-SK/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "Chat", + "Chat archived.": "", "Chat Background Image": "Obrázok pozadia chatu", "Chat Bubble UI": "Používateľské rozhranie bublín chatu (Chat Bubble UI)", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "Nepodarilo sa pridať súbor.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Nepodarilo sa prečítať obsah schránky", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "Nebola nájdená žiadny obsah HTML, CSS ani JavaScript.", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "Neboli nájdené žiadne znalostné databázy.", "No knowledge found": "Neboli nájdené žiadne znalosti", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "Neboli nájdené žiadne výsledky", "No results found": "Neboli nájdené žiadne výsledky", "No search query generated": "Nebola vygenerovaná žiadna vyhľadávacia otázka.", + "No servers detected": "", "No skills found": "", "No source available": "Nie je dostupný žiadny zdroj.", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "Pozitívny prístup", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "Rozdelenie odpovede", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "Výsledok", "RESULT": "Výsledok", "Retrieval": "", @@ -1585,6 +1593,7 @@ "Role": "Funkcia", "RTL": "RTL", "Run": "Spustiť", + "Run All": "", "Running": "Spúšťanie", "Running...": "Spúšťanie...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1775,6 +1784,7 @@ "Start a new conversation": "", "Start of the channel": "Začiatok kanála", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2119,6 +2129,8 @@ "You're now logged in.": "Teraz ste prihlásený(-á).", "Your Account": "Váš účet", "Your account status is currently pending activation.": "Stav vášho účtu je aktuálne čakajúci na aktiváciu.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Celý váš príspevok pôjde priamo vývojárovi pluginu; Open WebUI si neberie žiadne percento. Zvolená platforma na financovanie však môže mať vlastné poplatky.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/sr-RS/translation.json b/src/lib/i18n/locales/sr-RS/translation.json index 39c9d05530..1a0a7bd106 100644 --- a/src/lib/i18n/locales/sr-RS/translation.json +++ b/src/lib/i18n/locales/sr-RS/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "Откриј нове границе", "Chat": "Ћаскање", + "Chat archived.": "", "Chat Background Image": "Позадинска слика ћаскања", "Chat Bubble UI": "Прочеље балона ћаскања", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Неуспешно читање садржаја оставе", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "Нема резултата", "No results found": "Нема резултата", "No search query generated": "Није генерисан упит за претрагу", + "No servers detected": "", "No skills found": "", "No source available": "Нема доступног извора", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "Позитиван став", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "Исход", "RESULT": "Исход", "Retrieval": "", @@ -1584,6 +1592,7 @@ "Role": "Улога", "RTL": "ДНЛ", "Run": "Покрени", + "Run All": "", "Running": "Покрећем", "Running...": "Покрећем...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1774,6 +1783,7 @@ "Start a new conversation": "", "Start of the channel": "Почетак канала", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2118,6 +2128,8 @@ "You're now logged in.": "Сада сте пријављени.", "Your Account": "", "Your account status is currently pending activation.": "", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/sv-SE/translation.json b/src/lib/i18n/locales/sv-SE/translation.json index 95c7e54535..1459d67bf8 100644 --- a/src/lib/i18n/locales/sv-SE/translation.json +++ b/src/lib/i18n/locales/sv-SE/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Teckengräns för inmatning av automatisk komplettering", "Chart new frontiers": "Utforska nya gränser", "Chat": "Chatt", + "Chat archived.": "", "Chat Background Image": "Bakgrundsbild för chatt", "Chat Bubble UI": "UI för Chatbubblor", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "Misslyckades med att lägga till fil.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "Misslyckades med att ansluta till {{URL}} OpenAPI-verktygsserver", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "Misslyckades med att läsa in filinnehåll.", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Misslyckades med att läsa urklippsinnehåll", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "Inget HTML-, CSS- eller JavaScript-innehåll hittades.", "No inference engine with management support found": "Ingen inferensmotor med stöd för hantering hittades", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Ingen kunskapsbas hittades", "No memories to clear": "Inga minnen att rensa", @@ -1320,6 +1325,7 @@ "No results": "Inga resultat hittades", "No results found": "Inga resultat hittades", "No search query generated": "Ingen sökfråga genererad", + "No servers detected": "", "No skills found": "", "No source available": "Ingen tillgänglig källa", "No sources found": "Inga källor hittades", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "Vänta tills alla filer har laddats upp.", "Port": "Port", + "Ports": "", "Positive attitude": "Positivt inställning", "Prefer not to say": "Föredrar att inte att säga", "Prefix ID": "Prefix-ID", @@ -1571,6 +1578,7 @@ "Response splitting": "Svarsdelning", "Response Watermark": "Svarsvattenstämpel", "Responses": "", + "Restart": "", "Result": "Resultat", "RESULT": "Resultat", "Retrieval": "Hämtning", @@ -1583,6 +1591,7 @@ "Role": "Roll", "RTL": "RTL", "Run": "Kör", + "Run All": "", "Running": "Kör", "Running...": "Kör...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "Starta en ny konversation", "Start of the channel": "Början av kanalen", "Start Tag": "Starta en tagg", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "Du är nu inloggad.", "Your Account": "Ditt konto", "Your account status is currently pending activation.": "Ditt konto väntar på att bli aktiverat", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Hela ditt bidrag går direkt till pluginutvecklaren; Open WebUI tar ingen procentandel. Däremot kan den valda finansieringsplattformen ha egna avgifter.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/th-TH/translation.json b/src/lib/i18n/locales/th-TH/translation.json index 6cae379db6..4092f0e7fd 100644 --- a/src/lib/i18n/locales/th-TH/translation.json +++ b/src/lib/i18n/locales/th-TH/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "ขีดจำกัดจำนวนอักขระสำหรับอินพุตการสร้างคำอัตโนมัติ", "Chart new frontiers": "สำรวจพรมแดนใหม่", "Chat": "แชท", + "Chat archived.": "", "Chat Background Image": "ภาพพื้นหลังแชท", "Chat Bubble UI": "ส่วนติดต่อผู้ใช้แบบฟองแชท", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "เอฟเฟ็กต์เฟดสำหรับข้อความสตรีมมิ่ง", "Failed to add file.": "ไม่สามารถเพิ่มไฟล์ได้", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "เชื่อมต่อกับเซิร์ฟเวอร์เครื่องมือ OpenAPI ที่ {{URL}} ไม่สำเร็จ", @@ -836,9 +838,11 @@ "Failed to generate title": "สร้างชื่อไม่สำเร็จ", "Failed to import models": "นำเข้าโมเดลไม่สำเร็จ", "Failed to load chat preview": "ไม่สามารถโหลดตัวอย่างแชทได้", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "โหลดเนื้อหาไฟล์ไม่สำเร็จ", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "ย้ายแชทไม่สำเร็จ", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "อ่านเนื้อหาคลิปบอร์ดไม่สำเร็จ", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "ไม่พบเนื้อหา HTML, CSS หรือ JavaScript", "No inference engine with management support found": "ไม่พบเอนจินอนุมานที่รองรับการจัดการ", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "ไม่พบฐานความรู้", "No memories to clear": "ไม่มีความจำให้ลบ", @@ -1320,6 +1325,7 @@ "No results": "ไม่มีผลลัพธ์", "No results found": "ไม่มีผลลัพธ์", "No search query generated": "ไม่มีการสร้างคำค้นหา", + "No servers detected": "", "No skills found": "", "No source available": "ไม่มีแหล่งที่มา", "No sources found": "ไม่พบแหล่งข้อมูล", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "โปรดรอจนกว่าไฟล์ทั้งหมดจะอัปโหลดเสร็จสิ้น", "Port": "พอร์ต", + "Ports": "", "Positive attitude": "ทัศนคติเชิงบวก", "Prefer not to say": "ไม่ต้องการระบุ", "Prefix ID": "รหัสคำนำหน้า", @@ -1571,6 +1578,7 @@ "Response splitting": "การแยกข้อความตอบกลับ", "Response Watermark": "ลายน้ำของคำตอบ", "Responses": "", + "Restart": "", "Result": "ผลลัพธ์", "RESULT": "ผลลัพธ์", "Retrieval": "การดึงข้อมูล", @@ -1582,6 +1590,7 @@ "Role": "บทบาท", "RTL": "ขวาไปซ้าย", "Run": "เรียกใช้", + "Run All": "", "Running": "กำลังทำงาน", "Running...": "กำลังทำงาน...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1772,6 +1781,7 @@ "Start a new conversation": "เริ่มการสนทนาใหม่", "Start of the channel": "จุดเริ่มต้นของช่อง", "Start Tag": "แท็กเริ่มต้น", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2116,6 +2126,8 @@ "You're now logged in.": "คุณเข้าสู่ระบบแล้ว", "Your Account": "บัญชีของคุณ", "Your account status is currently pending activation.": "สถานะบัญชีของคุณกำลังรอการเปิดใช้งาน", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "การสนับสนุนทั้งหมดของคุณจะถูกส่งไปยังนักพัฒนาปลั๊กอินโดยตรง Open WebUI จะไม่หักส่วนแบ่งใดๆ อย่างไรก็ตาม แพลตฟอร์มการระดมทุนที่คุณเลือกอาจมีการเก็บค่าธรรมเนียมในส่วนของตนเอง", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/tk-TM/translation.json b/src/lib/i18n/locales/tk-TM/translation.json index e5b18b2d33..b8d605fa9c 100644 --- a/src/lib/i18n/locales/tk-TM/translation.json +++ b/src/lib/i18n/locales/tk-TM/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "Çat", + "Chat archived.": "", "Chat Background Image": "", "Chat Bubble UI": "Çat Bubble UI", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "Netije ýok", "No results found": "", "No search query generated": "", + "No servers detected": "", "No skills found": "", "No source available": "", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "", "RESULT": "NETIJE", "Retrieval": "", @@ -1583,6 +1591,7 @@ "Role": "Roli", "RTL": "", "Run": "", + "Run All": "", "Running": "", "Running...": "Işleýär...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "Kanal başy", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "", "Your Account": "", "Your account status is currently pending activation.": "", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/tr-TR/translation.json b/src/lib/i18n/locales/tr-TR/translation.json index fe8d75d0d9..9dddccb9cd 100644 --- a/src/lib/i18n/locales/tr-TR/translation.json +++ b/src/lib/i18n/locales/tr-TR/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Otomatik tamamlama üretimi girişi için karakter sınırı", "Chart new frontiers": "", "Chat": "Sohbet", + "Chat archived.": "", "Chat Background Image": "Sohbet Arka Plan Resmi", "Chat Bubble UI": "Sohbet Balonu Arayüzü", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "Dosya eklenemedi.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Pano içeriği okunamadı", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "HTML, CSS veya JavaScript içeriği bulunamadı.", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Bilgi bulunamadı", "No memories to clear": "Temizlenecek bellek yok", @@ -1320,6 +1325,7 @@ "No results": "Sonuç bulunamadı", "No results found": "Sonuç bulunamadı", "No search query generated": "Hiç arama sorgusu oluşturulmadı", + "No servers detected": "", "No skills found": "", "No source available": "Kaynak mevcut değil", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "Port", + "Ports": "", "Positive attitude": "Olumlu yaklaşım", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "Yanıt bölme", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "Sonuç", "RESULT": "Sonuç", "Retrieval": "", @@ -1583,6 +1591,7 @@ "Role": "Rol", "RTL": "Sağdan Sola", "Run": "Çalıştır", + "Run All": "", "Running": "Çalışıyor", "Running...": "Çalışıyor...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "Kanalın başlangıcı", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "Şimdi giriş yaptınız.", "Your Account": "Hesabınız", "Your account status is currently pending activation.": "Hesap durumunuz şu anda etkinleştirilmeyi bekliyor.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Tüm katkınız doğrudan eklenti geliştiricisine gidecektir; Open WebUI herhangi bir yüzde almaz. Ancak seçilen finansman platformunun kendi ücretleri olabilir.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/ug-CN/translation.json b/src/lib/i18n/locales/ug-CN/translation.json index 9f2850956c..56dccac739 100644 --- a/src/lib/i18n/locales/ug-CN/translation.json +++ b/src/lib/i18n/locales/ug-CN/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "ئاپتوماتىك تولدۇرۇش كىرگۈزۈشنىڭ ھەرپ چەكى", "Chart new frontiers": "يېڭى چېگرىلارنى پىلانلاش", "Chat": "سۆھبەت", + "Chat archived.": "", "Chat Background Image": "سۆھبەت ئارقا كۆرۈنۈش رەسىمى", "Chat Bubble UI": "سۆھبەت كۆپۈك كۆرۈنمە يۈزى ", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "ھۆججەت قوشۇش مەغلۇپ بولدى.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "{{URL}} OpenAPI قورال مۇلازىمېتىرىغا ئۇلىنىش مەغلۇپ بولدى", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "ھۆججەت مەزمۇنى يۈكلەش مەغلۇپ بولدى.", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "چاپلاش تاختىسى مەزمۇنىنى ئوقۇش مەغلۇپ بولدى", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "HTML، CSS ياكى JavaScript مەزمۇنى تېپىلمىدى.", "No inference engine with management support found": "باشقۇرۇشنى قوللايدىغان يەكۈن ماتورى تېپىلمىدى", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "بىلىم تېپىلمىدى", "No memories to clear": "تازلاشقا ئەسلەتمە يوق", @@ -1320,6 +1325,7 @@ "No results": "نەتىجە تېپىلمىدى", "No results found": "نەتىجە تېپىلمىدى", "No search query generated": "ئىزدەش سۇئالى ھاسىل قىلىنمىدى", + "No servers detected": "", "No skills found": "", "No source available": "مەنبە يوق", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "ئېغىز", + "Ports": "", "Positive attitude": "ئىجابىي پوزىتسىيە", "Prefer not to say": "", "Prefix ID": "Prefix ID", @@ -1571,6 +1578,7 @@ "Response splitting": "ئىنكاسنى بۆلۈش", "Response Watermark": "ئىنكاس سۇ بەلگىسى", "Responses": "", + "Restart": "", "Result": "نەتىجە", "RESULT": "نەتىجە", "Retrieval": "قايتۇرۇش", @@ -1583,6 +1591,7 @@ "Role": "رول", "RTL": "RTL (ئوڭدىن سولغا)", "Run": "ئىجرا قىلىش", + "Run All": "", "Running": "ئىجرا قىلىنىۋاتىدۇ", "Running...": "ئىجرا قىلىنىۋاتىدۇ...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "قانالنىڭ باشلانغىنى", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "سىز كىرىپ بولدىڭىز.", "Your Account": "", "Your account status is currently pending activation.": "ھېساباتىڭىزنىڭ ھازىرقى ھالىتى ئاكتىپلىنىشنى كۈتۈۋاتىدۇ.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "تۆلەم پۇلىڭىز بىۋاسىتە قىستۇرما تەرەققىياتچىسىغا بېرىلىدۇ؛ Open WebUI ھېچقانداق پىرسېنت ئالمايدۇ. بىراق تاللانغان مالىيە پلاتفورمىسىنىڭ ئۆزىنىڭ ھەققى بولۇشى مۇمكىن.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/uk-UA/translation.json b/src/lib/i18n/locales/uk-UA/translation.json index a8d81194d8..4d6f5c2060 100644 --- a/src/lib/i18n/locales/uk-UA/translation.json +++ b/src/lib/i18n/locales/uk-UA/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Ліміт символів для введення при генерації автозаповнення", "Chart new frontiers": "Відкривати нові горизонти", "Chat": "Чат", + "Chat archived.": "", "Chat Background Image": "Фонове зображення чату", "Chat Bubble UI": "Чат у вигляді бульбашок", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "Не вдалося додати файл.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "Не вдалося підключитися до серверу інструментів OpenAPI {{URL}}", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Не вдалося прочитати вміст буфера обміну", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "HTML, CSS або JavaScript контент не знайдено.", "No inference engine with management support found": "Не знайдено двигуна висновків з підтримкою керування", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Знання не знайдено.", "No memories to clear": "Немає спогадів для очищення", @@ -1320,6 +1325,7 @@ "No results": "Не знайдено жодного результату", "No results found": "Не знайдено жодного результату", "No search query generated": "Пошуковий запит не сформовано", + "No servers detected": "", "No skills found": "", "No source available": "Джерело не доступне", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "Порт", + "Ports": "", "Positive attitude": "Позитивне ставлення", "Prefer not to say": "", "Prefix ID": "ID префікса", @@ -1571,6 +1578,7 @@ "Response splitting": "Розбиття відповіді", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "Результат", "RESULT": "Результат", "Retrieval": "Пошук", @@ -1585,6 +1593,7 @@ "Role": "Роль", "RTL": "RTL", "Run": "Запустити", + "Run All": "", "Running": "Виконується", "Running...": "Виконується...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1775,6 +1784,7 @@ "Start a new conversation": "", "Start of the channel": "Початок каналу", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2119,6 +2129,8 @@ "You're now logged in.": "Ви увійшли в систему.", "Your Account": "", "Your account status is currently pending activation.": "Статус вашого облікового запису наразі очікує на активацію.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Весь ваш внесок піде безпосередньо розробнику плагіна; Open WebUI не бере жодних відсотків. Однак, обрана платформа фінансування може мати свої власні збори.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/ur-PK/translation.json b/src/lib/i18n/locales/ur-PK/translation.json index b6c34c9ef4..679bfa601b 100644 --- a/src/lib/i18n/locales/ur-PK/translation.json +++ b/src/lib/i18n/locales/ur-PK/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "", "Chart new frontiers": "", "Chat": "چیٹ", + "Chat archived.": "", "Chat Background Image": "چیٹ پس منظر کی تصویر", "Chat Bubble UI": "چیٹ بلبل انٹرفیس", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "فائل شامل کرنے میں ناکام", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "کلپ بورڈ مواد کو پڑھنے میں ناکام", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "کوئی HTML، CSS، یا جاوا اسکرپٹ مواد نہیں ملا", "No inference engine with management support found": "", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "کوئی معلومات نہیں ملی", "No memories to clear": "", @@ -1320,6 +1325,7 @@ "No results": "کوئی نتائج نہیں ملے", "No results found": "کوئی نتائج نہیں ملے", "No search query generated": "کوئی تلاش کی درخواست نہیں بنائی گئی", + "No servers detected": "", "No skills found": "", "No source available": "ماخذ دستیاب نہیں ہے", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "", + "Ports": "", "Positive attitude": "مثبت رویہ", "Prefer not to say": "", "Prefix ID": "", @@ -1571,6 +1578,7 @@ "Response splitting": "جواب کو تقسیم کرنا", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "نتیجہ", "RESULT": "نتیجہ", "Retrieval": "", @@ -1583,6 +1591,7 @@ "Role": "کردار", "RTL": "آر ٹی ایل", "Run": "چلائیں", + "Run All": "", "Running": "چل رہا ہے", "Running...": "چل رہا ہے...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "چینل کی شروعات", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "آپ اب لاگ ان ہو چکے ہیں", "Your Account": "", "Your account status is currently pending activation.": "آپ کے اکاؤنٹ کی حالت فی الحال فعال ہونے کے منتظر ہے", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "آپ کی پوری شراکت براہ راست پلگ ان ڈیولپر کو جائے گی؛ اوپن ویب یو آئی کوئی فیصد نہیں لیتی تاہم، منتخب کردہ فنڈنگ پلیٹ فارم کی اپنی فیس ہو سکتی ہیں", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/uz-Cyrl-UZ/translation.json b/src/lib/i18n/locales/uz-Cyrl-UZ/translation.json index a686a8bdc3..f35c516c93 100644 --- a/src/lib/i18n/locales/uz-Cyrl-UZ/translation.json +++ b/src/lib/i18n/locales/uz-Cyrl-UZ/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Автоматик тўлдиришни яратиш учун белгилар чегараси", "Chart new frontiers": "Янги чегараларни белгиланг", "Chat": "Чат", + "Chat archived.": "", "Chat Background Image": "Чат фон расми", "Chat Bubble UI": "Сhat Bubble Интерфейси", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "Файл қўшиб бўлмади.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "{{УРЛ}} ОпенАПИ асбоб серверига уланиб бўлмади", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "Файл таркибини юклаб бўлмади.", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Буфер таркибини ўқиб бўлмади", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "HTML, CСС ёки ЖаваСcрипт контенти топилмади.", "No inference engine with management support found": "Бошқарув ёрдами билан хулоса чиқариш механизми топилмади", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Ҳеч қандай билим топилмади", "No memories to clear": "Тозалаш учун хотиралар йўқ", @@ -1320,6 +1325,7 @@ "No results": "Ҳеч қандай натижа топилмади", "No results found": "Ҳеч қандай натижа топилмади", "No search query generated": "Ҳеч қандай қидирув сўрови яратилмади", + "No servers detected": "", "No skills found": "", "No source available": "Манба мавжуд эмас", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "Порт", + "Ports": "", "Positive attitude": "Ижобий муносабат", "Prefer not to say": "", "Prefix ID": "Префикс идентификатори", @@ -1571,6 +1578,7 @@ "Response splitting": "Жавобни ажратиш", "Response Watermark": "Жавоб сув белгиси", "Responses": "", + "Restart": "", "Result": "Натижа", "RESULT": "Натижа", "Retrieval": "Қидирув", @@ -1583,6 +1591,7 @@ "Role": "Рол", "RTL": "RTL", "Run": "Ишга тушириш", + "Run All": "", "Running": "Ишлаётган", "Running...": "Ишлаётган...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "Канал боши", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "Сиз энди тизимга кирдингиз.", "Your Account": "", "Your account status is currently pending activation.": "Ҳисобингиз ҳолати ҳозирда фаоллаштиришни кутмоқда.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Сизнинг барча ҳиссангиз тўғридан-тўғри плагин ишлаб чиқарувчисига ўтади; Open WebUI ҳеч қандай фоизни олмайди. Бироқ, танланган молиялаштириш платформаси ўз тўловларига эга бўлиши мумкин.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/uz-Latn-Uz/translation.json b/src/lib/i18n/locales/uz-Latn-Uz/translation.json index 033271e9a6..2af10b56d4 100644 --- a/src/lib/i18n/locales/uz-Latn-Uz/translation.json +++ b/src/lib/i18n/locales/uz-Latn-Uz/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Avtomatik toʻldirishni yaratish uchun belgilar chegarasi", "Chart new frontiers": "Yangi chegaralarni belgilang", "Chat": "Chat", + "Chat archived.": "", "Chat Background Image": "Chat fon rasmi", "Chat Bubble UI": "Chat Bubble UI", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "Fayl qo‘shib bo‘lmadi.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "{{URL}} OpenAPI asbob serveriga ulanib boʻlmadi", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "Fayl tarkibini yuklab bo‘lmadi.", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Bufer tarkibini o‘qib bo‘lmadi", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "HTML, CSS yoki JavaScript kontenti topilmadi.", "No inference engine with management support found": "Boshqaruv yordami bilan xulosa chiqarish mexanizmi topilmadi", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Hech qanday bilim topilmadi", "No memories to clear": "Tozalash uchun xotiralar yo'q", @@ -1320,6 +1325,7 @@ "No results": "Hech qanday natija topilmadi", "No results found": "Hech qanday natija topilmadi", "No search query generated": "Hech qanday qidiruv soʻrovi yaratilmadi", + "No servers detected": "", "No skills found": "", "No source available": "Manba mavjud emas", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "Port", + "Ports": "", "Positive attitude": "Ijobiy munosabat", "Prefer not to say": "", "Prefix ID": "Prefiks identifikatori", @@ -1571,6 +1578,7 @@ "Response splitting": "Javobni ajratish", "Response Watermark": "Javob suv belgisi", "Responses": "", + "Restart": "", "Result": "Natija", "RESULT": "Natija", "Retrieval": "Qidiruv", @@ -1583,6 +1591,7 @@ "Role": "Rol", "RTL": "RTL", "Run": "Yugurish", + "Run All": "", "Running": "Yugurish", "Running...": "Yugurish...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1773,6 +1782,7 @@ "Start a new conversation": "", "Start of the channel": "Kanal boshlanishi", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2117,6 +2127,8 @@ "You're now logged in.": "Siz endi tizimga kirdingiz.", "Your Account": "", "Your account status is currently pending activation.": "Hisobingiz holati hozirda faollashtirishni kutmoqda.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Sizning barcha hissangiz to'g'ridan-to'g'ri plagin ishlab chiqaruvchisiga o'tadi; Open WebUI hech qanday foizni olmaydi. Biroq, tanlangan moliyalashtirish platformasi o'z to'lovlariga ega bo'lishi mumkin.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/vi-VN/translation.json b/src/lib/i18n/locales/vi-VN/translation.json index 02475c3aa3..637321ef3a 100644 --- a/src/lib/i18n/locales/vi-VN/translation.json +++ b/src/lib/i18n/locales/vi-VN/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "Giới hạn ký tự cho đầu vào tạo tự động hoàn thành", "Chart new frontiers": "Vẽ nên những giới hạn mới", "Chat": "Trò chuyện", + "Chat archived.": "", "Chat Background Image": "Hình nền trò chuyện", "Chat Bubble UI": "Bảng chat", "Chat Completions": "", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "", "Failed to add file.": "Không thể thêm tệp.", "Failed to add members": "", + "Failed to archive chat.": "", "Failed to attach file": "", "Failed to clear status": "", "Failed to connect to {{URL}} OpenAPI tool server": "Không thể kết nối đến máy chủ công cụ OpenAPI {{URL}}", @@ -836,9 +838,11 @@ "Failed to generate title": "", "Failed to import models": "", "Failed to load chat preview": "", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "", "Failed to load file content.": "", "Failed to load Interface settings": "", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Không thể đọc nội dung clipboard", @@ -1305,6 +1309,7 @@ "No history available": "", "No HTML, CSS, or JavaScript content found.": "Không tìm thấy nội dung HTML, CSS hoặc JavaScript.", "No inference engine with management support found": "Không tìm thấy engine suy luận nào có hỗ trợ quản lý", + "No kernel": "", "No knowledge bases found.": "", "No knowledge found": "Không tìm thấy kiến thức", "No memories to clear": "Không có bộ nhớ nào để xóa", @@ -1320,6 +1325,7 @@ "No results": "Không tìm thấy kết quả", "No results found": "Không tìm thấy kết quả", "No search query generated": "Không có truy vấn tìm kiếm nào được tạo ra", + "No servers detected": "", "No skills found": "", "No source available": "Không có nguồn", "No sources found": "", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "", "Please wait until all files are uploaded.": "", "Port": "Cổng", + "Ports": "", "Positive attitude": "Thái độ tích cực", "Prefer not to say": "", "Prefix ID": "Tiền tố ID", @@ -1571,6 +1578,7 @@ "Response splitting": "Phân tách phản hồi", "Response Watermark": "", "Responses": "", + "Restart": "", "Result": "Kết quả", "RESULT": "Kết quả", "Retrieval": "Truy xuất", @@ -1582,6 +1590,7 @@ "Role": "Vai trò", "RTL": "RTL", "Run": "Thực hiện", + "Run All": "", "Running": "Đang chạy", "Running...": "Đang chạy...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", @@ -1772,6 +1781,7 @@ "Start a new conversation": "", "Start of the channel": "Đầu kênh", "Start Tag": "", + "Starting kernel...": "", "Status": "", "Status cleared successfully": "", "Status updated successfully": "", @@ -2116,6 +2126,8 @@ "You're now logged in.": "Bạn đã đăng nhập.", "Your Account": "", "Your account status is currently pending activation.": "Tài khoản của bạn hiện đang ở trạng thái chờ kích hoạt.", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Toàn bộ đóng góp của bạn sẽ được chuyển trực tiếp đến nhà phát triển plugin; Open WebUI không lấy bất kỳ tỷ lệ phần trăm nào. Tuy nhiên, nền tảng được chọn tài trợ có thể có phí riêng.", "Your message text or inputs": "", "Your usage stats have been successfully synced.": "", diff --git a/src/lib/i18n/locales/zh-CN/translation.json b/src/lib/i18n/locales/zh-CN/translation.json index 4c1ec974bf..9fac1d692e 100644 --- a/src/lib/i18n/locales/zh-CN/translation.json +++ b/src/lib/i18n/locales/zh-CN/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "输入框内容自动补全输入的字符限制", "Chart new frontiers": "开辟前沿", "Chat": "对话", + "Chat archived.": "", "Chat Background Image": "对话背景图片", "Chat Bubble UI": "以聊天气泡的形式显示对话内容", "Chat Completions": "Chat Completions", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "流式输出内容时启用动态渐显效果", "Failed to add file.": "添加文件失败", "Failed to add members": "添加成员失败", + "Failed to archive chat.": "", "Failed to attach file": "文件上传失败", "Failed to clear status": "清除状态失败", "Failed to connect to {{URL}} OpenAPI tool server": "连接到 {{URL}} OpenAPI 工具服务器失败", @@ -836,9 +838,11 @@ "Failed to generate title": "生成标题失败", "Failed to import models": "导入模型配置失败", "Failed to load chat preview": "对话预览加载失败", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "加载 Excel/CSV 文件失败,请尝试直接下载文件。", "Failed to load file content.": "文件内容加载失败", "Failed to load Interface settings": "“界面设置”数据加载失败", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "移动对话失败", "Failed to process URL: {{url}}": "处理链接失败: {{url}}", "Failed to read clipboard contents": "读取剪贴板内容失败", @@ -1305,6 +1309,7 @@ "No history available": "暂无历史记录", "No HTML, CSS, or JavaScript content found.": "未找到 HTML、CSS 或 JavaScript 内容。", "No inference engine with management support found": "未找到支持管理的推理引擎", + "No kernel": "", "No knowledge bases found.": "未找到知识库", "No knowledge found": "未找到知识", "No memories to clear": "记忆为空,无须清理", @@ -1320,6 +1325,7 @@ "No results": "未找到结果", "No results found": "未找到结果", "No search query generated": "未生成搜索查询", + "No servers detected": "", "No skills found": "没有找到技能", "No source available": "没有可用引用来源", "No sources found": "未找到任何引用来源", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "请至少选择一个用户以创建私聊频道。", "Please wait until all files are uploaded.": "请等待所有文件上传完毕。", "Port": "端口", + "Ports": "", "Positive attitude": "态度积极", "Prefer not to say": "暂不透露", "Prefix ID": "模型 ID 前缀", @@ -1571,6 +1578,7 @@ "Response splitting": "拆分回答", "Response Watermark": "复制时添加水印", "Responses": "Responses", + "Restart": "", "Result": "结果", "RESULT": "结果", "Retrieval": "检索", @@ -1582,6 +1590,7 @@ "Role": "角色", "RTL": "从右至左", "Run": "运行", + "Run All": "", "Running": "运行中", "Running...": "运行中...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "并行运行嵌入任务以加快处理速度。如果遇到限速问题,请关闭此选项。", @@ -1772,6 +1781,7 @@ "Start a new conversation": "开始新对话", "Start of the channel": "频道起点", "Start Tag": "起始标签", + "Starting kernel...": "", "Status": "状态", "Status cleared successfully": "状态已清除", "Status updated successfully": "状态已更新", @@ -2116,6 +2126,8 @@ "You're now logged in.": "已登录。", "Your Account": "您的账号", "Your account status is currently pending activation.": "您的账号当前状态为待激活", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "您的全部捐款将直接给到插件开发者,Open WebUI 不会收取任何分成。但众筹平台可能会有服务费。", "Your message text or inputs": "您的消息文本或输入", "Your usage stats have been successfully synced.": "已成功同步您的使用统计数据。", diff --git a/src/lib/i18n/locales/zh-TW/translation.json b/src/lib/i18n/locales/zh-TW/translation.json index 0fb0346019..996b4d48da 100644 --- a/src/lib/i18n/locales/zh-TW/translation.json +++ b/src/lib/i18n/locales/zh-TW/translation.json @@ -282,6 +282,7 @@ "Character limit for autocomplete generation input": "自動完成產生輸入的字元限制", "Chart new frontiers": "探索新領域", "Chat": "對話", + "Chat archived.": "", "Chat Background Image": "對話背景圖片", "Chat Bubble UI": "對話氣泡介面", "Chat Completions": "對話續寫", @@ -822,6 +823,7 @@ "Fade Effect for Streaming Text": "串流文字淡入效果", "Failed to add file.": "新增檔案失敗。", "Failed to add members": "新增成員失敗", + "Failed to archive chat.": "", "Failed to attach file": "檔案上傳失敗", "Failed to clear status": "清除狀態失敗", "Failed to connect to {{URL}} OpenAPI tool server": "無法連線至 {{URL}} OpenAPI 工具伺服器", @@ -836,9 +838,11 @@ "Failed to generate title": "產生標題失敗", "Failed to import models": "匯入模型失敗", "Failed to load chat preview": "對話預覽載入失敗", + "Failed to load DOCX file. Please try downloading it instead.": "", "Failed to load Excel/CSV file. Please try downloading it instead.": "無法載入 Excel/CSV 檔案。請嘗試直接下載檔案。", "Failed to load file content.": "載入檔案內容失敗。", "Failed to load Interface settings": "「介面設定」資料載入失敗", + "Failed to load PPTX file. Please try downloading it instead.": "", "Failed to move chat": "移動對話失敗", "Failed to process URL: {{url}}": "處理連結失敗:{{url}}", "Failed to read clipboard contents": "讀取剪貼簿內容失敗", @@ -1305,6 +1309,7 @@ "No history available": "暫無歷史紀錄", "No HTML, CSS, or JavaScript content found.": "未找到 HTML、CSS 或 JavaScript 內容。", "No inference engine with management support found": "未找到支援管理功能的推理引擎", + "No kernel": "", "No knowledge bases found.": "未找到知識庫", "No knowledge found": "未找到知識", "No memories to clear": "沒有記憶可清除", @@ -1320,6 +1325,7 @@ "No results": "沒有結果", "No results found": "未找到任何結果", "No search query generated": "未產生搜尋查詢", + "No servers detected": "", "No skills found": "找不到任何技能", "No source available": "無可用來源", "No sources found": "未找到任何來源", @@ -1475,6 +1481,7 @@ "Please select at least one user for Direct Message channel.": "請至少選擇一位使用者以建立直接訊息頻道。", "Please wait until all files are uploaded.": "請等待所有檔案上傳完畢。", "Port": "連接埠", + "Ports": "", "Positive attitude": "積極的態度", "Prefer not to say": "不想透露", "Prefix ID": "前置 ID", @@ -1571,6 +1578,7 @@ "Response splitting": "回應分割", "Response Watermark": "回應浮水印", "Responses": "回答", + "Restart": "", "Result": "結果", "RESULT": "結果", "Retrieval": "檢索", @@ -1582,6 +1590,7 @@ "Role": "角色", "RTL": "從右到左", "Run": "執行", + "Run All": "", "Running": "正在執行", "Running...": "正在執行...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "同時執行嵌入任務以加快處理速度。如果遇到速率限制問題,請關閉此功能。", @@ -1772,6 +1781,7 @@ "Start a new conversation": "開始新對話", "Start of the channel": "頻道起點", "Start Tag": "起始標籤", + "Starting kernel...": "", "Status": "狀態", "Status cleared successfully": "狀態已清除", "Status updated successfully": "狀態已更新", @@ -2116,6 +2126,8 @@ "You're now logged in.": "您已登入。", "Your Account": "您的帳號", "Your account status is currently pending activation.": "您的帳號目前正在等待啟用。", + "Your browser does not support the audio tag.": "", + "Your browser does not support the video tag.": "", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "您的所有貢獻將會直接交給外掛開發者;Open WebUI 不會收取任何抽成。然而,所選擇的贊助平臺可能有其自身的費用。", "Your message text or inputs": "您的訊息文字或輸入", "Your usage stats have been successfully synced.": "已成功同步您的使用統計資料。", diff --git a/src/lib/utils/codeHighlight.ts b/src/lib/utils/codeHighlight.ts index 0e33dd3872..23861bc77b 100644 --- a/src/lib/utils/codeHighlight.ts +++ b/src/lib/utils/codeHighlight.ts @@ -186,4 +186,3 @@ export async function highlightCode(code: string, filePath: string): Promise { - let s = ''; - let n = i; - while (n >= 0) { - s = String.fromCharCode(65 + (n % 26)) + s; - n = Math.floor(n / 26) - 1; - } - return s; + let s = ''; + let n = i; + while (n >= 0) { + s = String.fromCharCode(65 + (n % 26)) + s; + n = Math.floor(n / 26) - 1; + } + return s; }; /** Escape HTML entities */ const esc = (v: unknown): string => { - if (v === null || v === undefined || v === '') return ' '; - return String(v).replace(/&/g, '&').replace(//g, '>'); + if (v === null || v === undefined || v === '') return ' '; + return String(v).replace(/&/g, '&').replace(//g, '>'); }; export interface ExcelTableResult { - html: string; - rowCount: number; - colCount: number; + html: string; + rowCount: number; + colCount: number; } /** @@ -38,49 +38,51 @@ export interface ExcelTableResult { * Uses sheet_to_json with header:1 for a raw 2D array. */ export async function excelToTable(worksheet: WorkSheet): Promise { - const XLSX = await import('xlsx'); - const rows: unknown[][] = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: '' }); + const XLSX = await import('xlsx'); + const rows: unknown[][] = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: '' }); - if (rows.length === 0) { - return { html: '
#
 
', rowCount: 0, colCount: 0 }; - } + if (rows.length === 0) { + return { + html: '
 
', + rowCount: 0, + colCount: 0 + }; + } - // Determine column count from the widest row - const colCount = rows.reduce((max, row) => Math.max(max, row.length), 0); - const rowCount = rows.length; + // Determine column count from the widest row + const colCount = rows.reduce((max, row) => Math.max(max, row.length), 0); + const rowCount = rows.length; - const parts: string[] = []; - parts.push(''); + const parts: string[] = []; + parts.push('
'); - // Column letter header row - parts.push(''); - parts.push(''); // corner cell - for (let c = 0; c < colCount; c++) { - parts.push(``); - } - parts.push(''); + // Column letter header row + parts.push(''); + parts.push(''); // corner cell + for (let c = 0; c < colCount; c++) { + parts.push(``); + } + parts.push(''); - // Data rows - parts.push(''); - for (let r = 0; r < rowCount; r++) { - const row = rows[r]; - parts.push(''); - parts.push(``); - for (let c = 0; c < colCount; c++) { - const val = c < row.length ? row[c] : ''; - const isNum = typeof val === 'number'; - parts.push( - `${esc(val)}` - ); - } - parts.push(''); - } - parts.push('
${colLetter(c)}
${colLetter(c)}
${r + 1}
'); + // Data rows + parts.push(''); + for (let r = 0; r < rowCount; r++) { + const row = rows[r]; + parts.push(''); + parts.push(`${r + 1}`); + for (let c = 0; c < colCount; c++) { + const val = c < row.length ? row[c] : ''; + const isNum = typeof val === 'number'; + parts.push(`${esc(val)}`); + } + parts.push(''); + } + parts.push(''); - const DOMPurify = (await import('dompurify')).default; - return { - html: DOMPurify.sanitize(parts.join('')), - rowCount, - colCount - }; + const DOMPurify = (await import('dompurify')).default; + return { + html: DOMPurify.sanitize(parts.join('')), + rowCount, + colCount + }; } diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index 455594b65c..5a0f899ffc 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -275,7 +275,6 @@ export const canvasPixelTest = () => { return true; }; - let resizeImageWarmupDone = false; /** * Draws an image to a canvas at the given dimensions and returns a data URL. @@ -285,7 +284,7 @@ async function resizeImageToDataURL( img: HTMLImageElement, width: number, height: number, - mimeType = 'image/jpeg', + mimeType = 'image/jpeg' ): Promise { const canvas = document.createElement('canvas'); canvas.width = width; @@ -294,22 +293,23 @@ async function resizeImageToDataURL( const toDataURL = () => canvas.toDataURL(mimeType); - if (!resizeImageWarmupDone && canvas.toBlob && /android|iphone|ipad|ipod/i.test(navigator?.userAgent)) { + if ( + !resizeImageWarmupDone && + canvas.toBlob && + /android|iphone|ipad|ipod/i.test(navigator?.userAgent) + ) { resizeImageWarmupDone = true; return new Promise((resolve) => { - canvas.toBlob( - (blob) => { - if (!blob) { - resolve(toDataURL()); - return; - } - const reader = new FileReader(); - reader.onload = () => resolve(String(reader.result)); - reader.onerror = () => resolve(toDataURL()); - reader.readAsDataURL(blob); - }, - mimeType, - ); + canvas.toBlob((blob) => { + if (!blob) { + resolve(toDataURL()); + return; + } + const reader = new FileReader(); + reader.onload = () => resolve(String(reader.result)); + reader.onerror = () => resolve(toDataURL()); + reader.readAsDataURL(blob); + }, mimeType); }); } return Promise.resolve(toDataURL()); @@ -393,9 +393,9 @@ export const generateInitialsImage = (name) => { const initials = sanitizedName.length > 0 ? sanitizedName[0] + - (sanitizedName.split(' ').length > 1 - ? sanitizedName[sanitizedName.lastIndexOf(' ') + 1] - : '') + (sanitizedName.split(' ').length > 1 + ? sanitizedName[sanitizedName.lastIndexOf(' ') + 1] + : '') : ''; ctx.fillText(initials.toUpperCase(), canvas.width / 2, canvas.height / 2); @@ -551,10 +551,10 @@ export const compareVersion = (latest, current) => { return current === '0.0.0' ? false : current.localeCompare(latest, undefined, { - numeric: true, - sensitivity: 'case', - caseFirst: 'upper' - }) < 0; + numeric: true, + sensitivity: 'case', + caseFirst: 'upper' + }) < 0; }; export const extractCurlyBraceWords = (text) => { diff --git a/src/lib/utils/pptxToHtml.ts b/src/lib/utils/pptxToHtml.ts index 193469ddc5..045ac70001 100644 --- a/src/lib/utils/pptxToHtml.ts +++ b/src/lib/utils/pptxToHtml.ts @@ -11,249 +11,247 @@ const EMU_PER_PX = 9525; const emuToPx = (emu: number) => Math.round(emu / EMU_PER_PX); -const parseEmu = (val: string | null | undefined): number => - val ? parseInt(val, 10) || 0 : 0; +const parseEmu = (val: string | null | undefined): number => (val ? parseInt(val, 10) || 0 : 0); /** Load a data URI into an Image element and wait for it. */ const loadImage = (src: string): Promise => - new Promise((resolve, reject) => { - const img = new Image(); - img.onload = () => resolve(img); - img.onerror = () => reject(new Error('Failed to load image')); - img.src = src; - }); + new Promise((resolve, reject) => { + const img = new Image(); + img.onload = () => resolve(img); + img.onerror = () => reject(new Error('Failed to load image')); + img.src = src; + }); /** * Convert PPTX ArrayBuffer → array of PNG data URL strings, one per slide. */ export async function pptxToImages( - buffer: ArrayBuffer + buffer: ArrayBuffer ): Promise<{ images: string[]; width: number; height: number }> { - const JSZip = (await import('jszip')).default; - const zip = await JSZip.loadAsync(buffer); + const JSZip = (await import('jszip')).default; + const zip = await JSZip.loadAsync(buffer); - // ── Read slide dimensions from presentation.xml ────────────────── - let slideW = 960; - let slideH = 540; - const presXml = zip.file('ppt/presentation.xml'); - if (presXml) { - const presText = await presXml.async('text'); - const presDoc = new DOMParser().parseFromString(presText, 'application/xml'); - const sldSz = presDoc.getElementsByTagName('p:sldSz')[0]; - if (sldSz) { - slideW = emuToPx(parseEmu(sldSz.getAttribute('cx'))); - slideH = emuToPx(parseEmu(sldSz.getAttribute('cy'))); - } - } + // ── Read slide dimensions from presentation.xml ────────────────── + let slideW = 960; + let slideH = 540; + const presXml = zip.file('ppt/presentation.xml'); + if (presXml) { + const presText = await presXml.async('text'); + const presDoc = new DOMParser().parseFromString(presText, 'application/xml'); + const sldSz = presDoc.getElementsByTagName('p:sldSz')[0]; + if (sldSz) { + slideW = emuToPx(parseEmu(sldSz.getAttribute('cx'))); + slideH = emuToPx(parseEmu(sldSz.getAttribute('cy'))); + } + } - // ── Collect media files (images) as base64 data URIs ───────────── - const media: Record = {}; - const mediaFiles = Object.keys(zip.files).filter((f) => f.startsWith('ppt/media/')); - await Promise.all( - mediaFiles.map(async (path) => { - const file = zip.file(path); - if (!file) return; - const base64 = await file.async('base64'); - const ext = path.split('.').pop()?.toLowerCase() ?? ''; - const mime = - ext === 'png' - ? 'image/png' - : ext === 'gif' - ? 'image/gif' - : ext === 'svg' - ? 'image/svg+xml' - : ext === 'emf' || ext === 'wmf' - ? 'image/x-emf' - : 'image/jpeg'; - media[path] = `data:${mime};base64,${base64}`; - }) - ); + // ── Collect media files (images) as base64 data URIs ───────────── + const media: Record = {}; + const mediaFiles = Object.keys(zip.files).filter((f) => f.startsWith('ppt/media/')); + await Promise.all( + mediaFiles.map(async (path) => { + const file = zip.file(path); + if (!file) return; + const base64 = await file.async('base64'); + const ext = path.split('.').pop()?.toLowerCase() ?? ''; + const mime = + ext === 'png' + ? 'image/png' + : ext === 'gif' + ? 'image/gif' + : ext === 'svg' + ? 'image/svg+xml' + : ext === 'emf' || ext === 'wmf' + ? 'image/x-emf' + : 'image/jpeg'; + media[path] = `data:${mime};base64,${base64}`; + }) + ); - // ── Discover slide files ───────────────────────────────────────── - const slideFiles = Object.keys(zip.files) - .filter((f) => /^ppt\/slides\/slide\d+\.xml$/.test(f)) - .sort((a, b) => { - const na = parseInt(a.match(/slide(\d+)/)?.[1] ?? '0'); - const nb = parseInt(b.match(/slide(\d+)/)?.[1] ?? '0'); - return na - nb; - }); + // ── Discover slide files ───────────────────────────────────────── + const slideFiles = Object.keys(zip.files) + .filter((f) => /^ppt\/slides\/slide\d+\.xml$/.test(f)) + .sort((a, b) => { + const na = parseInt(a.match(/slide(\d+)/)?.[1] ?? '0'); + const nb = parseInt(b.match(/slide(\d+)/)?.[1] ?? '0'); + return na - nb; + }); - const images: string[] = []; + const images: string[] = []; - for (const slidePath of slideFiles) { - const slideText = await zip.file(slidePath)!.async('text'); - const slideDoc = new DOMParser().parseFromString(slideText, 'application/xml'); + for (const slidePath of slideFiles) { + const slideText = await zip.file(slidePath)!.async('text'); + const slideDoc = new DOMParser().parseFromString(slideText, 'application/xml'); - // Load relationship file for this slide to resolve image references - const slideNum = slidePath.match(/slide(\d+)/)?.[1]; - const relsPath = `ppt/slides/_rels/slide${slideNum}.xml.rels`; - const rels: Record = {}; - const relsFile = zip.file(relsPath); - if (relsFile) { - const relsText = await relsFile.async('text'); - const relsDoc = new DOMParser().parseFromString(relsText, 'application/xml'); - const relEls = relsDoc.getElementsByTagName('Relationship'); - for (let i = 0; i < relEls.length; i++) { - const rel = relEls[i]; - const id = rel.getAttribute('Id') ?? ''; - const target = rel.getAttribute('Target') ?? ''; - if (target.startsWith('../')) { - rels[id] = 'ppt/' + target.replace('../', ''); - } else { - rels[id] = target; - } - } - } + // Load relationship file for this slide to resolve image references + const slideNum = slidePath.match(/slide(\d+)/)?.[1]; + const relsPath = `ppt/slides/_rels/slide${slideNum}.xml.rels`; + const rels: Record = {}; + const relsFile = zip.file(relsPath); + if (relsFile) { + const relsText = await relsFile.async('text'); + const relsDoc = new DOMParser().parseFromString(relsText, 'application/xml'); + const relEls = relsDoc.getElementsByTagName('Relationship'); + for (let i = 0; i < relEls.length; i++) { + const rel = relEls[i]; + const id = rel.getAttribute('Id') ?? ''; + const target = rel.getAttribute('Target') ?? ''; + if (target.startsWith('../')) { + rels[id] = 'ppt/' + target.replace('../', ''); + } else { + rels[id] = target; + } + } + } - // ── Create canvas and render slide ─────────────────────────── - const canvas = document.createElement('canvas'); - canvas.width = slideW; - canvas.height = slideH; - const ctx = canvas.getContext('2d')!; + // ── Create canvas and render slide ─────────────────────────── + const canvas = document.createElement('canvas'); + canvas.width = slideW; + canvas.height = slideH; + const ctx = canvas.getContext('2d')!; - // White background - ctx.fillStyle = '#ffffff'; - ctx.fillRect(0, 0, slideW, slideH); + // White background + ctx.fillStyle = '#ffffff'; + ctx.fillRect(0, 0, slideW, slideH); - const spTree = slideDoc.getElementsByTagName('p:spTree')[0]; - if (!spTree) { - images.push(canvas.toDataURL('image/png')); - continue; - } + const spTree = slideDoc.getElementsByTagName('p:spTree')[0]; + if (!spTree) { + images.push(canvas.toDataURL('image/png')); + continue; + } - const shapes = [ - ...Array.from(spTree.getElementsByTagName('p:sp')), - ...Array.from(spTree.getElementsByTagName('p:pic')) - ]; + const shapes = [ + ...Array.from(spTree.getElementsByTagName('p:sp')), + ...Array.from(spTree.getElementsByTagName('p:pic')) + ]; - for (const shape of shapes) { - const xfrm = - shape.getElementsByTagName('a:xfrm')[0] ?? - shape.getElementsByTagName('p:xfrm')[0]; - if (!xfrm) continue; + for (const shape of shapes) { + const xfrm = + shape.getElementsByTagName('a:xfrm')[0] ?? shape.getElementsByTagName('p:xfrm')[0]; + if (!xfrm) continue; - const off = xfrm.getElementsByTagName('a:off')[0]; - const ext = xfrm.getElementsByTagName('a:ext')[0]; - if (!off || !ext) continue; + const off = xfrm.getElementsByTagName('a:off')[0]; + const ext = xfrm.getElementsByTagName('a:ext')[0]; + if (!off || !ext) continue; - const x = emuToPx(parseEmu(off.getAttribute('x'))); - const y = emuToPx(parseEmu(off.getAttribute('y'))); - const w = emuToPx(parseEmu(ext.getAttribute('cx'))); - const h = emuToPx(parseEmu(ext.getAttribute('cy'))); + const x = emuToPx(parseEmu(off.getAttribute('x'))); + const y = emuToPx(parseEmu(off.getAttribute('y'))); + const w = emuToPx(parseEmu(ext.getAttribute('cx'))); + const h = emuToPx(parseEmu(ext.getAttribute('cy'))); - if (w === 0 && h === 0) continue; + if (w === 0 && h === 0) continue; - // ── Picture ────────────────────────────────────────────── - const blipFill = shape.getElementsByTagName('p:blipFill')[0]; - if (blipFill) { - const blip = blipFill.getElementsByTagName('a:blip')[0]; - if (blip) { - const rEmbed = blip.getAttribute('r:embed') ?? ''; - const mediaPath = rels[rEmbed]; - const dataUri = mediaPath ? media[mediaPath] : ''; - if (dataUri && !dataUri.includes('image/x-emf')) { - try { - const img = await loadImage(dataUri); - ctx.drawImage(img, x, y, w, h); - } catch { - // Skip images that fail to load - } - } - } - continue; - } + // ── Picture ────────────────────────────────────────────── + const blipFill = shape.getElementsByTagName('p:blipFill')[0]; + if (blipFill) { + const blip = blipFill.getElementsByTagName('a:blip')[0]; + if (blip) { + const rEmbed = blip.getAttribute('r:embed') ?? ''; + const mediaPath = rels[rEmbed]; + const dataUri = mediaPath ? media[mediaPath] : ''; + if (dataUri && !dataUri.includes('image/x-emf')) { + try { + const img = await loadImage(dataUri); + ctx.drawImage(img, x, y, w, h); + } catch { + // Skip images that fail to load + } + } + } + continue; + } - // ── Text shape ─────────────────────────────────────────── - const txBody = shape.getElementsByTagName('p:txBody')[0]; - if (!txBody) continue; + // ── Text shape ─────────────────────────────────────────── + const txBody = shape.getElementsByTagName('p:txBody')[0]; + if (!txBody) continue; - ctx.save(); - ctx.rect(x, y, w, h); - ctx.clip(); + ctx.save(); + ctx.rect(x, y, w, h); + ctx.clip(); - const paragraphs = txBody.getElementsByTagName('a:p'); - let cursorY = y; - const defaultFontSize = 12; + const paragraphs = txBody.getElementsByTagName('a:p'); + let cursorY = y; + const defaultFontSize = 12; - for (let pi = 0; pi < paragraphs.length; pi++) { - const para = paragraphs[pi]; - const runs = para.getElementsByTagName('a:r'); + for (let pi = 0; pi < paragraphs.length; pi++) { + const para = paragraphs[pi]; + const runs = para.getElementsByTagName('a:r'); - if (runs.length === 0) { - cursorY += defaultFontSize * 1.5; - continue; - } + if (runs.length === 0) { + cursorY += defaultFontSize * 1.5; + continue; + } - // Calculate max font size in this paragraph for line height - let maxFontPt = defaultFontSize; - for (let ri = 0; ri < runs.length; ri++) { - const rPr = runs[ri].getElementsByTagName('a:rPr')[0]; - if (rPr) { - const sz = rPr.getAttribute('sz'); - if (sz) { - const pt = parseInt(sz, 10) / 100; - if (pt > maxFontPt) maxFontPt = pt; - } - } - } + // Calculate max font size in this paragraph for line height + let maxFontPt = defaultFontSize; + for (let ri = 0; ri < runs.length; ri++) { + const rPr = runs[ri].getElementsByTagName('a:rPr')[0]; + if (rPr) { + const sz = rPr.getAttribute('sz'); + if (sz) { + const pt = parseInt(sz, 10) / 100; + if (pt > maxFontPt) maxFontPt = pt; + } + } + } - const lineHeight = maxFontPt * 1.4; - cursorY += maxFontPt; // baseline offset + const lineHeight = maxFontPt * 1.4; + cursorY += maxFontPt; // baseline offset - let cursorX = x + 4; // small left padding + let cursorX = x + 4; // small left padding - for (let ri = 0; ri < runs.length; ri++) { - const run = runs[ri]; - const rPr = run.getElementsByTagName('a:rPr')[0]; - const text = run.getElementsByTagName('a:t')[0]?.textContent ?? ''; - if (!text) continue; + for (let ri = 0; ri < runs.length; ri++) { + const run = runs[ri]; + const rPr = run.getElementsByTagName('a:rPr')[0]; + const text = run.getElementsByTagName('a:t')[0]?.textContent ?? ''; + if (!text) continue; - let fontPt = defaultFontSize; - let bold = false; - let italic = false; - let color = '#000000'; + let fontPt = defaultFontSize; + let bold = false; + let italic = false; + let color = '#000000'; - if (rPr) { - if (rPr.getAttribute('b') === '1') bold = true; - if (rPr.getAttribute('i') === '1') italic = true; - const sz = rPr.getAttribute('sz'); - if (sz) fontPt = parseInt(sz, 10) / 100; - const solidFill = rPr.getElementsByTagName('a:solidFill')[0]; - if (solidFill) { - const srgb = solidFill.getElementsByTagName('a:srgbClr')[0]; - if (srgb) { - const val = srgb.getAttribute('val'); - if (val) color = `#${val}`; - } - } - } + if (rPr) { + if (rPr.getAttribute('b') === '1') bold = true; + if (rPr.getAttribute('i') === '1') italic = true; + const sz = rPr.getAttribute('sz'); + if (sz) fontPt = parseInt(sz, 10) / 100; + const solidFill = rPr.getElementsByTagName('a:solidFill')[0]; + if (solidFill) { + const srgb = solidFill.getElementsByTagName('a:srgbClr')[0]; + if (srgb) { + const val = srgb.getAttribute('val'); + if (val) color = `#${val}`; + } + } + } - ctx.font = `${italic ? 'italic ' : ''}${bold ? 'bold ' : ''}${fontPt}pt Calibri, Arial, sans-serif`; - ctx.fillStyle = color; - ctx.textBaseline = 'alphabetic'; + ctx.font = `${italic ? 'italic ' : ''}${bold ? 'bold ' : ''}${fontPt}pt Calibri, Arial, sans-serif`; + ctx.fillStyle = color; + ctx.textBaseline = 'alphabetic'; - // Simple word-wrap within the shape bounds - const words = text.split(/(\s+)/); - for (const word of words) { - const metrics = ctx.measureText(word); - if (cursorX + metrics.width > x + w && cursorX > x + 4) { - cursorX = x + 4; - cursorY += lineHeight; - } - if (cursorY > y + h) break; - ctx.fillText(word, cursorX, cursorY); - cursorX += metrics.width; - } - } + // Simple word-wrap within the shape bounds + const words = text.split(/(\s+)/); + for (const word of words) { + const metrics = ctx.measureText(word); + if (cursorX + metrics.width > x + w && cursorX > x + 4) { + cursorX = x + 4; + cursorY += lineHeight; + } + if (cursorY > y + h) break; + ctx.fillText(word, cursorX, cursorY); + cursorX += metrics.width; + } + } - cursorY += lineHeight * 0.4; // paragraph spacing - } + cursorY += lineHeight * 0.4; // paragraph spacing + } - ctx.restore(); - } + ctx.restore(); + } - images.push(canvas.toDataURL('image/png')); - } + images.push(canvas.toDataURL('image/png')); + } - return { images, width: slideW, height: slideH }; + return { images, width: slideW, height: slideH }; } From b9c0a9c3bf93fa6a4c1fd871304d90eab72eb432 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sat, 7 Mar 2026 23:16:43 +0100 Subject: [PATCH 0779/1854] enh: prevent models from always using internal knowledge base search first (#22264) Some models always primarily use the internal knowledge base first before deviating to the web search tool --- backend/open_webui/tools/builtin.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/backend/open_webui/tools/builtin.py b/backend/open_webui/tools/builtin.py index eec760fe01..7427592380 100644 --- a/backend/open_webui/tools/builtin.py +++ b/backend/open_webui/tools/builtin.py @@ -155,8 +155,7 @@ async def search_web( ) -> str: """ Search the public web for information. Best for current events, external references, - or topics not covered in internal documents. If knowledge base tools are available, - consider checking those first for internal information. + or topics not covered in internal documents. :param query: The search query to look up :param count: Number of results to return (default: 5) From fbf315e624ce64053928c69e2dd61fb2fca9a036 Mon Sep 17 00:00:00 2001 From: alifurkanstahl <180474740+alifurkanstahl@users.noreply.github.com> Date: Sat, 7 Mar 2026 23:31:23 +0100 Subject: [PATCH 0780/1854] i18n: expand Turkish translations across missing frontend UI strings (#22360) * feat(i18n): add Turkish translations for access and add-action strings * feat(i18n): add Turkish translations for access, permission, and upload strings * feat(i18n): add Turkish translations for API, archive, and attach strings * feat(i18n): add Turkish translations for chat and channel UI strings * feat(i18n): add Turkish translations for common UI actions and dialogs * feat(i18n): add Turkish translations for copy, create, and delete UI strings * feat(i18n): add Turkish translations for display, download, and edit UI strings * feat(i18n): add Turkish translations for form inputs, errors, and file UI string * feat(i18n): add Turkish translations for skill-related UI strings * i18n: add Turkish translations for settings-related UI strings * i18n: add Turkish translations for terminal-related UI strings * i18n: add Turkish translations for misc frontend UI strings * i18n: add Turkish translations for search-related UI strings --------- Co-authored-by: MSI I9 12900KS RTX --- src/lib/i18n/locales/tr-TR/translation.json | 718 ++++++++++---------- 1 file changed, 359 insertions(+), 359 deletions(-) diff --git a/src/lib/i18n/locales/tr-TR/translation.json b/src/lib/i18n/locales/tr-TR/translation.json index 9dddccb9cd..42c2b98fed 100644 --- a/src/lib/i18n/locales/tr-TR/translation.json +++ b/src/lib/i18n/locales/tr-TR/translation.json @@ -4,141 +4,141 @@ "(e.g. `sh webui.sh --api --api-auth username_password`)": "(örn. `sh webui.sh --api --api-auth username_password`)", "(e.g. `sh webui.sh --api`)": "(örn. `sh webui.sh --api`)", "(latest)": "(en son)", - "(leave blank for to use commercial endpoint)": "", + "(leave blank for to use commercial endpoint)": "Ticari uç noktayı kullanmak için boş bırakın", "[Last] dddd [at] h:mm A": "", "[Today at] h:mm A": "", "[Yesterday at] h:mm A": "", "{{ models }}": "{{ models }}", - "{{COUNT}} Available Tools": "", - "{{COUNT}} characters": "", - "{{COUNT}} extracted lines": "", - "{{COUNT}} files": "", - "{{COUNT}} hidden lines": "", - "{{COUNT}} members": "", + "{{COUNT}} Available Tools": "{{COUNT}} Kullanılabilir Araç", + "{{COUNT}} characters": "{{COUNT}} karakter", + "{{COUNT}} extracted lines": "{{COUNT}} çıkarılan satır", + "{{COUNT}} files": "{{COUNT}} dosya", + "{{COUNT}} hidden lines": "{{COUNT}} gizli satır", + "{{COUNT}} members": "{{COUNT}} üye", "{{COUNT}} Replies": "{{COUNT}} Yanıt", - "{{COUNT}} Rows": "", - "{{COUNT}} Sources": "", - "{{COUNT}} words": "", + "{{COUNT}} Rows": "{{COUNT}} satır", + "{{COUNT}} Sources": "{{COUNT}} kaynak", + "{{COUNT}} words": "{{COUNT}} kelime", "{{COUNT}}d_time_ago": "", "{{COUNT}}h_time_ago": "", "{{COUNT}}m_time_ago": "", "{{COUNT}}w_time_ago": "", "{{COUNT}}y_time_ago": "", "{{LOCALIZED_DATE}} at {{LOCALIZED_TIME}}": "", - "{{model}} download has been canceled": "", - "{{modelName}} profile image": "", - "{{NAMES}} reacted with {{REACTION}}": "", + "{{model}} download has been canceled": "{{model}} indirme işlemi iptal edildi", + "{{modelName}} profile image": "{{modelName}} profil resmi", + "{{NAMES}} reacted with {{REACTION}}": "{{NAMES}}, {{REACTION}} ile tepki verdi", "{{user}}'s Chats": "{{user}}'ın Sohbetleri", "{{webUIName}} Backend Required": "{{webUIName}} Arka-uç Gerekli", "*Prompt node ID(s) are required for image generation": "*Görüntü oluşturma için düğüm kimlikleri gereklidir", - "1 Source": "", - "1m_time_ago": "", - "A collaboration channel where people join as members": "", - "A discussion channel where access is controlled by groups and permissions": "", + "1 Source": "1 Kaynak", + "1m_time_ago": "1 dk önce", + "A collaboration channel where people join as members": "İnsanların üye olarak katıldığı bir iş birliği kanalı", + "A discussion channel where access is controlled by groups and permissions": "Erişimin gruplar ve izinlerle kontrol edildiği bir tartışma kanalı", "A new version (v{{LATEST_VERSION}}) is now available.": "Yeni bir sürüm (v{{LATEST_VERSION}}) artık mevcut.", - "A private conversation between you and selected users": "", + "A private conversation between you and selected users": "Sizinle seçili kullanıcılar arasında özel bir konuşma", "A task model is used when performing tasks such as generating titles for chats and web search queries": "Bir görev modeli, sohbetler ve web arama sorguları için başlık oluşturma gibi görevleri yerine getirirken kullanılır", "a user": "bir kullanıcı", "About": "Hakkında", - "Accept Autocomplete Generation\nJump to Prompt Variable": "", + "Accept Autocomplete Generation\nJump to Prompt Variable": "Otomatik Tamamlama Oluşturmayı Kabul Et\nPrompt Değişkenine Git", "Access": "Erişim", "Access Control": "Erişim Kontrolü", - "Access Grants": "", - "Access List": "", + "Access Grants": "Erişim İzinleri", + "Access List": "Erişim Listesi", "Accessible to all users": "Tüm kullanıcılara erişilebilir", "Account": "Hesap", "Account Activation Pending": "Hesap Aktivasyonu Bekleniyor", "Accurate information": "Doğru bilgi", - "Action": "", - "Action not found": "", + "Action": "Aksiyon", + "Action not found": "Aksiyon bulunamadı", "Action Required for Chat Log Storage": "Sohbet günlüğünü kaydetmek için işlem gerekli", "Actions": "Aksiyonlar", "Activate": "Aktif Et", "Activate this command by typing \"/{{COMMAND}}\" to chat input.": "Sohbet girişine \"/{{COMMAND}}\" yazarak bu komutu etkinleştirin.", "Active": "Etkin", "Active Users": "Aktif Kullanıcılar", - "Activity": "", + "Activity": "Etkinlik", "Add": "Ekle", "Add a model ID": "Bir model kimliği ekleyin", "Add a short description about what this model does": "Bu modelin ne yaptığı hakkında kısa bir açıklama ekleyin", "Add a tag": "Bir etiket ekleyin", - "Add a tag...": "", - "Add Access": "", + "Add a tag...": "Bir etiket ekleyin...", + "Add Access": "Erişim Ekle", "Add Arena Model": "Arena Modeli Ekle", "Add Connection": "Bağlantı Ekle", "Add Content": "İçerik Ekle", "Add content here": "Buraya içerik ekleyin", "Add Custom Parameter": "Özel Parametre Ekle", - "Add Custom Prompt": "", - "Add Details": "", + "Add Custom Prompt": "Özel Prompt Ekle", + "Add Details": "Ayrıntı Ekle", "Add Files": "Dosyalar Ekle", - "Add Image": "", - "Add Member": "", - "Add Members": "", + "Add Image": "Görsel Ekle", + "Add Member": "Üye Ekle", + "Add Members": "Üyeleri Ekle", "Add Memory": "Bellek Ekle", "Add Model": "Model Ekle", "Add Reaction": "Tepki Ekle", - "Add tag": "", + "Add tag": "Etiket ekle", "Add Tag": "Etiket Ekle", - "Add Terminal": "", - "Add Terminal Connection": "", + "Add Terminal": "Terminal Ekle", + "Add Terminal Connection": "Terminal Bağlantısı Ekle", "Add text content": "Metin içeriği ekleme", - "Add to favorites": "", + "Add to favorites": "Favorilere ekle", "Add User": "Kullanıcı Ekle", "Add User Group": "Kullanıcı Grubu Ekle", - "Add webpage": "", - "Add your Open Terminal URL and API key in Settings → Integrations.": "", + "Add webpage": "Web sayfası ekle", + "Add your Open Terminal URL and API key in Settings → Integrations.": "Open Terminal URL'nizi ve API anahtarınızı Ayarlar → Entegrasyonlar bölümünde girin.", "Additional Config": "Ek Yapılandırma", "Additional configuration options for marker. This should be a JSON string with key-value pairs. For example, '{\"key\": \"value\"}'. Supported keys include: disable_links, keep_pageheader_in_output, keep_pagefooter_in_output, filter_blank_pages, drop_repeated_text, layout_coverage_threshold, merge_threshold, height_tolerance, gap_threshold, image_threshold, min_line_length, level_count, default_level": "", - "Additional feedback comments": "", + "Additional feedback comments": "Ek geri bildirim yorumları", "Additional Parameters": "Ek Parametreler", "Adds filenames, titles, sections, and snippets into the BM25 text to improve lexical recall.": "", "Adjusting these settings will apply changes universally to all users.": "Bu ayarların yapılması, değişiklikleri tüm kullanıcılara evrensel olarak uygulayacaktır.", "admin": "yönetici", "Admin": "Yönetici", - "Admin Contact Email": "", + "Admin Contact Email": "Yönetici İletişim E-postası", "Admin Panel": "Yönetici Paneli", "Admin Settings": "Yönetici Ayarları", "Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "Yöneticiler her zaman tüm araçlara erişebilir; kullanıcıların çalışma alanındaki model başına atanmış araçlara ihtiyacı vardır.", - "Advanced": "", + "Advanced": "Gelişmiş", "Advanced Parameters": "Gelişmiş Parametreler", "Advanced parameters for MinerU parsing (enable_ocr, enable_formula, enable_table, language, model_version, page_ranges)": "", "Advanced Params": "Gelişmiş Parametreler", "After updating or changing the embedding model, you must reindex the knowledge base for the changes to take effect. You can do this using the \"Reindex\" button below.": "", "AI": "Yapay Zeka", "All": "Tüm", - "All chats have been unarchived.": "", - "All models are now hidden": "", - "All models are now visible": "", + "All chats have been unarchived.": "Tüm sohbetler arşivden çıkarıldı.", + "All models are now hidden": "Tüm modeller artık gizli", + "All models are now visible": "Tüm modeller artık görünür", "All models deleted successfully": "Tüm modeller başarıyla silindi", - "All time": "", - "All Users": "", - "Allow Call": "", + "All time": "Tüm zamanlar", + "All Users": "Tüm Kullanıcılar", + "Allow Call": "Aramaya İzin Ver", "Allow Chat Controls": "Sohbet Kontrollerine İzin Ver", "Allow Chat Delete": "Sohbet Silmeye İzin Ver", - "Allow Chat Edit": "Sohbet Silmeye İzin Ver", + "Allow Chat Edit": "Sohbet Düzenlemeye İzin Ver", "Allow Chat Export": "Sohbetin Dışa Aktarımına İzin Ver", - "Allow Chat Params": "", + "Allow Chat Params": "Sohbet Parametrelerine İzin Ver", "Allow Chat Share": "Sohbetin Paylaşılmasına İzin Ver", - "Allow Chat System Prompt": "", + "Allow Chat System Prompt": "Sohbet Sistem Promptuna İzin Ver", "Allow Chat Valves": "", - "Allow Continue Response": "", + "Allow Continue Response": "Yanıta Devam Etmeye İzin Ver", "Allow Delete Messages": "Mesaj Silmeye İzin Ver", "Allow File Upload": "Dosya Yüklemeye İzin Ver", "Allow Multiple Models in Chat": "Sohbette Birden Fazla Modele İzin Ver", - "Allow non-local voices": "Yerel olmayan seslere izin verin", - "Allow Rate Response": "", + "Allow non-local voices": "Yerel olmayan seslere izin ver", + "Allow Rate Response": "Yanıtı Değerlendirmeye İzin Ver", "Allow Regenerate Response": "Yanıtı Yeniden Oluşturmaya İzin Ver", - "Allow Sharing With Users": "", - "Allow Speech to Text": "", + "Allow Sharing With Users": "Kullanıcılarla Paylaşmaya İzin Ver", + "Allow Speech to Text": "Sesten Metne İzin Ver", "Allow Temporary Chat": "Geçici Sohbetlere İzin Ver", - "Allow Text to Speech": "", + "Allow Text to Speech": "Metinden Sese İzin Ver", "Allow User Location": "Kullanıcı Konumuna İzin Ver", "Allow Voice Interruption in Call": "Aramada Ses Kesintisine İzin Ver", - "Allow Web Upload": "", + "Allow Web Upload": "Web İçeriği Yüklemeye İzin Ver", "Allowed Endpoints": "İzin Verilen Uç Noktalar", - "Allowed File Extensions": "", - "Allowed file extensions for upload. Separate multiple extensions with commas. Leave empty for all file types.": "", + "Allowed File Extensions": "İzin Verilen Dosya Uzantıları", + "Allowed file extensions for upload. Separate multiple extensions with commas. Leave empty for all file types.": "Yükleme için izin verilen dosya uzantıları. Birden fazla uzantıyı virgülle ayırın. Tüm dosya türleri için boş bırakın.", "Already have an account?": "Zaten bir hesabınız mı var?", "Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out.": "", "Always": "Daima", @@ -147,56 +147,56 @@ "Always Play Notification Sound": "Her Zaman Bildirim Sesini Oynat", "Amazing": "Harika", "an assistant": "bir asistan", - "An error occurred while fetching the explanation": "", + "An error occurred while fetching the explanation": "Açıklama alınırken bir hata oluştu", "Analytics": "Analiz", "Analyzed": "Analiz edildi", "Analyzing...": "Analiz ediliyor...", "and {{COUNT}} more": "ve {{COUNT}} daha", "and create a new shared link.": "ve yeni bir paylaşılan bağlantı oluşturun.", "Android": "Android", - "Anyone": "", + "Anyone": "Herkes", "API Base URL": "API Temel URL", - "API Base URL for Datalab Marker service. Defaults to: https://www.datalab.to/api/v1/marker": "", + "API Base URL for Datalab Marker service. Defaults to: https://www.datalab.to/api/v1/marker": "Datalab Marker hizmeti için API temel URL'si. Varsayılan: https://www.datalab.to/api/v1/marker", "API Key": "API Anahtarı", "API Key created.": "API Anahtarı oluşturuldu.", "API Key Endpoint Restrictions": "API Anahtarı Uç Nokta Kısıtlamaları", "API keys": "API anahtarları", - "API Keys": "", - "API Mode": "", - "API Timeout": "", - "API Type": "", + "API Keys": "API Anahtarları", + "API Mode": "API Modu", + "API Timeout": "API Zaman Aşımı", + "API Type": "API Türü", "API Version": "API Sürümü", - "API Version is required": "", + "API Version is required": "API Sürümü gereklidir", "Application DN": "Uygulama DN", "Application DN Password": "Uygulama DN Parola", "applies to all users with the \"user\" role": "\"kullanıcı\" rolüne sahip tüm kullanıcılar için geçerlidir", "April": "Nisan", "Archive": "Arşiv", - "Archive All": "", + "Archive All": "Tümünü Arşivle", "Archive All Chats": "Tüm Sohbetleri Arşivle", "Archived Chats": "Arşivlenmiş Sohbetler", "archived-chat-export": "arşivlenmiş-sohbet-aktarımı", - "Are you sure you want to archive all chats? This action cannot be undone.": "", - "Are you sure you want to clear all memories? This action cannot be undone.": "", - "Are you sure you want to delete \"{{NAME}}\"?": "", - "Are you sure you want to delete all chats? This action cannot be undone.": "", + "Are you sure you want to archive all chats? This action cannot be undone.": "Tüm sohbetleri arşivlemek istediğinizden emin misiniz? Bu işlem geri alınamaz.", + "Are you sure you want to clear all memories? This action cannot be undone.": "Tüm bellekleri temizlemek istediğinizden emin misiniz? Bu işlem geri alınamaz.", + "Are you sure you want to delete \"{{NAME}}\"?": "\"{{NAME}}\" öğesini silmek istediğinizden emin misiniz?", + "Are you sure you want to delete all chats? This action cannot be undone.": "Tüm sohbetleri silmek istediğinizden emin misiniz? Bu işlem geri alınamaz.", "Are you sure you want to delete this channel?": "Bu kanalı silmek istediğinizden emin misiniz?", "Are you sure you want to delete this message?": "Bu mesajı silmek istediğinizden emin misiniz?", - "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "Bu sürümü silmek istediğinizden emin misiniz? Alt sürümler bu sürümün üst sürümüne yeniden bağlanacaktır.", "Are you sure you want to unarchive all archived chats?": "Arşivlenmiş tüm sohbetlerin arşivini kaldırmak istediğinizden emin misiniz?", "Arena Models": "Arena Modelleri", "Artifacts": "Eserler", - "Asc": "", + "Asc": "Artan", "Ask": "Sor", "Ask a question": "Bir soru sorun", "Assistant": "Asistan", "Async Embedding Processing": "", - "Attach File From Knowledge": "", - "Attach Knowledge": "", - "Attach Notes": "", - "Attach Webpage": "", + "Attach File From Knowledge": "Bilgi Tabanından Dosya Ekle", + "Attach Knowledge": "Bilgi Tabanı Ekle", + "Attach Notes": "Not Ekle", + "Attach Webpage": "Web sayfası ekle", "Attention to detail": "Ayrıntılara dikkat", - "Attribute for Mail": "", + "Attribute for Mail": "E-posta için Özellik", "Attribute for Username": "Kullanıcı Adı için Özellik", "Audio": "Ses", "August": "Ağustos", @@ -204,7 +204,7 @@ "Authenticate": "Kimlik Doğrulama", "Authentication": "Kimlik Doğrulama", "Auto": "Otomatik", - "Auto (Random)": "", + "Auto (Random)": "Otomatik (Rastgele)", "Auto-Copy Response to Clipboard": "Yanıtı Panoya Otomatik Kopyala", "Auto-playback response": "Yanıtı otomatik oynatma", "Autocomplete Generation": "Otomatik Tamamlama Üretimi", @@ -215,7 +215,7 @@ "AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 Temel URL gereklidir.", "Automatically inject system tools in native function calling mode (e.g., timestamps, memory, chat history, notes, etc.)": "", "Available list": "Mevcut liste", - "Available models": "", + "Available models": "Mevcut modeller", "Available Tools": "Mevcut Araçlar", "available users": "kullanılabilir kullanıcılar", "available!": "mevcut!", @@ -233,24 +233,24 @@ "before": "önce", "Being lazy": "Tembelleşiyor", "Beta": "Beta", - "Bing": "", + "Bing": "Bing", "Bing Search V7 Endpoint": "Bing Arama V7 Uç Noktası", "Bing Search V7 Subscription Key": "Bing Arama V7 Abonelik Anahtarı", - "Bio": "", - "Birth Date": "", + "Bio": "Biyografi", + "Birth Date": "Doğum Tarihi", "BM25 Weight": "", "Bocha Search API Key": "Bocha Arama API Anahtarı", "Bold": "Kalın", "Boosting or penalizing specific tokens for constrained responses. Bias values will be clamped between -100 and 100 (inclusive). (Default: none)": "", - "Brave": "", + "Brave": "Brave", "Brave Search API Key": "Brave Search API Anahtarı", - "Browse and query knowledge bases": "", - "Builtin Tools": "", - "Bullet List": "", - "Button ID": "", - "Button Label": "", - "Button Prompt": "", - "by {{name}}": "", + "Browse and query knowledge bases": "Bilgi tabanlarına göz at ve sorgula", + "Builtin Tools": "Yerleşik Araçlar", + "Bullet List": "Madde İşaretli Liste", + "Button ID": "Düğme Kimliği", + "Button Label": "Düğme Etiketi", + "Button Prompt": "Düğme Promptu", + "by {{name}}": "{{name}} tarafından", "By {{name}}": "{{name}} Tarafından", "Bypass Embedding and Retrieval": "", "Bypass Web Loader": "", @@ -260,22 +260,22 @@ "Call feature is not supported when using Web STT engine": "Web STT motoru kullanılırken arama özelliği desteklenmiyor", "Camera": "Kamera", "Cancel": "İptal", - "Cancel download of {{model}}": "", - "Cannot create an empty note.": "", - "Cannot delete the production version": "", + "Cancel download of {{model}}": "{{model}} indirmesini iptal et", + "Cannot create an empty note.": "Boş bir not oluşturulamaz.", + "Cannot delete the production version": "Üretim sürümü silinemez", "Capabilities": "Yetenekler", "Capture": "Kayıt", "Capture Audio": "Sesi Kaydet", "Certificate Path": "Sertifika Yolu", - "Change folder icon": "", + "Change folder icon": "Klasör simgesini değiştir", "Change Password": "Parola Değiştir", - "Change User Role": "", + "Change User Role": "Kullanıcı Rolünü Değiştir", "Channel": "Kanal", "Channel deleted successfully": "Kanal başarıyla silindi", "Channel Name": "Kanal Adı", - "Channel name cannot be empty.": "", - "Channel name must be less than 128 characters": "", - "Channel Type": "", + "Channel name cannot be empty.": "Kanal adı boş olamaz.", + "Channel name must be less than 128 characters": "Kanal adı 128 karakterden kısa olmalıdır", + "Channel Type": "Kanal Türü", "Channel updated successfully": "Kanal başarıyla güncellendi", "Channels": "Kanallar", "Character": "Karakter", @@ -285,17 +285,17 @@ "Chat archived.": "", "Chat Background Image": "Sohbet Arka Plan Resmi", "Chat Bubble UI": "Sohbet Balonu Arayüzü", - "Chat Completions": "", - "Chat Conversation": "", + "Chat Completions": "Sohbet Tamamlamaları", + "Chat Conversation": "Sohbet Konuşması", "Chat direction": "Sohbet Yönü", - "Chat exported successfully": "", - "Chat History": "", - "Chat ID": "", - "Chat moved successfully": "", + "Chat exported successfully": "Sohbet başarıyla dışa aktarıldı", + "Chat History": "Sohbet Geçmişi", + "Chat ID": "Sohbet Kimliği", + "Chat moved successfully": "Sohbet başarıyla taşındı", "Chat Permissions": "Sohbet İzinleri", "Chat Tags Auto-Generation": "Sohbet Etiketleri Otomatik Oluşturma", - "Chat unshared successfully.": "", - "chats": "", + "Chat unshared successfully.": "Sohbet paylaşımı başarıyla kaldırıldı.", + "chats": "sohbetler", "Chats": "Sohbetler", "Check Again": "Tekrar Kontrol Et", "Check for updates": "Güncellemeleri kontrol et", @@ -310,8 +310,8 @@ "Citations": "Alıntılar", "Clear memory": "Belleği temizle", "Clear Memory": "Belleği Temizle", - "Clear search": "", - "Clear status": "", + "Clear search": "Aramayı temizle", + "Clear status": "Durumu temizle", "click here": "buraya tıklayın", "Click here for filter guides.": "Filtre kılavuzları için buraya tıklayın.", "Click here for help.": "Yardım için buraya tıklayın.", @@ -325,21 +325,21 @@ "Click here to upload a workflow.json file.": "Bir workflow.json dosyası yüklemek için buraya tıklayın.", "click here.": "buraya tıklayın.", "Click on the user role button to change a user's role.": "Bir kullanıcının rolünü değiştirmek için kullanıcı rolü düğmesine tıklayın.", - "Click to copy ID": "", + "Click to copy ID": "Kimliği kopyalamak için tıklayın", "Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Panoya yazma izni reddedildi. Tarayıcı ayarlarını kontrol ederek gerekli izinleri sağlayabilirsiniz.", "Clone": "Klon", "Clone Chat": "Sohbeti Klonla", "Clone of {{TITLE}}": "{{TITLE}}'ın kopyası", "Close": "Kapat", - "Close Banner": "", - "Close chat controls": "", - "Close citation modal": "", - "Close Configure Connection Modal": "", - "Close feedback": "", - "Close modal": "", - "Close Modal": "", - "Close settings modal": "", - "Close Sidebar": "", + "Close Banner": "Afişi kapat", + "Close chat controls": "Sohbet kontrollerini kapat", + "Close citation modal": "Alıntı penceresini kapat", + "Close Configure Connection Modal": "Bağlantı Yapılandırma penceresini kapat", + "Close feedback": "Geri bildirimi kapat", + "Close modal": "Pencereyi kapat", + "Close Modal": "Pencereyi kapat", + "Close settings modal": "Ayarlar penceresini kapat", + "Close Sidebar": "Kenar çubuğunu kapat", "cloud": "", "CMU ARCTIC speaker embedding name": "", "Code Block": "", @@ -352,10 +352,10 @@ "Code Interpreter": "Kod Yorumlayıcısı", "Code Interpreter Engine": "Kod Yorumlama Motoru", "Code Interpreter Prompt Template": "Kod Yorumlama İstem Şablonu", - "Collaboration channel where people join as members": "", + "Collaboration channel where people join as members": "İnsanların üye olarak katıldığı bir iş birliği kanalı", "Collapse": "Daralt", "Collection": "Koleksiyon", - "Collections": "", + "Collections": "Koleksiyonlar", "Color": "Renk", "ComfyUI": "ComfyUI", "ComfyUI API Key": "ComfyUI API Anahtarı", @@ -364,13 +364,13 @@ "ComfyUI Workflow": "ComfyUI İş Akışı", "ComfyUI Workflow Nodes": "ComfyUI İş Akışı Düğümleri", "Comma separated Node Ids (e.g. 1 or 1,2)": "", - "command": "", + "command": "komut", "Command": "Komut", "Comment": "Yorum", "Commit Message": "", - "Community Reviews": "", + "Community Reviews": "Topluluk İncelemeleri", "Completions": "Tamamlamalar", - "Compress Images in Channels": "", + "Compress Images in Channels": "Kanallarda Görselleri Sıkıştır", "Concurrent Requests": "Eşzamanlı İstekler", "Config": "", "Config imported successfully": "", @@ -379,10 +379,10 @@ "Confirm Password": "Parolayı Onayla", "Confirm your action": "İşleminizi onaylayın", "Confirm your new password": "Yeni parolanızı onaylayın", - "Confirm Your Password": "", - "Connect to an AI provider to start chatting": "", - "Connect to Open Terminal instances to browse files and use them as always-on tools. Only one can be active at a time.": "", - "Connect to Open Terminal instances. All users will have access to file browsing and terminal tools through these servers.": "", + "Confirm Your Password": "Parolanızı Onaylayın", + "Connect to an AI provider to start chatting": "Sohbete başlamak için bir AI sağlayıcısına bağlanın", + "Connect to Open Terminal instances to browse files and use them as always-on tools. Only one can be active at a time.": "Dosyalara göz atmak ve bunları her zaman açık araçlar olarak kullanmak için Open Terminal örneklerine bağlanın. Aynı anda yalnızca biri etkin olabilir.", + "Connect to Open Terminal instances. All users will have access to file browsing and terminal tools through these servers.": "Open Terminal örneklerine bağlanın. Tüm kullanıcılar bu sunucular üzerinden dosya gezintisine ve terminal araçlarına erişebilecek.", "Connect to your own OpenAI compatible API endpoints.": "", "Connect to your own OpenAPI compatible external tool servers.": "Kendi OpenAPI uyumlu harici araç sunucularınıza bağlanın.", "Connection failed": "Bağlantı başarısız", @@ -404,14 +404,14 @@ "Control the repetition of token sequences in the generated text. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 1.1) will be more lenient. At 1, it is disabled.": "", "Controls": "Kontroller", "Controls the balance between coherence and diversity of the output. A lower value will result in more focused and coherent text.": "", - "Conversation saved successfully": "", + "Conversation saved successfully": "Konuşma başarıyla kaydedildi", "Copied": "Kopyalandı", "Copied link to clipboard": "Bağlantıyı panoya kopyalandı", "Copied shared chat URL to clipboard!": "Paylaşılan sohbet URL'si panoya kopyalandı!", "Copied to clipboard": "Panoya kopyalandı", "Copy": "Kopyala", - "Copy API Key": "", - "Copy content": "", + "Copy API Key": "API Anahtarını Kopyala", + "Copy content": "İçeriği kopyala", "Copy Formatted Text": "Biçimlenirilmiş Metni Kopyala", "Copy Last Code Block": "", "Copy Last Response": "", @@ -424,56 +424,56 @@ "Copy URL": "", "Copying to clipboard was successful!": "Panoya kopyalama başarılı!", "CORS must be properly configured by the provider to allow requests from Open WebUI.": "Open WebUI’dan gelen isteklerin kabul edilebilmesi için sağlayıcının CORS yapılandırmasının doğru şekilde yapılmış olması gerekir.", - "Could not read file.": "", + "Could not read file.": "Dosya okunamadı.", "Create": "Oluştur", "Create a knowledge base": "Bir bilgi tabanı oluştur", "Create a model": "Bir model oluştur", - "Create a new note": "", + "Create a new note": "Yeni bir not oluştur", "Create Account": "Hesap Oluştur", "Create Admin Account": "Yönetici Hesabı Oluştur", "Create Channel": "Kanal Oluştur", "Create Folder": "Klasör Oluştur", - "Create Image": "", + "Create Image": "Görsel Oluştur", "Create Knowledge": "Bilgi Oluştur", "Create Model": "Model Oluştur", "Create new key": "Yeni anahtar oluştur", "Create new secret key": "Yeni gizli anahtar oluştur", - "Create note": "", + "Create note": "Not oluştur", "Create Note": "Not Oluştur", "Create your first note by clicking on the plus button below.": "İlk notunuzu aşağıdaki artı düğmesine basarak oluşturun.", "Created at": "Oluşturulma tarihi", "Created At": "Şu Tarihte Oluşturuldu:", "Created by": "Şunun tarafından oluşturuldu:", "Created by you": "Senin tarafından oluşturuldu", - "Created on {{date}}": "", + "Created on {{date}}": "{{date}} tarihinde oluşturuldu", "CSV Import": "CSV İçe Aktarma", - "Ctrl+Enter to Send": "", + "Ctrl+Enter to Send": "Göndermek için Ctrl+Enter", "Current Model": "Mevcut Model", "Current Password": "Mevcut Parola", "Custom": "Özel", - "Custom description enabled": "", - "Custom Gender": "", + "Custom description enabled": "Özel açıklama etkin", + "Custom Gender": "Özel Cinsiyet", "Custom Parameter Name": "", "Custom Parameter Value": "", - "Daily Messages": "", + "Daily Messages": "Günlük Mesajlar", "Danger Zone": "Tehlikeli Bölge", "Dark": "Koyu", - "Data Controls": "", + "Data Controls": "Veri Kontrolleri", "Database": "Veritabanı", "Datalab Marker API": "", "DD/MM/YYYY": "GG/AA/YYYY", "DDGS Backend": "", "December": "Aralık", - "Decrease UI Scale": "", + "Decrease UI Scale": "Arayüz Ölçeğini Küçült", "Deepgram": "", "Default": "Varsayılan", "Default (Open AI)": "Varsayılan (Open AI)", "Default (SentenceTransformers)": "Varsayılan (SentenceTransformers)", - "Default action buttons will be used.": "", - "Default description enabled": "", - "Default Features": "", - "Default Filters": "", - "Default Group": "", + "Default action buttons will be used.": "Varsayılan işlem düğmeleri kullanılacak.", + "Default description enabled": "Varsayılan açıklama etkin", + "Default Features": "Varsayılan Özellikler", + "Default Filters": "Varsayılan Filtreler", + "Default Group": "Varsayılan Grup", "Default mode works with a wider range of models by calling tools once before execution. Native mode leverages the model's built-in tool-calling capabilities, but requires the model to inherently support this feature.": "Varsayılan mod, araçları yürütmeden önce bir kez çağırarak daha geniş bir model yelpazesiyle çalışır. Yerel mod, modelin yerleşik araç çağırma yeteneklerinden yararlanır, ancak modelin bu özelliği doğal olarak desteklemesini gerektirir.", "Default Model": "Varsayılan Model", "Default model updated": "Varsayılan model güncellendi", @@ -484,48 +484,48 @@ "Default to ALL": "TÜMÜ'nü varsayılan olarak", "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", "Default User Role": "Varsayılan Kullanıcı Rolü", - "Defaults": "", + "Defaults": "Varsayılanlar", "Delete": "Sil", "Delete a model": "Bir modeli sil", - "Delete All": "", + "Delete All": "Tümünü Sil", "Delete All Chats": "Tüm Sohbetleri Sil", - "Delete all contents inside this folder": "", + "Delete all contents inside this folder": "Bu klasördeki tüm içerikleri sil", "Delete Chat": "Sohbeti Sil", "Delete chat?": "Sohbeti sil?", - "Delete File": "", + "Delete File": "Dosyayı Sil", "Delete folder?": "Klasörü sil?", "Delete function?": "Fonksiyonu sil?", "Delete Message": "Mesajı Sil", "Delete message?": "Mesaj Silinsin mi?", - "Delete Model": "", + "Delete Model": "Modeli Sil", "Delete note?": "Not Silinsin mi?", "Delete prompt?": "Promptu sil?", - "Delete skill?": "", + "Delete skill?": "Yeteneği sil?", "delete this link": "bu bağlantıyı sil", "Delete tool?": "Aracı sil?", "Delete User": "Kullanıcıyı Sil", - "Delete Version": "", - "Deleted": "", + "Delete Version": "Sürümü Sil", + "Deleted": "Silindi", "Deleted {{deleteModelTag}}": "{{deleteModelTag}} silindi", "Deleted {{name}}": "{{name}} silindi", "Deleted User": "Kullanıcı Silindi", "Deployment names are required for Azure OpenAI": "", - "Desc": "", - "Describe the edit...": "", - "Describe the image...": "", - "Describe what changed...": "", + "Desc": "Azalan", + "Describe the edit...": "Düzenlemeyi açıklayın...", + "Describe the image...": "Görseli açıklayın...", + "Describe what changed...": "Nelerin değiştiğini açıklayın...", "Describe your knowledge base and objectives": "Bilgi tabanınızı ve hedeflerinizi açıklayın", "Description": "Açıklama", - "Detect Artifacts Automatically": "", + "Detect Artifacts Automatically": "Eserleri Otomatik Algıla", "Dictate": "", "Didn't fully follow instructions": "Talimatları tam olarak takip etmedi", "Direct": "Doğrudan", "Direct Connections": "Doğrudan Bağlantılar", - "Direct Connections allow users to connect to their own OpenAI compatible API endpoints.": "", - "Direct Message": "", - "Direct Tool Servers": "", - "Directory selection was cancelled": "", - "Disable All": "", + "Direct Connections allow users to connect to their own OpenAI compatible API endpoints.": "Doğrudan Bağlantılar, kullanıcıların kendi OpenAI uyumlu API uç noktalarına bağlanmasına olanak tanır.", + "Direct Message": "Doğrudan Mesaj", + "Direct Tool Servers": "Doğrudan Araç Sunucuları", + "Directory selection was cancelled": "Dizin seçimi iptal edildi", + "Disable All": "Tümünü Devre Dışı Bırak", "Disable Code Interpreter": "Kod Yorumlayıcıyı Devre Dışı Bırak", "Disable Image Extraction": "", "Disable image extraction from the PDF. If Use LLM is enabled, images will be automatically captioned. Defaults to False.": "", @@ -534,24 +534,24 @@ "Discover a model": "Bir model keşfedin", "Discover a prompt": "Bir prompt keşfedin", "Discover a tool": "Bir araç keşfedin", - "Discover how to use Open WebUI and seek support from the community.": "", + "Discover how to use Open WebUI and seek support from the community.": "Open WebUI'yi nasıl kullanacağınızı keşfedin ve topluluktan destek alın.", "Discover wonders": "Harikaları keşfedin", "Discover, download, and explore custom functions": "Özel fonksiyonları keşfedin, indirin ve inceleyin", "Discover, download, and explore custom prompts": "Özel promptları keşfedin, indirin ve inceleyin", "Discover, download, and explore custom tools": "Özel araçları keşfedin, indirin ve inceleyin", "Discover, download, and explore model presets": "Model ön ayarlarını keşfedin, indirin ve inceleyin", - "Discussion channel where access is based on groups and permissions": "", - "Display": "", - "Display chat title in tab": "", + "Discussion channel where access is based on groups and permissions": "Erişimin gruplar ve izinlere dayandığı bir tartışma kanalı", + "Display": "Görüntüle", + "Display chat title in tab": "Sekmede sohbet başlığını göster", "Display Emoji in Call": "Aramada Emoji Göster", - "Display Multi-model Responses in Tabs": "", + "Display Multi-model Responses in Tabs": "Çoklu model yanıtlarını sekmelerde göster", "Display the username instead of You in the Chat": "Sohbet'te Siz yerine kullanıcı adını göster", "Displays citations in the response": "Yanıtta alıntıları gösterir", - "Displays status updates (e.g., web search progress) in the response": "", + "Displays status updates (e.g., web search progress) in the response": "Yanıtta durum güncellemelerini gösterir (ör. web arama ilerlemesi)", "Dive into knowledge": "Bilgiye dalmak", "Do not install functions from sources you do not fully trust.": "Tamamen güvenmediğiniz kaynaklardan fonksiyonlar yüklemeyin.", "Do not install tools from sources you do not fully trust.": "Tamamen güvenmediğiniz kaynaklardan araçlar yüklemeyin.", - "Do you want to sync your usage stats with Open WebUI Community?": "", + "Do you want to sync your usage stats with Open WebUI Community?": "Kullanım istatistiklerinizi Open WebUI Community ile senkronize etmek istiyor musunuz?", "Docling": "Docling", "Docling Parameters": "", "Docling Server URL required.": "", @@ -560,9 +560,9 @@ "Document Intelligence endpoint required.": "", "Document Intelligence Model": "", "Documentation": "Dökümantasyon", - "Documents": "", + "Documents": "Belgeler", "does not make any external connections, and your data stays securely on your locally hosted server.": "herhangi bir harici bağlantı yapmaz ve verileriniz güvenli bir şekilde yerel olarak barındırılan sunucunuzda kalır.", - "Domain Filter List": "", + "Domain Filter List": "Alan Adı Filtre Listesi", "don't fetch random pipelines from sources you don't trust.": "Güvenmediğiniz kaynaklardan rastgele pipelines getirmeyin.", "Don't have an account?": "Hesabınız yok mu?", "don't install random functions from sources you don't trust.": "Tanımadığınız kaynaklardan rastgele fonksiyonlar yüklemeyin.", @@ -571,33 +571,33 @@ "Done": "Tamamlandı", "Download": "İndir", "Download & Delete": "İndir ve Sil", - "Download as JSON": "", + "Download as JSON": "JSON olarak indir", "Download as SVG": "SVG olarak İndir", "Download canceled": "İndirme iptal edildi", "Download Database": "Veritabanını İndir", - "Downloading stats...": "", + "Downloading stats...": "İstatistikler indiriliyor...", "Draw": "Çiz", - "Drop any files here to upload": "", - "Drop files here to upload": "", + "Drop any files here to upload": "Yüklemek için dosyaları buraya bırakın", + "Drop files here to upload": "Yüklemek için dosyaları buraya bırakın", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "örn. '30s', '10m'. Geçerli zaman birimleri 's', 'm', 'h'.", - "e.g. 'low', 'medium', 'high'": "", + "e.g. 'low', 'medium', 'high'": "örn. 'low', 'medium', 'high'", "e.g. \"json\" or a JSON schema": "örn. \"json\" veya JSON şablonu", "e.g. 60": "örn. 60", "e.g. A filter to remove profanity from text": "örn. Metinden küfürleri kaldırmak için bir filtre", - "e.g. about the Roman Empire": "", + "e.g. about the Roman Empire": "örn. Roma İmparatorluğu hakkında", "e.g. alloy, echo, shimmer": "", "e.g. Code Review Guidelines": "", "e.g. code-review-guidelines": "", - "e.g. en": "", + "e.g. en": "örn. en", "e.g. My Filter": "örn. Benim Filtrem", "e.g. My Tools": "örn. Benim Araçlarım", "e.g. my_filter": "örn. benim_filtrem", "e.g. my_tools": "örn. benim_araçlarım", - "e.g. pdf, docx, txt": "", - "e.g. Step-by-step instructions for code reviews": "", - "e.g. Tell me a fun fact": "", - "e.g. Tell me a fun fact about the Roman Empire": "", + "e.g. pdf, docx, txt": "örn. pdf, docx, txt", + "e.g. Step-by-step instructions for code reviews": "örn. Kod incelemeleri için adım adım talimatlar", + "e.g. Tell me a fun fact": "örn. Bana eğlenceli bir bilgi söyle", + "e.g. Tell me a fun fact about the Roman Empire": "örn. Bana Roma İmparatorluğu hakkında eğlenceli bir bilgi söyle", "e.g. Tools for performing various operations": " örn.Çeşitli işlemleri gerçekleştirmek için araçlar", "e.g., 3, 4, 5 (leave blank for default)": "örn. 3, 4, 5 (öntanımlı değer için boş bırakın)", "e.g., audio/wav,audio/mpeg,video/* (leave blank for defaults)": "", @@ -608,12 +608,12 @@ "Edit Channel": "Kanalı Düzenle", "Edit Connection": "Bağlantıyı Düzenle", "Edit Default Permissions": "Varsayılan İzinleri Düzenle", - "Edit Folder": "", - "Edit Image": "", - "Edit Last Message": "", + "Edit Folder": "Klasörü Düzenle", + "Edit Image": "Görseli Düzenle", + "Edit Last Message": "Son Mesajı Düzenle", "Edit Memory": "Belleği Düzenle", "Edit Prompt": "", - "Edit Terminal Connection": "", + "Edit Terminal Connection": "Terminal Bağlantısını Düzenle", "Edit User": "Kullanıcıyı Düzenle", "Edit User Group": "Kullanıcı Grubunu Düzenle", "Edit workflow.json content": "", @@ -630,7 +630,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Gömme Modeli", "Embedding Model Engine": "Gömme Modeli Motoru", - "Enable All": "", + "Enable All": "Tümünü Etkinleştir", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Sohbet mesajları için otomatik tamamlama üretimini etkinleştir", "Enable Code Execution": "Kod Çalıştırmayı Etkinleştir", @@ -638,7 +638,7 @@ "Enable Community Sharing": "Topluluk Paylaşımını Etkinleştir", "Enable Memory Locking (mlock) to prevent model data from being swapped out of RAM. This option locks the model's working set of pages into RAM, ensuring that they will not be swapped out to disk. This can help maintain performance by avoiding page faults and ensuring fast data access.": "", "Enable Memory Mapping (mmap) to load model data. This option allows the system to use disk storage as an extension of RAM by treating disk files as if they were in RAM. This can improve model performance by allowing for faster data access. However, it may not work correctly with all systems and can consume a significant amount of disk space.": "", - "Enable Message Queue": "", + "Enable Message Queue": "Mesaj Kuyruğunu Etkinleştir", "Enable Message Rating": "Mesaj Değerlendirmeyi Etkinleştir", "Enable Mirostat sampling for controlling perplexity.": "", "Enable New Sign Ups": "Yeni Kayıtları Etkinleştir", @@ -648,7 +648,7 @@ "Endpoint URL": "Uçnokta URL", "Enforce Temporary Chat": "Geçici Sohbete Zorla", "Enhance": "İyileştir", - "Enrich Hybrid Search Text": "", + "Enrich Hybrid Search Text": "Hibrit Arama Metnini Zenginleştir", "Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "CSV dosyanızın şu sırayla 4 sütun içerdiğinden emin olun: İsim, E-posta, Şifre, Rol.", "Enter {{role}} message here": "Buraya {{role}} mesajını girin", "Enter a detail about yourself for your LLMs to recall": "LLM'lerinizin hatırlaması için kendiniz hakkında bir bilgi girin", @@ -662,7 +662,7 @@ "Enter Application DN Password": "Uygulama DN Parolasını Girin", "Enter Bing Search V7 Endpoint": "Bing Arama V7 Uç Noktasını Girin", "Enter Bing Search V7 Subscription Key": "Bing Arama V7 Abonelik Anahtarını Girin", - "Enter Bocha Search API Key": "", + "Enter Bocha Search API Key": "Bocha Search API Anahtarını Girin", "Enter Brave Search API Key": "Brave Search API Anahtarını Girin", "Enter certificate path": "Sertifika yolunu girin", "Enter Chunk Min Size Target": "", @@ -683,10 +683,10 @@ "Enter Exa API Key": "", "Enter External Document Loader API Key": "", "Enter External Document Loader URL": "", - "Enter External Web Loader API Key": "", - "Enter External Web Loader URL": "", - "Enter External Web Search API Key": "", - "Enter External Web Search URL": "", + "Enter External Web Loader API Key": "Harici Web Yükleyici API Anahtarını Girin", + "Enter External Web Loader URL": "Harici Web Yükleyici URL'sini Girin", + "Enter External Web Search API Key": "Harici Web Arama API Anahtarını Girin", + "Enter External Web Search URL": "Harici Web Arama URL'sini Girin", "Enter Firecrawl API Base URL": "", "Enter Firecrawl API Key": "", "Enter Firecrawl Timeout": "", @@ -704,7 +704,7 @@ "Enter Jupyter Token": "", "Enter Jupyter URL": "", "Enter Kagi Search API Key": "Kagi Search API Anahtarını Girin", - "Enter Key Behavior": "", + "Enter Key Behavior": "Enter Tuşu Davranışı", "Enter language codes": "Dil kodlarını girin", "Enter MinerU API Key": "", "Enter Mistral API Base URL": "", @@ -715,10 +715,10 @@ "Enter name": "İsim girin", "Enter New Password": "Yeni Parola Girin", "Enter Number of Steps (e.g. 50)": "Adım Sayısını Girin (örn. 50)", - "Enter Ollama Cloud API Key": "", - "Enter Perplexity API Key": "", - "Enter Perplexity Search API URL": "", - "Enter Playwright Timeout": "", + "Enter Ollama Cloud API Key": "Ollama Cloud API Anahtarını Girin", + "Enter Perplexity API Key": "Perplexity API Anahtarını Girin", + "Enter Perplexity Search API URL": "Perplexity Search API URL'sini Girin", + "Enter Playwright Timeout": "Playwright Zaman Aşımını Girin", "Enter Playwright WebSocket URL": "", "Enter proxy URL (e.g. https://user:password@host:port)": "", "Enter reasoning effort": "", @@ -726,7 +726,7 @@ "Enter SearchApi API Key": "Arama-API Anahtarını Girin", "Enter SearchApi Engine": "Arama-API Motorunu Girin", "Enter Searxng Query URL": "Searxng Sorgu URL'sini girin", - "Enter Searxng search language": "", + "Enter Searxng search language": "Searxng arama dilini girin", "Enter Seed": " Tohum(seed) Girin", "Enter SerpApi API Key": "", "Enter SerpApi Engine": "", @@ -736,32 +736,32 @@ "Enter server host": "Sunucu ana bilgisayarını girin", "Enter server label": "Sunucu etiketini girin", "Enter server port": "Sunucu bağlantı noktasını girin", - "Enter skill instructions in markdown...": "", - "Enter Sougou Search API sID": "", - "Enter Sougou Search API SK": "", + "Enter skill instructions in markdown...": "Yetenek talimatlarını Markdown olarak girin...", + "Enter Sougou Search API sID": "Sougou Search API sID'sini Girin", + "Enter Sougou Search API SK": "Sougou Search API SK'sini Girin", "Enter stop sequence": "Durdurma dizisini girin", "Enter system prompt": "Sistem promptunu girin", "Enter system prompt here": "Sistem promptunu buraya girin.", "Enter Tavily API Key": "Tavily API Anahtarını Girin", "Enter Tavily Extract Depth": "", "Enter the public URL of your WebUI. This URL will be used to generate links in the notifications.": "", - "Enter the URL of the function to import": "", - "Enter the URL to import": "", + "Enter the URL of the function to import": "İçe aktarılacak fonksiyonun URL'sini girin", + "Enter the URL to import": "İçe aktarılacak URL'yi girin", "Enter Tika Server URL": "Tika Sunucu URL'sini Girin", - "Enter timeout in seconds": "", - "Enter to Send": "", + "Enter timeout in seconds": "Zaman aşımını saniye cinsinden girin", + "Enter to Send": "Göndermek için Enter", "Enter Top K": "Top K'yı girin", "Enter Top K Reranker": "", "Enter URL (e.g. http://127.0.0.1:7860/)": "URL'yi Girin (örn. http://127.0.0.1:7860/)", "Enter URL (e.g. http://localhost:11434)": "URL'yi Girin (e.g. http://localhost:11434)", - "Enter value": "", - "Enter value (true/false)": "", - "Enter Yacy Password": "", - "Enter Yacy URL (e.g. http://yacy.example.com:8090)": "", - "Enter Yacy Username": "", - "Enter Yandex Web Search API Key": "", - "Enter Yandex Web Search URL": "", - "Enter You.com API Key": "", + "Enter value": "Bir değer girin", + "Enter value (true/false)": "Bir değer girin (true/false)", + "Enter Yacy Password": "Yacy Parolasını Girin", + "Enter Yacy URL (e.g. http://yacy.example.com:8090)": "Yacy URL'sini Girin (örn. http://yacy.example.com:8090)", + "Enter Yacy Username": "Yacy Kullanıcı Adını Girin", + "Enter Yandex Web Search API Key": "Yandex Web Search API Anahtarını Girin", + "Enter Yandex Web Search URL": "Yandex Web Search URL'sini Girin", + "Enter You.com API Key": "You.com API Anahtarını Girin", "Enter your code here...": "Kodu buraya girin...", "Enter your current password": "Mevcut parolanızı girin", "Enter Your Email": "E-postanızı Girin", @@ -778,14 +778,14 @@ "Entra ID": "", "Error": "Hata", "ERROR": "HATA", - "Error accessing directory": "", + "Error accessing directory": "Dizine erişilirken hata oluştu", "Error accessing Google Drive: {{error}}": "Google Drive'a erişim hatası: {{error}}", - "Error accessing media devices.": "", - "Error starting recording.": "", + "Error accessing media devices.": "Medya cihazlarına erişirken hata oluştu.", + "Error starting recording.": "Kayıt başlatılırken hata oluştu.", "Error unloading model: {{error}}": "", "Error uploading file: {{error}}": "Dosya yüklenirken hata oluştu: {{error}}", - "Error: A model with the ID '{{modelId}}' already exists. Please select a different ID to proceed.": "", - "Error: Model ID cannot be empty. Please enter a valid ID to proceed.": "", + "Error: A model with the ID '{{modelId}}' already exists. Please select a different ID to proceed.": "Hata: '{{modelId}}' kimliğine sahip bir model zaten mevcut. Devam etmek için lütfen farklı bir kimlik seçin.", + "Error: Model ID cannot be empty. Please enter a valid ID to proceed.": "Hata: Model kimliği boş olamaz. Devam etmek için lütfen geçerli bir kimlik girin.", "Evaluations": "Değerlendirmeler", "Exa API Key": "Exa API Anahtarı", "Example: (&(objectClass=inetOrgPerson)(uid=%s))": "Örnek: (&(objectClass=inetOrgPerson)(uid=%s))", @@ -807,93 +807,93 @@ "Export All Chats (All Users)": "Tüm Sohbetleri Dışa Aktar (Tüm Kullanıcılar)", "Export chat (.json)": "Sohbeti dışa aktar (.json)", "Export Chats": "Sohbetleri Dışa Aktar", - "Export Config": "", - "Export Models": "", + "Export Config": "Yapılandırmayı Dışa Aktar", + "Export Models": "Modelleri Dışa Aktar", "Export Prompts": "", "Export to CSV": "CSV'ye Aktar", - "Export Tools": "", - "Export Users": "", - "External": "", - "External Document Loader URL required.": "", - "External Task Model": "", - "External Web Loader API Key": "", - "External Web Loader URL": "", - "External Web Search API Key": "", - "External Web Search URL": "", - "Fade Effect for Streaming Text": "", + "Export Tools": "Araçları Dışa Aktar", + "Export Users": "Kullanıcıları Dışa Aktar", + "External": "Harici", + "External Document Loader URL required.": "Harici Belge Yükleyici URL gerekli.", + "External Task Model": "Harici Görev Modeli", + "External Web Loader API Key": "Harici Web Yükleyici API Anahtarı", + "External Web Loader URL": "Harici Web Yükleyici URL'si", + "External Web Search API Key": "Harici Web Arama API Anahtarı", + "External Web Search URL": "Harici Web Arama URL'si", + "Fade Effect for Streaming Text": "Akış Metni için Solma Efekti", "Failed to add file.": "Dosya eklenemedi.", - "Failed to add members": "", + "Failed to add members": "Üyeler eklenemedi", "Failed to archive chat.": "", - "Failed to attach file": "", - "Failed to clear status": "", + "Failed to attach file": "Dosya eklenemedi", + "Failed to clear status": "Durum temizlenemedi", "Failed to connect to {{URL}} OpenAPI tool server": "", - "Failed to connect to {{URL}} terminal server": "", - "Failed to copy link": "", + "Failed to connect to {{URL}} terminal server": "{{URL}} terminal sunucusuna bağlanılamadı", + "Failed to copy link": "Bağlantı kopyalanamadı", "Failed to create API Key.": "API Anahtarı oluşturulamadı.", - "Failed to delete note": "", - "Failed to download image": "", - "Failed to extract content from the file: {{error}}": "", - "Failed to extract content from the file.": "", - "Failed to fetch models": "", - "Failed to generate title": "", - "Failed to import models": "", - "Failed to load chat preview": "", + "Failed to delete note": "Not silinemedi", + "Failed to download image": "Görsel indirilemedi", + "Failed to extract content from the file: {{error}}": "Dosyadan içerik çıkarılamadı: {{error}}", + "Failed to extract content from the file.": "Dosyadan içerik çıkarılamadı.", + "Failed to fetch models": "Modeller alınamadı", + "Failed to generate title": "Başlık oluşturulamadı", + "Failed to import models": "Modeller içe aktarılamadı", + "Failed to load chat preview": "Sohbet ön izlemesi yüklenemedi", "Failed to load DOCX file. Please try downloading it instead.": "", - "Failed to load Excel/CSV file. Please try downloading it instead.": "", - "Failed to load file content.": "", - "Failed to load Interface settings": "", + "Failed to load Excel/CSV file. Please try downloading it instead.": "Excel/CSV dosyası yüklenemedi. Lütfen bunun yerine indirmeyi deneyin.", + "Failed to load file content.": "Dosya içeriği yüklenemedi.", + "Failed to load Interface settings": "Arayüz ayarları yüklenemedi", "Failed to load PPTX file. Please try downloading it instead.": "", - "Failed to move chat": "", + "Failed to move chat": "Sohbet taşınamadı", "Failed to process URL: {{url}}": "", "Failed to read clipboard contents": "Pano içeriği okunamadı", - "Failed to remove member": "", + "Failed to remove member": "Üye kaldırılamadı", "Failed to render diagram": "", "Failed to render visualization": "", - "Failed to save connections": "", + "Failed to save connections": "Bağlantılar kaydedilemedi", "Failed to save conversation": "Sohbet kaydedilemedi", "Failed to save models configuration": "Modeller yapılandırması kaydedilemedi", - "Failed to save terminal servers": "", - "Failed to unshare chat.": "", + "Failed to save terminal servers": "Terminal sunucuları kaydedilemedi", + "Failed to unshare chat.": "Sohbet paylaşımı kaldırılamadı.", "Failed to update settings": "Ayarlar güncellenemedi", - "Failed to update status": "", + "Failed to update status": "Durum güncellenemedi", "Failed to upload file.": "Dosya yüklenemedi.", "Features": "Özellikler", "Features Permissions": "Özellik Yetkileri", "February": "Şubat", - "Feedback": "", - "Feedback Activity": "", - "Feedback deleted successfully": "", - "Feedback Details": "", + "Feedback": "Geri Bildirim", + "Feedback Activity": "Geri Bildirim Etkinliği", + "Feedback deleted successfully": "Geri bildirim başarıyla silindi", + "Feedback Details": "Geri Bildirim Ayrıntıları", "Feedback History": "Geri Bildirim Geçmişi", "Feel free to add specific details": "Spesifik ayrıntılar eklemekten çekinmeyin", - "Female": "", + "Female": "Kadın", "File": "Dosya", "File added successfully.": "Dosya başarıyla eklendi.", - "File attached to chat": "", - "File browser": "", - "File content": "", + "File attached to chat": "Dosya sohbete eklendi", + "File browser": "Dosya tarayıcısı", + "File content": "Dosya içeriği", "File content updated successfully.": "Dosya içeriği başarıyla güncellendi.", - "File Context": "", - "File deleted successfully.": "", + "File Context": "Dosya Bağlamı", + "File deleted successfully.": "Dosya başarıyla silindi.", "File Mode": "Dosya Modu", - "File name": "", + "File name": "Dosya adı", "File not found.": "Dosya bulunamadı.", "File removed successfully.": "Dosya başarıyla kaldırıldı.", "File size should not exceed {{maxSize}} MB.": "Dosya boyutu {{maxSize}} MB'yi aşmamalıdır.", - "File Upload": "", + "File Upload": "Dosya Yükleme", "File uploaded successfully": "Dosya başarıyla yüklendi", - "File uploaded!": "", - "Filename": "", + "File uploaded!": "Dosya yüklendi!", + "Filename": "Dosya adı", "Files": "Dosyalar", "Filter": "", "Filter is now globally disabled": "Filtre artık global olarak devre dışı", "Filter is now globally enabled": "Filtre artık global olarak devrede", "Filters": "Filtreler", "Fingerprint spoofing detected: Unable to use initials as avatar. Defaulting to default profile image.": "Parmak izi sahteciliği tespit edildi: Avatar olarak baş harfler kullanılamıyor. Varsayılan profil resmine dönülüyor.", - "Firecrawl API Base URL": "", - "Firecrawl API Key": "", - "Firecrawl Timeout (s)": "", - "Floating Quick Actions": "", + "Firecrawl API Base URL": "Firecrawl API Temel URL'si", + "Firecrawl API Key": "Firecrawl API Anahtarı", + "Firecrawl Timeout (s)": "Firecrawl Zaman Aşımı (s)", + "Floating Quick Actions": "Yüzen Hızlı Eylemler", "Focus Chat Input": "", "Folder": "Klasör", "Folder Background Image": "Klasör Arka Plan Resmi", @@ -910,7 +910,7 @@ "Follow Up Generation": "", "Follow Up Generation Prompt": "", "Follow up: {{question}}": "", - "Follow-Up Auto-Generation": "", + "Follow-Up Auto-Generation": "Devam İstemlerini Otomatik Oluşturma", "Followed instructions perfectly": "Talimatları mükemmel şekilde takip etti", "for placeholders": "", "Force OCR": "", @@ -992,7 +992,7 @@ "Hide from Sidebar": "", "Hide Model": "Modeli Gizle", "High": "", - "High Contrast Mode": "", + "High Contrast Mode": "Yüksek Kontrast Modu", "History": "", "Home": "", "Host": "Ana bilgisayar", @@ -1012,8 +1012,8 @@ "Ignite curiosity": "Merak uyandırın", "Image": "Görsel", "Image Compression": "Görüntü Sıkıştırma", - "Image Compression Height": "", - "Image Compression Width": "", + "Image Compression Height": "Görüntü Sıkıştırma Yüksekliği", + "Image Compression Width": "Görüntü Sıkıştırma Genişliği", "Image Edit": "", "Image Edit Engine": "", "Image Generation": "Görüntü Oluşturma", @@ -1039,7 +1039,7 @@ "Include `--api-auth` flag when running stable-diffusion-webui": "stable-diffusion-webui çalıştırılırken `--api-auth` bayrağını dahil edin", "Include `--api` flag when running stable-diffusion-webui": "stable-diffusion-webui çalıştırılırken `--api` bayrağını dahil edin", "Includes SharePoint": "SharePoint içerir", - "Increase UI Scale": "", + "Increase UI Scale": "Arayüz Ölçeğini Büyüt", "Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive.": "", "Info": "Bilgi", "Initials": "", @@ -1049,9 +1049,9 @@ "Input Key (e.g. text, unet_name, steps)": "", "Input Variables": "", "Insert": "", - "Insert Follow-Up Prompt to Input": "", - "Insert Prompt as Rich Text": "", - "Insert Suggestion Prompt to Input": "", + "Insert Follow-Up Prompt to Input": "Devam İstemini Girdiye Ekle", + "Insert Prompt as Rich Text": "İstemi Zengin Metin Olarak Ekle", + "Insert Suggestion Prompt to Input": "Öneri İstemini Girdiye Ekle", "Install from Github URL": "Github URL'sinden yükleyin", "Instant Auto-Send After Voice Transcription": "Ses Transkripsiyonundan Sonra Anında Otomatik Gönder", "Integration": "", @@ -1083,7 +1083,7 @@ "JWT Expiration": "JWT Bitişi", "JWT Token": "JWT Token", "Kagi Search API Key": "Kagi Arama API Anahtarı", - "Keep Follow-Up Prompts in Chat": "", + "Keep Follow-Up Prompts in Chat": "Devam İstemlerini Sohbette Tut", "Keep in Sidebar": "", "Key": "Anahtar", "Key is required": "Anahtar gerekli", @@ -1119,7 +1119,7 @@ "Leaderboard": "Liderlik Tablosu", "Learn more": "", "Learn More": "", - "Learn more about Open Terminal": "", + "Learn more about Open Terminal": "Open Terminal hakkında daha fazla bilgi edinin", "Learn more about OpenAPI tool servers.": "OpenAPI araç sunucuları hakkında daha fazla bilgi edinin.", "Learn more about Voxtral transcription.": "", "Leave a public review for {{modelName}}": "", @@ -1130,8 +1130,8 @@ "Leave empty to include all models from \"{{url}}/models\" endpoint": "", "Leave empty to include all models or select specific models": "Tüm modelleri dahil etmek için boş bırakın veya belirli modelleri seçin", "Leave empty to use first admin user": "", - "Leave empty to use the default config, or enter a valid json (see https://yandex.cloud/en/docs/search-api/api-ref/WebSearch/search#yandex.cloud.searchapi.v2.WebSearchRequest)": "", - "Leave empty to use the default model (voxtral-mini-latest).": "", + "Leave empty to use the default config, or enter a valid json (see https://yandex.cloud/en/docs/search-api/api-ref/WebSearch/search#yandex.cloud.searchapi.v2.WebSearchRequest)": "Varsayılan yapılandırmayı kullanmak için boş bırakın veya geçerli bir JSON girin (bkz. https://yandex.cloud/en/docs/search-api/api-ref/WebSearch/search#yandex.cloud.searchapi.v2.WebSearchRequest)", + "Leave empty to use the default model (voxtral-mini-latest).": "Varsayılan modeli kullanmak için boş bırakın (voxtral-mini-latest).", "Leave empty to use the default prompt, or enter a custom prompt": "Varsayılan promptu kullanmak için boş bırakın veya özel bir prompt girin", "Leave model field empty to use the default model.": "", "Legacy": "", @@ -1139,7 +1139,7 @@ "License": "Lisans", "Lift List": "", "Light": "Açık", - "Limit concurrent search queries. 0 = unlimited (default). Set to 1 for sequential execution (recommended for APIs with strict rate limits like Brave free tier).": "", + "Limit concurrent search queries. 0 = unlimited (default). Set to 1 for sequential execution (recommended for APIs with strict rate limits like Brave free tier).": "Eşzamanlı arama sorgularını sınırla. 0 = sınırsız (varsayılan). Sıralı yürütme için 1 olarak ayarlayın (Brave ücretsiz katman gibi katı oran sınırlarına sahip API'ler için önerilir).", "Limits the number of concurrent embedding requests. Set to 0 for unlimited.": "", "List": "", "Listening...": "Dinleniyor...", @@ -1221,12 +1221,12 @@ "Model {{name}} is now {{status}}": "{{name}} modeli artık {{status}}", "Model {{name}} is now hidden": "Model {{name}} artık gizli", "Model {{name}} is now visible": "Model {{name}} artık görünür", - "Model accepts file inputs": "", + "Model accepts file inputs": "Model dosya girdilerini kabul eder", "Model accepts image inputs": "Model görüntü girdilerini kabul eder", - "Model can execute code and perform calculations": "", + "Model can execute code and perform calculations": "Model kod çalıştırabilir ve hesaplamalar yapabilir", "Model can generate images based on text prompts": "", - "Model can search the web for information": "", - "Model Capabilities": "", + "Model can search the web for information": "Model bilgileri aramak için web'de arama yapabilir", + "Model Capabilities": "Model Yetenekleri", "Model created successfully!": "Model başarıyla oluşturuldu!", "Model filesystem path detected. Model shortname is required for update, cannot continue.": "Model dosya sistemi yolu algılandı. Güncelleme için model kısa adı gerekli, devam edilemiyor.", "Model Filtering": "Model Filtreleme", @@ -1262,7 +1262,7 @@ "More Options": "", "Move": "", "Moved {{name}}": "", - "My Terminal": "", + "My Terminal": "Terminalim", "Name": "Ad", "Name and ID are required, please fill them out": "", "Name your knowledge base": "Bilgi tabanınıza bir ad verin", @@ -1279,9 +1279,9 @@ "New Note": "", "New Password": "Yeni Parola", "New Prompt": "", - "New Skill": "", + "New Skill": "Yeni Yetenek", "New Temporary Chat": "", - "New Terminal": "", + "New Terminal": "Yeni Terminal", "New Tool": "", "New Webhook": "", "new-channel": "yeni-kanal", @@ -1326,12 +1326,12 @@ "No results found": "Sonuç bulunamadı", "No search query generated": "Hiç arama sorgusu oluşturulmadı", "No servers detected": "", - "No skills found": "", + "No skills found": "Yetenek bulunamadı", "No source available": "Kaynak mevcut değil", "No sources found": "", "No suggestion prompts": "Önerilen istem yok", - "No Terminal connection configured.": "", - "No terminal connections configured.": "", + "No Terminal connection configured.": "Yapılandırılmış Terminal bağlantısı yok.", + "No terminal connections configured.": "Yapılandırılmış terminal bağlantısı yok.", "No tool server connections configured.": "", "No tools found": "", "No users were found.": "Kullanıcı bulunamadı.", @@ -1386,12 +1386,12 @@ "Open in full screen": "Tam ekranda aç", "Open link": "", "Open modal to configure connection": "", - "Open Modal To Manage Floating Quick Actions": "", - "Open Modal To Manage Image Compression": "", + "Open Modal To Manage Floating Quick Actions": "Yüzen hızlı eylemleri yönetmek için pencereyi aç", + "Open Modal To Manage Image Compression": "Görüntü sıkıştırmayı yönetmek için pencereyi aç", "Open Model Selector": "", "Open Settings": "", "Open Sidebar": "", - "Open Terminal": "", + "Open Terminal": "Terminali Aç", "Open User Profile Menu": "", "Open WebUI can use tools provided by any OpenAPI server.": "Open WebUI OpenAPI tarafından sağlanan araçları kullanabilir", "Open WebUI uses faster-whisper internally.": "Open WebUI, dahili olarak daha hızlı-fısıltı kullanır.", @@ -1441,9 +1441,9 @@ "Permission denied when accessing microphone: {{error}}": "Mikrofona erişim izni reddedildi: {{error}}", "Permissions": "İzinler", "Perplexity API Key": "Perplexity API Anahtarı", - "Perplexity Model": "", - "Perplexity Search API URL": "", - "Perplexity Search Context Usage": "", + "Perplexity Model": "Perplexity Modeli", + "Perplexity Search API URL": "Perplexity Search API URL'si", + "Perplexity Search Context Usage": "Perplexity Search Bağlam Kullanımı", "Personalization": "Kişiselleştirme", "Pin": "Sabitle", "Pinned": "Sabitlenmiş", @@ -1513,7 +1513,7 @@ "Pull Model": "", "Query Generation Prompt": "Sorgu Oluşturma Promptu", "Querying": "", - "Quick Actions": "", + "Quick Actions": "Hızlı Eylemler", "RAG Template": "RAG Şablonu", "Rate {{rating}} out of 10": "", "Rating": "Derecelendirme", @@ -1535,7 +1535,7 @@ "Refresh": "", "Refused when it shouldn't have": "Reddedilmemesi gerekirken reddedildi", "Regenerate": "Tekrar Oluştur", - "Regenerate Menu": "", + "Regenerate Menu": "Yeniden Oluşturma Menüsü", "Regenerate Response": "", "Register Again": "", "Register Client": "", @@ -1558,7 +1558,7 @@ "Remove image": "", "Remove Model": "Modeli Kaldır", "Rename": "Yeniden Adlandır", - "Render Markdown in Previews": "", + "Render Markdown in Previews": "Önizlemelerde Markdown'u İşle", "Reorder Models": "Modelleri Yeniden Sırala", "Reply": "", "Reply in Thread": "Konuya Yanıtla", @@ -1602,46 +1602,46 @@ "Save Chat": "", "Saved": "Kaydedildi", "Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Sohbet kayıtlarının doğrudan tarayıcınızın depolama alanına kaydedilmesi artık desteklenmemektedir. Lütfen aşağıdaki butona tıklayarak sohbet kayıtlarınızı indirmek ve silmek için bir dakikanızı ayırın. Endişelenmeyin, sohbet günlüklerinizi arkayüze kolayca yeniden aktarabilirsiniz:", - "Scroll On Branch Change": "", + "Scroll On Branch Change": "Dal Değişiminde Kaydır", "Search": "Ara", "Search a model": "Bir model ara", - "Search all emojis": "", - "Search and manage user memories": "", - "Search and view user chat history": "", + "Search all emojis": "Tüm emojileri ara", + "Search and manage user memories": "Kullanıcı anılarını ara ve yönet", + "Search and view user chat history": "Kullanıcı sohbet geçmişini ara ve görüntüle", "Search Base": "Temel Ara", - "Search channels and channel messages": "", + "Search channels and channel messages": "Kanalları ve kanal mesajlarını ara", "Search Chats": "Sohbetleri Ara", "Search Collection": "Koleksiyon Ara", - "Search Files": "", + "Search Files": "Dosyaları Ara", "Search Filters": "Filtreleri Ara", - "search for archived chats": "", - "search for folders": "", - "search for pinned chats": "", - "search for shared chats": "", + "search for archived chats": "arşivlenmiş sohbetleri ara", + "search for folders": "klasörleri ara", + "search for pinned chats": "sabitlenmiş sohbetleri ara", + "search for shared chats": "paylaşılan sohbetleri ara", "search for tags": "etiketler için ara", "Search Functions": "Fonksiyonları Ara", - "Search Groups": "", - "Search In Models": "", + "Search Groups": "Grupları Ara", + "Search In Models": "Modellerde Ara", "Search Knowledge": "Bilgi Ara", "Search Models": "Modelleri Ara", - "Search Notes": "", + "Search Notes": "Notları Ara", "Search options": "Arama seçenekleri", "Search Prompts": "Prompt Ara", "Search Result Count": "Arama Sonucu Sayısı", - "Search Skills": "", + "Search Skills": "Yetenekleri Ara", "Search the internet": "İNternette Ara", - "Search the web and fetch URLs": "", + "Search the web and fetch URLs": "Web'de ara ve URL'leri getir", "Search Tools": "Arama Araçları", - "Search, view, and manage user notes": "", + "Search, view, and manage user notes": "Kullanıcı notlarını ara, görüntüle ve yönet", "SearchApi API Key": "Arama-API API Anahtarı", "SearchApi Engine": "Arama-API Motoru", "Searched {{count}} sites": "{{count}} site arandı", - "Searching": "", + "Searching": "Aranıyor", "Searching \"{{searchQuery}}\"": "\"{{searchQuery}}\" aranıyor", "Searching Knowledge for \"{{searchQuery}}\"": "\"{{searchQuery}}\" için Bilgi aranıyor", "Searching the web": "İnternette aranıyor...", "Searxng Query URL": "Searxng Sorgu URL'si", - "Searxng search language (all, en, es, de, fr, etc.)": "", + "Searxng search language (all, en, es, de, fr, etc.)": "Searxng arama dili (all, en, es, de, fr, vb.)", "See readme.md for instructions": "Yönergeler için readme.md dosyasına bakın", "See what's new": "Yeniliklere göz atın", "Seed": "Seed", @@ -1730,7 +1730,7 @@ "Show All": "", "Show all ({{COUNT}} characters)": "", "Show Files": "", - "Show Formatting Toolbar": "", + "Show Formatting Toolbar": "Biçimlendirme Araç Çubuğunu Göster", "Show image preview": "", "Show Model": "Modeli Göster", "Show Shortcuts": "", @@ -1748,18 +1748,18 @@ "Single": "", "Sink List": "", "sk-1234": "sk-1234", - "Skill created successfully": "", - "Skill deleted successfully": "", - "Skill Description": "", - "Skill ID": "", - "Skill imported successfully": "", - "Skill Instructions": "", - "Skill Name": "", - "Skill updated successfully": "", - "Skills": "", - "Skills Access": "", - "Skills Public Sharing": "", - "Skills Sharing": "", + "Skill created successfully": "Yetenek başarıyla oluşturuldu", + "Skill deleted successfully": "Yetenek başarıyla silindi", + "Skill Description": "Yetenek Açıklaması", + "Skill ID": "Yetenek Kimliği", + "Skill imported successfully": "Yetenek başarıyla içe aktarıldı", + "Skill Instructions": "Yetenek Talimatları", + "Skill Name": "Yetenek Adı", + "Skill updated successfully": "Yetenek başarıyla güncellendi", + "Skills": "Yetenekler", + "Skills Access": "Yeteneklere Erişim", + "Skills Public Sharing": "Yeteneklerin Herkese Açık Paylaşımı", + "Skills Sharing": "Yeteneklerin Paylaşımı", "Skip Cache": "", "Skip the cache and re-run the inference. Defaults to False.": "", "Something went wrong :/": "", @@ -1768,10 +1768,10 @@ "Sonar Pro": "", "Sonar Reasoning": "", "Sonar Reasoning Pro": "", - "Sort": "", - "Sort by": "", - "Sougou Search API sID": "", - "Sougou Search API SK": "", + "Sort": "Sırala", + "Sort by": "Şuna göre sırala", + "Sougou Search API sID": "Sougou Search API sID'si", + "Sougou Search API SK": "Sougou Search API SK'si", "Source": "Kaynak", "Speech Playback Speed": "Konuşma Oynatma Hızı", "Speech recognition error: {{error}}": "Konuşma tanıma hatası: {{error}}", @@ -1801,7 +1801,7 @@ "Strip existing OCR text from the PDF and re-run OCR. Ignored if Force OCR is enabled. Defaults to False.": "", "STT Model": "STT Modeli", "STT Settings": "STT Ayarları", - "Stylized PDF Export": "", + "Stylized PDF Export": "Biçimlendirilmiş PDF Dışa Aktarımı", "Submit question": "", "Submit suggestion": "", "Subtitle": "", @@ -1835,13 +1835,13 @@ "Task Model": "", "Tasks": "Görevler", "Tavily API Key": "Tavily API Anahtarı", - "Tavily Extract Depth": "", + "Tavily Extract Depth": "Tavily Çıkarma Derinliği", "Tell us more:": "Bize daha fazlasını anlat:", "Temperature": "Temperature", "Temporary Chat": "Geçici Sohbet", - "Temporary Chat by Default": "", - "Terminal": "", - "Terminal servers saved": "", + "Temporary Chat by Default": "Varsayılan Olarak Geçici Sohbet", + "Terminal": "Terminal", + "Terminal servers saved": "Terminal sunucuları kaydedildi", "Text Splitter": "Metin Bölücü", "Text-to-Speech": "Metinden Sese", "Text-to-Speech Engine": "Metinden Sese Motoru", @@ -1912,7 +1912,7 @@ "To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "WebUI'ye erişmek için lütfen yöneticiyle iletişime geçin. Yöneticiler kullanıcı durumlarını Yönetici Panelinden yönetebilir.", "To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "Bilgi tabanını buraya eklemek için önce bunları \"Bilgi\" çalışma alanına ekleyin.", "To learn more about available endpoints, visit our documentation.": "Mevcut uç noktalar hakkında daha fazla bilgi edinmek için belgelerimize göz atın.", - "To select skills here, add them to the \"Skills\" workspace first.": "", + "To select skills here, add them to the \"Skills\" workspace first.": "Burada yetenek seçmek için önce bunları \"Yetenekler\" çalışma alanına ekleyin.", "To select toolkits here, add them to the \"Tools\" workspace first.": "Araçları burada seçmek için öncelikle bunları \"Araçlar\" çalışma alanına ekleyin.", "Toast notifications for new updates": "", "Today": "Bugün", @@ -1948,9 +1948,9 @@ "Top K Reranker": "", "Transformers": "Dönüştürücüler", "Trouble accessing Ollama?": "Ollama'ya erişmede sorun mu yaşıyorsunuz?", - "Trust Proxy Environment": "", - "Try adjusting your search or filter to find what you are looking for.": "", - "Try Again": "", + "Trust Proxy Environment": "Proxy Ortamına Güven", + "Try adjusting your search or filter to find what you are looking for.": "Aradığınızı bulmak için aramanızı veya filtrenizi ayarlamayı deneyin.", + "Try Again": "Tekrar Dene", "TTS Model": "TTS Modeli", "TTS Settings": "TTS Ayarları", "TTS Voice": "TTS Sesi", @@ -1959,7 +1959,7 @@ "Type Hugging Face Resolve (Download) URL": "HuggingFace Çözümleme (İndirme) URL'sini Yazın", "Uh-oh! There was an issue with the response.": "Opps! Yanıtla ilgili bir sorun oluştu", "UI": "Arayüz", - "UI Scale": "", + "UI Scale": "Arayüz Ölçeği", "Unarchive All": "Tümünü Arşivden Çıkar", "Unarchive All Archived Chats": "Arşivlenmiş Tüm Sohbetleri Arşivden Çıkar", "Unarchive Chat": "Sohbeti Arşivden Çıkar", @@ -2060,7 +2060,7 @@ "Web Loader Engine": "", "Web Search": "Web Araması", "Web Search Engine": "Web Arama Motoru", - "Web Search in Chat": "", + "Web Search in Chat": "Sohbette Web Araması", "Web Search Query Generation": "Web Arama Sorgusu Oluşturma", "Webhook Name": "", "Webhook URL": "Webhook URL", @@ -2097,11 +2097,11 @@ "Yacy Instance URL": "", "Yacy Password": "Yacy Parolası", "Yacy Username": "Yacy Kullanıcı Adı", - "Yahoo": "", - "Yandex": "", - "Yandex Web Search API Key": "", - "Yandex Web Search config": "", - "Yandex Web Search URL": "", + "Yahoo": "Yahoo", + "Yandex": "Yandex", + "Yandex Web Search API Key": "Yandex Web Arama API Anahtarı", + "Yandex Web Search config": "Yandex Web Arama Yapılandırması", + "Yandex Web Search URL": "Yandex Web Arama URL'si", "Yesterday": "Dün", "Yesterday at {{LOCALIZED_TIME}}": "", "You": "Sen", @@ -2111,7 +2111,7 @@ "You cannot upload an empty file.": "Boş bir dosya yükleyemezsiniz.", "You do not have permission to edit this model": "", "You do not have permission to edit this prompt.": "", - "You do not have permission to edit this skill.": "", + "You do not have permission to edit this skill.": "Bu yeteneği düzenleme izniniz yok.", "You do not have permission to edit this tool": "", "You do not have permission to make this public": "", "You do not have permission to send messages in this channel.": "", From 2d0b94794f63f9b1a8c9db0e212e5d32b8f020bb Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sat, 7 Mar 2026 23:35:25 +0100 Subject: [PATCH 0781/1854] Update translation.json (#22353) --- src/lib/i18n/locales/de-DE/translation.json | 26 ++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/lib/i18n/locales/de-DE/translation.json b/src/lib/i18n/locales/de-DE/translation.json index 21e871c778..94d544d1bf 100644 --- a/src/lib/i18n/locales/de-DE/translation.json +++ b/src/lib/i18n/locales/de-DE/translation.json @@ -282,7 +282,7 @@ "Character limit for autocomplete generation input": "Zeichenlimit für Eingabe der Autovervollständigung", "Chart new frontiers": "Neue Grenzen erkunden", "Chat": "Chat", - "Chat archived.": "", + "Chat archived.": "Chat archiviert.", "Chat Background Image": "Hintergrundbild des Chats", "Chat Bubble UI": "Sprechblasen-Ansicht", "Chat Completions": "Chat Completions", @@ -823,7 +823,7 @@ "Fade Effect for Streaming Text": "Fade-Effekt für Text-Streaming", "Failed to add file.": "Hinzufügen der Datei fehlgeschlagen.", "Failed to add members": "Mitglieder konnten nicht hinzugefügt werden", - "Failed to archive chat.": "", + "Failed to archive chat.": "Chat konnte nicht archiviert werden.", "Failed to attach file": "Datei konnte nicht hinzugefügt werden", "Failed to clear status": "Status konnte nicht geleert werden", "Failed to connect to {{URL}} OpenAPI tool server": "Verbindung zum OpenAPI-Toolserver {{URL}} fehlgeschlagen", @@ -838,11 +838,11 @@ "Failed to generate title": "Titel konnte nicht generiert werden", "Failed to import models": "Modelle konnten nicht importiert werden", "Failed to load chat preview": "Chat-Vorschau konnte nicht geladen werden", - "Failed to load DOCX file. Please try downloading it instead.": "", + "Failed to load DOCX file. Please try downloading it instead.": "DOCX Datei konnte nicht geladen werden. Versuche die Datei stattdessen herunterzuladen.", "Failed to load Excel/CSV file. Please try downloading it instead.": "Excel/CSV-Datei konnte nicht geladen werden. Bitte versuchen Sie stattdessen, sie herunterzuladen.", "Failed to load file content.": "Dateiinhalt konnte nicht geladen werden.", "Failed to load Interface settings": "Interface Einstellungen konnten nicht geladen werden", - "Failed to load PPTX file. Please try downloading it instead.": "", + "Failed to load PPTX file. Please try downloading it instead.": "PPTX Datei konnte nicht geladen werden. Versuche die Datei stattdessen herunterzuladen.", "Failed to move chat": "Chat konnte nicht verschoben werden", "Failed to process URL: {{url}}": "{{url}} konnte nicht verarbeitet werden", "Failed to read clipboard contents": "Zwischenablage konnte nicht gelesen werden", @@ -1261,7 +1261,7 @@ "More options": "Mehr Optionen", "More Options": "Mehr Optionen", "Move": "Verschieben", - "Moved {{name}}": "", + "Moved {{name}}": "{{name}} verschoben", "My Terminal": "Meine Terminals", "Name": "Name", "Name and ID are required, please fill them out": "Name und ID sind erforderlich, bitte füllen Sie diese aus", @@ -1309,7 +1309,7 @@ "No history available": "Keine History verfügbar", "No HTML, CSS, or JavaScript content found.": "Keine HTML-, CSS- oder JavaScript-Inhalte gefunden.", "No inference engine with management support found": "Keine Inferenz-Engine mit Verwaltungsunterstützung gefunden", - "No kernel": "", + "No kernel": "Kein Kernel", "No knowledge bases found.": "Keine Wissensspeicher gefunden.", "No knowledge found": "Kein Wissen gefunden", "No memories to clear": "Keine Erinnerungen zum Löschen", @@ -1325,7 +1325,7 @@ "No results": "Keine Ergebnisse", "No results found": "Keine Ergebnisse gefunden", "No search query generated": "Keine Suchanfrage generiert", - "No servers detected": "", + "No servers detected": "Keine Server erkannt", "No skills found": "Keine Skills gefunden", "No source available": "Keine Quelle verfügbar", "No sources found": "Keine Quellen gefunden", @@ -1481,7 +1481,7 @@ "Please select at least one user for Direct Message channel.": "Bitte wählen Sie mindestens einen Benutzer für den Direktnachrichten-Kanal aus.", "Please wait until all files are uploaded.": "Bitte warten Sie, bis alle Dateien hochgeladen sind.", "Port": "Port", - "Ports": "", + "Ports": "Ports", "Positive attitude": "Positive Einstellung", "Prefer not to say": "Keine Angabe", "Prefix ID": "Präfix-ID", @@ -1578,7 +1578,7 @@ "Response splitting": "Antwortaufteilung", "Response Watermark": "Antwort-Wasserzeichen", "Responses": "Responses", - "Restart": "", + "Restart": "Neustarten", "Result": "Ergebnis", "RESULT": "ERGEBNIS", "Retrieval": "Abruf", @@ -1591,7 +1591,7 @@ "Role": "Rolle", "RTL": "RTL", "Run": "Ausführen", - "Run All": "", + "Run All": "Alle starten", "Running": "Läuft", "Running...": "Läuft...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "Führt Embedding-Aufgaben parallel aus, um die Verarbeitung zu beschleunigen. Deaktivieren Sie dies, falls Rate-Limits oder Ressourcenprobleme auftreten.", @@ -1782,7 +1782,7 @@ "Start a new conversation": "Neue Unterhaltung beginnen", "Start of the channel": "Beginn des Kanals", "Start Tag": "Start-Tag", - "Starting kernel...": "", + "Starting kernel...": "Kernel starten...", "Status": "Status", "Status cleared successfully": "Status erfolgreich gelöscht", "Status updated successfully": "Status erfolgreich aktualisiert", @@ -2127,8 +2127,8 @@ "You're now logged in.": "Sie sind jetzt angemeldet.", "Your Account": "Ihr Konto", "Your account status is currently pending activation.": "Ihr Kontostatus wartet derzeit auf Aktivierung.", - "Your browser does not support the audio tag.": "", - "Your browser does not support the video tag.": "", + "Your browser does not support the audio tag.": "Dein Browser unterstützt den Audio tag nicht.", + "Your browser does not support the video tag.": "Dein Browser unterstützt den Video tag nicht.", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Ihr gesamter Beitrag geht direkt an den Plugin-Entwickler; Open WebUI behält keinen Anteil ein. Die gewählte Plattform kann jedoch eigene Gebühren erheben.", "Your message text or inputs": "Ihre Nachrichtentexte oder Eingaben", "Your usage stats have been successfully synced.": "Ihre Nutzungsstatistiken wurden erfolgreich synchronisiert.", From c7d1d1e390a79c6c86d4bfe439fd7de6f5fb060f Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 16:36:20 -0600 Subject: [PATCH 0782/1854] refac --- src/lib/components/chat/Chat.svelte | 18 ++++++++++++------ .../workspace/Models/ModelEditor.svelte | 6 +++++- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index 8ea3edb882..7d5e131d26 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -2009,6 +2009,17 @@ return features; }; + const getStopTokens = () => { + const stop = params?.stop ?? $settings?.params?.stop; + if (!stop) return undefined; + + const tokens = Array.isArray(stop) ? stop : stop.split(',').map((s) => s.trim()); + + return tokens + .filter(Boolean) + .map((token) => decodeURIComponent(JSON.parse(`"${token.replace(/"/g, '\\"')}"`))); + }; + const sendMessageSocket = async (model, _messages, _history, responseMessageId, _chatId) => { const responseMessage = _history.messages[responseMessageId]; const userMessage = _history.messages[responseMessage.parentId]; @@ -2170,12 +2181,7 @@ params: { ...$settings?.params, ...params, - stop: - (params?.stop ?? $settings?.params?.stop ?? undefined) - ? (params?.stop.split(',').map((token) => token.trim()) ?? $settings.params.stop).map( - (str) => decodeURIComponent(JSON.parse('"' + str.replace(/\"/g, '\\"') + '"')) - ) - : undefined + stop: getStopTokens() }, files: (files?.length ?? 0) > 0 ? files : undefined, diff --git a/src/lib/components/workspace/Models/ModelEditor.svelte b/src/lib/components/workspace/Models/ModelEditor.svelte index 4d86113f50..8978c0c00a 100644 --- a/src/lib/components/workspace/Models/ModelEditor.svelte +++ b/src/lib/components/workspace/Models/ModelEditor.svelte @@ -218,7 +218,11 @@ } info.params.system = system.trim() === '' ? null : system; - info.params.stop = params.stop ? params.stop.split(',').filter((s) => s.trim()) : null; + info.params.stop = params.stop + ? (typeof params.stop === 'string' ? params.stop.split(',') : params.stop).filter( + (s) => s.trim() + ) + : null; Object.keys(info.params).forEach((key) => { if (info.params[key] === '' || info.params[key] === null) { delete info.params[key]; From 70a31a9a57bdd0690ac270f31ebd1b46e8fdfa98 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 16:40:14 -0600 Subject: [PATCH 0783/1854] fix: terminals button ui --- src/lib/components/chat/MessageInput.svelte | 92 +++++++++++---------- 1 file changed, 47 insertions(+), 45 deletions(-) diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index f3108abf25..5d5344592b 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -1803,59 +1803,61 @@ {/if} - {#if (!history?.currentId || history.messages[history.currentId]?.done == true) && ($_user?.role === 'admin' || ($_user?.permissions?.chat?.stt ?? true))} + {#if !history?.currentId || history.messages[history.currentId]?.done == true} {#if ($terminalServers ?? []).length > 0 || ($settings?.terminalServers ?? []).some((s) => s.url)} {/if} - - - - + + + + + + + {/if} {/if} {#if prompt === '' && files.length === 0 && ($_user?.role === 'admin' || ($_user?.permissions?.chat?.call ?? true))} From 044fd1bd15cae06a5c56a321ca79d8362942f66a Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 16:49:26 -0600 Subject: [PATCH 0784/1854] refac --- src/lib/components/chat/FileNav.svelte | 36 ++++++++++++++++---------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/lib/components/chat/FileNav.svelte b/src/lib/components/chat/FileNav.svelte index 707be186ef..81ee750a22 100644 --- a/src/lib/components/chat/FileNav.svelte +++ b/src/lib/components/chat/FileNav.svelte @@ -177,7 +177,8 @@ const config = await getTerminalConfig(terminal.url, terminal.key); terminalEnabled = config?.features?.terminal !== false; - const cwd = await getCwd(terminal.url, terminal.key); + const rawCwd = await getCwd(terminal.url, terminal.key); + const cwd = rawCwd ? normalizePath(rawCwd) : null; const dir = cwd ? (cwd.endsWith('/') ? cwd : cwd + '/') : '/'; savedPath = dir; loadDir(dir); @@ -197,18 +198,22 @@ const isPdf = (path: string) => path.split('.').pop()?.toLowerCase() === 'pdf'; const isOffice = (path: string) => OFFICE_EXTS.has(path.split('.').pop()?.toLowerCase() ?? ''); - const buildBreadcrumbs = (path: string) => - path - .split('/') - .filter(Boolean) - .reduce( - (acc, part) => { - const prev = acc[acc.length - 1]; - acc.push({ label: part, path: `${prev.path}${part}/` }); - return acc; - }, - [{ label: '/', path: '/' }] - ); + /** Normalize Windows backslashes to forward slashes. */ + const normalizePath = (p: string) => p.replace(/\\/g, '/'); + + const buildBreadcrumbs = (path: string) => { + const parts = path.split('/').filter(Boolean); + const isDrive = /^[A-Za-z]:$/.test(parts[0] ?? ''); + const root = isDrive ? { label: parts[0], path: `${parts[0]}/` } : { label: '/', path: '/' }; + return (isDrive ? parts.slice(1) : parts).reduce( + (acc, part) => { + const prev = acc[acc.length - 1]; + acc.push({ label: part, path: `${prev.path}${part}/` }); + return acc; + }, + [root] + ); + }; // ── File preview management ────────────────────────────────────────── const clearFilePreview = () => { @@ -486,6 +491,7 @@ if (!filePath || !selectedTerminal) return; handledDisplayFile = true; showFileNavPath.set(null); + filePath = normalizePath(filePath); const lastSlash = filePath.lastIndexOf('/'); const dir = lastSlash > 0 ? filePath.substring(0, lastSlash + 1) : '/'; @@ -507,6 +513,7 @@ const unsubFileNavDir = showFileNavDir.subscribe(async (filePath) => { if (!filePath || !selectedTerminal) return; showFileNavDir.set(null); + filePath = normalizePath(filePath); const lastSlash = filePath.lastIndexOf('/'); const dir = lastSlash > 0 ? filePath.substring(0, lastSlash + 1) : '/'; @@ -525,7 +532,8 @@ if (!handledDisplayFile) { if (savedPath === '/') { - const cwd = await getCwd(terminal.url, terminal.key); + const rawCwd = await getCwd(terminal.url, terminal.key); + const cwd = rawCwd ? normalizePath(rawCwd) : null; if (cwd) savedPath = cwd.endsWith('/') ? cwd : cwd + '/'; } loadDir(savedPath); From 51a2d2b7011040bb0550ace12aa4d33a66984bbe Mon Sep 17 00:00:00 2001 From: Shirasawa <764798966@qq.com> Date: Sun, 8 Mar 2026 06:51:04 +0800 Subject: [PATCH 0785/1854] i18n: improve Chinese translation (#22351) --- src/lib/i18n/locales/zh-CN/translation.json | 26 +++++++++---------- src/lib/i18n/locales/zh-TW/translation.json | 28 ++++++++++----------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/lib/i18n/locales/zh-CN/translation.json b/src/lib/i18n/locales/zh-CN/translation.json index 9fac1d692e..744785c78a 100644 --- a/src/lib/i18n/locales/zh-CN/translation.json +++ b/src/lib/i18n/locales/zh-CN/translation.json @@ -282,7 +282,7 @@ "Character limit for autocomplete generation input": "输入框内容自动补全输入的字符限制", "Chart new frontiers": "开辟前沿", "Chat": "对话", - "Chat archived.": "", + "Chat archived.": "对话已归档。", "Chat Background Image": "对话背景图片", "Chat Bubble UI": "以聊天气泡的形式显示对话内容", "Chat Completions": "Chat Completions", @@ -823,7 +823,7 @@ "Fade Effect for Streaming Text": "流式输出内容时启用动态渐显效果", "Failed to add file.": "添加文件失败", "Failed to add members": "添加成员失败", - "Failed to archive chat.": "", + "Failed to archive chat.": "对话归档失败。", "Failed to attach file": "文件上传失败", "Failed to clear status": "清除状态失败", "Failed to connect to {{URL}} OpenAPI tool server": "连接到 {{URL}} OpenAPI 工具服务器失败", @@ -838,11 +838,11 @@ "Failed to generate title": "生成标题失败", "Failed to import models": "导入模型配置失败", "Failed to load chat preview": "对话预览加载失败", - "Failed to load DOCX file. Please try downloading it instead.": "", + "Failed to load DOCX file. Please try downloading it instead.": "无法加载 DOCX 文件,请尝试下载后查看。", "Failed to load Excel/CSV file. Please try downloading it instead.": "加载 Excel/CSV 文件失败,请尝试直接下载文件。", "Failed to load file content.": "文件内容加载失败", "Failed to load Interface settings": "“界面设置”数据加载失败", - "Failed to load PPTX file. Please try downloading it instead.": "", + "Failed to load PPTX file. Please try downloading it instead.": "无法加载 PPTX 文件,请尝试下载后查看。", "Failed to move chat": "移动对话失败", "Failed to process URL: {{url}}": "处理链接失败: {{url}}", "Failed to read clipboard contents": "读取剪贴板内容失败", @@ -1261,7 +1261,7 @@ "More options": "更多选项", "More Options": "更多选项", "Move": "移动", - "Moved {{name}}": "", + "Moved {{name}}": "移动“{{name}}”成功", "My Terminal": "我的终端", "Name": "名称", "Name and ID are required, please fill them out": "名称和 ID 是必填项,请填写。", @@ -1309,7 +1309,7 @@ "No history available": "暂无历史记录", "No HTML, CSS, or JavaScript content found.": "未找到 HTML、CSS 或 JavaScript 内容。", "No inference engine with management support found": "未找到支持管理的推理引擎", - "No kernel": "", + "No kernel": "未找到内核", "No knowledge bases found.": "未找到知识库", "No knowledge found": "未找到知识", "No memories to clear": "记忆为空,无须清理", @@ -1325,7 +1325,7 @@ "No results": "未找到结果", "No results found": "未找到结果", "No search query generated": "未生成搜索查询", - "No servers detected": "", + "No servers detected": "未检测到任何服务器", "No skills found": "没有找到技能", "No source available": "没有可用引用来源", "No sources found": "未找到任何引用来源", @@ -1481,7 +1481,7 @@ "Please select at least one user for Direct Message channel.": "请至少选择一个用户以创建私聊频道。", "Please wait until all files are uploaded.": "请等待所有文件上传完毕。", "Port": "端口", - "Ports": "", + "Ports": "端口", "Positive attitude": "态度积极", "Prefer not to say": "暂不透露", "Prefix ID": "模型 ID 前缀", @@ -1578,7 +1578,7 @@ "Response splitting": "拆分回答", "Response Watermark": "复制时添加水印", "Responses": "Responses", - "Restart": "", + "Restart": "重启", "Result": "结果", "RESULT": "结果", "Retrieval": "检索", @@ -1590,7 +1590,7 @@ "Role": "角色", "RTL": "从右至左", "Run": "运行", - "Run All": "", + "Run All": "运行全部", "Running": "运行中", "Running...": "运行中...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "并行运行嵌入任务以加快处理速度。如果遇到限速问题,请关闭此选项。", @@ -1781,7 +1781,7 @@ "Start a new conversation": "开始新对话", "Start of the channel": "频道起点", "Start Tag": "起始标签", - "Starting kernel...": "", + "Starting kernel...": "正在启动内核...", "Status": "状态", "Status cleared successfully": "状态已清除", "Status updated successfully": "状态已更新", @@ -2126,8 +2126,8 @@ "You're now logged in.": "已登录。", "Your Account": "您的账号", "Your account status is currently pending activation.": "您的账号当前状态为待激活", - "Your browser does not support the audio tag.": "", - "Your browser does not support the video tag.": "", + "Your browser does not support the audio tag.": "您的浏览器不支持播放音频。", + "Your browser does not support the video tag.": "您的浏览器不支持播放视频。", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "您的全部捐款将直接给到插件开发者,Open WebUI 不会收取任何分成。但众筹平台可能会有服务费。", "Your message text or inputs": "您的消息文本或输入", "Your usage stats have been successfully synced.": "已成功同步您的使用统计数据。", diff --git a/src/lib/i18n/locales/zh-TW/translation.json b/src/lib/i18n/locales/zh-TW/translation.json index 996b4d48da..eba4340e1b 100644 --- a/src/lib/i18n/locales/zh-TW/translation.json +++ b/src/lib/i18n/locales/zh-TW/translation.json @@ -282,7 +282,7 @@ "Character limit for autocomplete generation input": "自動完成產生輸入的字元限制", "Chart new frontiers": "探索新領域", "Chat": "對話", - "Chat archived.": "", + "Chat archived.": "對話已封存。", "Chat Background Image": "對話背景圖片", "Chat Bubble UI": "對話氣泡介面", "Chat Completions": "對話續寫", @@ -823,7 +823,7 @@ "Fade Effect for Streaming Text": "串流文字淡入效果", "Failed to add file.": "新增檔案失敗。", "Failed to add members": "新增成員失敗", - "Failed to archive chat.": "", + "Failed to archive chat.": "封存對話失敗。", "Failed to attach file": "檔案上傳失敗", "Failed to clear status": "清除狀態失敗", "Failed to connect to {{URL}} OpenAPI tool server": "無法連線至 {{URL}} OpenAPI 工具伺服器", @@ -838,11 +838,11 @@ "Failed to generate title": "產生標題失敗", "Failed to import models": "匯入模型失敗", "Failed to load chat preview": "對話預覽載入失敗", - "Failed to load DOCX file. Please try downloading it instead.": "", + "Failed to load DOCX file. Please try downloading it instead.": "無法載入 DOCX 檔案,請改為下載後再開啟。", "Failed to load Excel/CSV file. Please try downloading it instead.": "無法載入 Excel/CSV 檔案。請嘗試直接下載檔案。", "Failed to load file content.": "載入檔案內容失敗。", "Failed to load Interface settings": "「介面設定」資料載入失敗", - "Failed to load PPTX file. Please try downloading it instead.": "", + "Failed to load PPTX file. Please try downloading it instead.": "無法載入 PPTX 檔案,請改為下載後再開啟。", "Failed to move chat": "移動對話失敗", "Failed to process URL: {{url}}": "處理連結失敗:{{url}}", "Failed to read clipboard contents": "讀取剪貼簿內容失敗", @@ -1261,7 +1261,7 @@ "More options": "更多選項", "More Options": "更多選項", "Move": "移動", - "Moved {{name}}": "", + "Moved {{name}}": "已移動 {{name}}", "My Terminal": "我的終端", "Name": "名稱", "Name and ID are required, please fill them out": "名稱和 ID 為必填項目,請填寫", @@ -1309,7 +1309,7 @@ "No history available": "暫無歷史紀錄", "No HTML, CSS, or JavaScript content found.": "未找到 HTML、CSS 或 JavaScript 內容。", "No inference engine with management support found": "未找到支援管理功能的推理引擎", - "No kernel": "", + "No kernel": "無核心", "No knowledge bases found.": "未找到知識庫", "No knowledge found": "未找到知識", "No memories to clear": "沒有記憶可清除", @@ -1325,7 +1325,7 @@ "No results": "沒有結果", "No results found": "未找到任何結果", "No search query generated": "未產生搜尋查詢", - "No servers detected": "", + "No servers detected": "未偵測到伺服器", "No skills found": "找不到任何技能", "No source available": "無可用來源", "No sources found": "未找到任何來源", @@ -1481,7 +1481,7 @@ "Please select at least one user for Direct Message channel.": "請至少選擇一位使用者以建立直接訊息頻道。", "Please wait until all files are uploaded.": "請等待所有檔案上傳完畢。", "Port": "連接埠", - "Ports": "", + "Ports": "連接埠", "Positive attitude": "積極的態度", "Prefer not to say": "不想透露", "Prefix ID": "前置 ID", @@ -1577,8 +1577,8 @@ "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "無法啟用回應通知,因為網站權限已遭拒。請前往瀏覽器設定以授予必要存取權限。", "Response splitting": "回應分割", "Response Watermark": "回應浮水印", - "Responses": "回答", - "Restart": "", + "Responses": "Responses", + "Restart": "重新啟動", "Result": "結果", "RESULT": "結果", "Retrieval": "檢索", @@ -1590,7 +1590,7 @@ "Role": "角色", "RTL": "從右到左", "Run": "執行", - "Run All": "", + "Run All": "全部執行", "Running": "正在執行", "Running...": "正在執行...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "同時執行嵌入任務以加快處理速度。如果遇到速率限制問題,請關閉此功能。", @@ -1781,7 +1781,7 @@ "Start a new conversation": "開始新對話", "Start of the channel": "頻道起點", "Start Tag": "起始標籤", - "Starting kernel...": "", + "Starting kernel...": "正在啟動核心…", "Status": "狀態", "Status cleared successfully": "狀態已清除", "Status updated successfully": "狀態已更新", @@ -2126,8 +2126,8 @@ "You're now logged in.": "您已登入。", "Your Account": "您的帳號", "Your account status is currently pending activation.": "您的帳號目前正在等待啟用。", - "Your browser does not support the audio tag.": "", - "Your browser does not support the video tag.": "", + "Your browser does not support the audio tag.": "您的瀏覽器不支援音訊播放。", + "Your browser does not support the video tag.": "您的瀏覽器不支援影片播放。", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "您的所有貢獻將會直接交給外掛開發者;Open WebUI 不會收取任何抽成。然而,所選擇的贊助平臺可能有其自身的費用。", "Your message text or inputs": "您的訊息文字或輸入", "Your usage stats have been successfully synced.": "已成功同步您的使用統計資料。", From 5eb9b58488b42ab8dcfdcc003ecdc964b7f2e866 Mon Sep 17 00:00:00 2001 From: Shirasawa <764798966@qq.com> Date: Sun, 8 Mar 2026 06:51:56 +0800 Subject: [PATCH 0786/1854] feat: Avoid overview profile image squashed (#22261) --- src/lib/components/chat/Overview/Node.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/components/chat/Overview/Node.svelte b/src/lib/components/chat/Overview/Node.svelte index 0bf36bb918..17c5e51e0c 100644 --- a/src/lib/components/chat/Overview/Node.svelte +++ b/src/lib/components/chat/Overview/Node.svelte @@ -25,7 +25,7 @@
@@ -45,7 +45,7 @@
From 7820a311baee785abe2aaf6aef1304c6305ab3fe Mon Sep 17 00:00:00 2001 From: Shirasawa <764798966@qq.com> Date: Sun, 8 Mar 2026 06:53:28 +0800 Subject: [PATCH 0787/1854] fix: prevent message queue from overflowing screen (#22176) --- src/lib/components/chat/MessageInput.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index 5d5344592b..2cbd0d9557 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -1175,7 +1175,7 @@ {#if messageQueue.length > 0}
{#each messageQueue as queuedMessage (queuedMessage.id)} Date: Sat, 7 Mar 2026 16:59:06 -0600 Subject: [PATCH 0788/1854] refac --- backend/open_webui/utils/models.py | 87 ++++++++++++++---------------- 1 file changed, 41 insertions(+), 46 deletions(-) diff --git a/backend/open_webui/utils/models.py b/backend/open_webui/utils/models.py index 564100b14f..e67fa62295 100644 --- a/backend/open_webui/utils/models.py +++ b/backend/open_webui/utils/models.py @@ -149,63 +149,58 @@ async def get_all_models(request, refresh: bool = False, user: UserModel = None) ] custom_models = Models.get_all_models() + + # Single O(1) lookup: Ollama base names first, then exact IDs (exact wins). + model_lookup = {} + for model in models: + if model.get("owned_by") == "ollama": + model_lookup.setdefault(model["id"].split(":")[0], model) + model_lookup[model["id"]] = model + + existing_ids = {m["id"] for m in models} + for custom_model in custom_models: if custom_model.base_model_id is None: - # Applied directly to a base model - for model in models: - if custom_model.id == model["id"] or ( - model.get("owned_by") == "ollama" - and custom_model.id - == model["id"].split(":")[ - 0 - ] # Ollama may return model ids in different formats (e.g., 'llama3' vs. 'llama3:7b') - ): - if custom_model.is_active: - model["name"] = custom_model.name - model["info"] = custom_model.model_dump() + model = model_lookup.get(custom_model.id) - # Set action_ids and filter_ids - action_ids = [] - filter_ids = [] + if model: + if custom_model.is_active: + model["name"] = custom_model.name + model["info"] = custom_model.model_dump() - if "info" in model: - if "meta" in model["info"]: - action_ids.extend( - model["info"]["meta"].get("actionIds", []) - ) - filter_ids.extend( - model["info"]["meta"].get("filterIds", []) - ) + action_ids = [] + filter_ids = [] - if "params" in model["info"]: - # Remove params to avoid exposing sensitive info - del model["info"]["params"] + if "info" in model: + if "meta" in model["info"]: + action_ids.extend( + model["info"]["meta"].get("actionIds", []) + ) + filter_ids.extend( + model["info"]["meta"].get("filterIds", []) + ) - model["action_ids"] = action_ids - model["filter_ids"] = filter_ids - else: - models.remove(model) + if "params" in model["info"]: + del model["info"]["params"] - elif custom_model.is_active and ( - custom_model.id not in [model["id"] for model in models] - ): - # Custom model based on a base model + model["action_ids"] = action_ids + model["filter_ids"] = filter_ids + else: + models.remove(model) + + elif custom_model.is_active and custom_model.id not in existing_ids: owned_by = "openai" connection_type = None - pipe = None - for m in models: - if ( - custom_model.base_model_id == m["id"] - or custom_model.base_model_id == m["id"].split(":")[0] - ): - owned_by = m.get("owned_by", "unknown") - if "pipe" in m: - pipe = m["pipe"] - - connection_type = m.get("connection_type", None) - break + base_model = model_lookup.get(custom_model.base_model_id) + if base_model is None: + base_model = model_lookup.get(custom_model.base_model_id.split(":")[0]) + if base_model: + owned_by = base_model.get("owned_by", "unknown") + if "pipe" in base_model: + pipe = base_model["pipe"] + connection_type = base_model.get("connection_type", None) model = { "id": f"{custom_model.id}", From 03c6caac1fc8625f85cf1164f5a977be8005c1bc Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 17:02:02 -0600 Subject: [PATCH 0789/1854] refac --- backend/open_webui/utils/models.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/backend/open_webui/utils/models.py b/backend/open_webui/utils/models.py index e67fa62295..96d1e363f1 100644 --- a/backend/open_webui/utils/models.py +++ b/backend/open_webui/utils/models.py @@ -151,17 +151,17 @@ async def get_all_models(request, refresh: bool = False, user: UserModel = None) custom_models = Models.get_all_models() # Single O(1) lookup: Ollama base names first, then exact IDs (exact wins). - model_lookup = {} + base_model_lookup = {} for model in models: if model.get("owned_by") == "ollama": - model_lookup.setdefault(model["id"].split(":")[0], model) - model_lookup[model["id"]] = model + base_model_lookup.setdefault(model["id"].split(":")[0], model) + base_model_lookup[model["id"]] = model existing_ids = {m["id"] for m in models} for custom_model in custom_models: if custom_model.base_model_id is None: - model = model_lookup.get(custom_model.id) + model = base_model_lookup.get(custom_model.id) if model: if custom_model.is_active: @@ -188,14 +188,17 @@ async def get_all_models(request, refresh: bool = False, user: UserModel = None) else: models.remove(model) - elif custom_model.is_active and custom_model.id not in existing_ids: + elif custom_model.is_active: + if custom_model.id in existing_ids: + continue + owned_by = "openai" connection_type = None pipe = None - base_model = model_lookup.get(custom_model.base_model_id) + base_model = base_model_lookup.get(custom_model.base_model_id) if base_model is None: - base_model = model_lookup.get(custom_model.base_model_id.split(":")[0]) + base_model = base_model_lookup.get(custom_model.base_model_id.split(":")[0]) if base_model: owned_by = base_model.get("owned_by", "unknown") if "pipe" in base_model: From e6b00a8905f0f855a1745b7a94d264ae6f80ff7f Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 17:03:23 -0600 Subject: [PATCH 0790/1854] refac --- backend/open_webui/utils/models.py | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/open_webui/utils/models.py b/backend/open_webui/utils/models.py index 96d1e363f1..cb5865d88c 100644 --- a/backend/open_webui/utils/models.py +++ b/backend/open_webui/utils/models.py @@ -161,6 +161,7 @@ async def get_all_models(request, refresh: bool = False, user: UserModel = None) for custom_model in custom_models: if custom_model.base_model_id is None: + # Override applied directly to a base model (shares the same ID) model = base_model_lookup.get(custom_model.id) if model: From 626fcff417afba642f4f71e0498267a21435c524 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 17:06:30 -0600 Subject: [PATCH 0791/1854] refac --- src/lib/components/chat/Chat.svelte | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index 7d5e131d26..b510dd0b65 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -934,15 +934,19 @@ } }; - $: if (history) { - cancelAnimationFrame(contentsRAF); - contentsRAF = requestAnimationFrame(() => { - getContents(); - contentsRAF = null; - }); - } else { - artifactContents.set([]); - } + const onHistoryChange = (history) => { + if (history) { + cancelAnimationFrame(contentsRAF); + contentsRAF = requestAnimationFrame(() => { + getContents(); + contentsRAF = null; + }); + } else { + artifactContents.set([]); + } + }; + + $: onHistoryChange(history); const getContents = () => { const messages = history ? createMessagesList(history, history.currentId) : []; From 42ecdb5407bec6d0718bc749b3e84e51f3815c21 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 17:11:44 -0600 Subject: [PATCH 0792/1854] refac --- src/lib/components/chat/Artifacts.svelte | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lib/components/chat/Artifacts.svelte b/src/lib/components/chat/Artifacts.svelte index 4d2c8af816..7e0bdf2060 100644 --- a/src/lib/components/chat/Artifacts.svelte +++ b/src/lib/components/chat/Artifacts.svelte @@ -98,15 +98,18 @@ }); const unsubscribeArtifactContents = artifactContents.subscribe((value) => { - contents = value; - console.log('Artifact contents updated:', contents); + const newContents = value ?? []; + console.log('Artifact contents updated:', newContents); - if (contents.length === 0) { + if (newContents.length === 0) { showControls.set(false); showArtifacts.set(false); + selectedContentIdx = 0; + } else if (newContents.length > contents.length) { + selectedContentIdx = newContents.length - 1; } - selectedContentIdx = contents ? contents.length - 1 : 0; + contents = newContents; }); return () => { From 2108f420eaafe936742e97731e8647c105ea4900 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 8 Mar 2026 00:12:22 +0100 Subject: [PATCH 0793/1854] chore: dep bump (#22305) * chore: dep bump * revert: Brotli dependency bump (1.2.0 -> 1.1.0) --- backend/requirements-min.txt | 18 ++++---- backend/requirements.txt | 79 ++++++++++++++++++------------------ pyproject.toml | 56 ++++++++++++------------- 3 files changed, 76 insertions(+), 77 deletions(-) diff --git a/backend/requirements-min.txt b/backend/requirements-min.txt index 6d28dc16d9..13bd199f08 100644 --- a/backend/requirements-min.txt +++ b/backend/requirements-min.txt @@ -1,8 +1,8 @@ # Minimal requirements for backend to run # WIP: use this as a reference to build a minimal docker image -fastapi==0.128.5 -uvicorn[standard]==0.40.0 +fastapi==0.135.1 +uvicorn[standard]==0.41.0 pydantic==2.12.5 python-multipart==0.0.22 itsdangerous==2.2.0 @@ -13,7 +13,7 @@ cryptography bcrypt==5.0.0 argon2-cffi==25.1.0 PyJWT[crypto]==2.11.0 -authlib==1.6.7 +authlib==1.6.9 requests==2.32.5 aiohttp==3.13.2 # do not update to 3.13.3 - broken @@ -25,12 +25,12 @@ Brotli==1.1.0 httpx[socks,http2,zstd,cli,brotli]==0.28.1 starsessions[redis]==2.2.1 -sqlalchemy==2.0.46 -alembic==1.18.3 +sqlalchemy==2.0.48 +alembic==1.18.4 peewee==3.19.0 peewee-migrate==1.14.3 -pycrdt==0.12.46 +pycrdt==0.12.47 redis APScheduler==3.11.2 @@ -42,14 +42,14 @@ asgiref==3.11.1 mcp==1.26.0 openai -langchain==1.2.9 +langchain==1.2.10 langchain-community==0.4.1 langchain-classic==1.0.1 -langchain-text-splitters==1.1.0 +langchain-text-splitters==1.1.1 fake-useragent==2.2.0 -chromadb==1.4.1 +chromadb==1.5.2 black==26.1.0 pydub chardet==5.2.0 diff --git a/backend/requirements.txt b/backend/requirements.txt index 06fb3b8194..3d3a54965d 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -1,5 +1,5 @@ -fastapi==0.128.5 -uvicorn[standard]==0.40.0 +fastapi==0.135.1 +uvicorn[standard]==0.41.0 pydantic==2.12.5 python-multipart==0.0.22 itsdangerous==2.2.0 @@ -10,7 +10,7 @@ cryptography bcrypt==5.0.0 argon2-cffi==25.1.0 PyJWT[crypto]==2.11.0 -authlib==1.6.7 +authlib==1.6.9 requests==2.32.5 aiohttp==3.13.2 # do not update to 3.13.3 - broken @@ -23,17 +23,17 @@ httpx[socks,http2,zstd,cli,brotli]==0.28.1 starsessions[redis]==2.2.1 python-mimeparse==2.0.0 -sqlalchemy==2.0.46 -alembic==1.18.3 +sqlalchemy==2.0.48 +alembic==1.18.4 peewee==3.19.0 peewee-migrate==1.14.3 -pycrdt==0.12.46 +pycrdt==0.12.47 redis APScheduler==3.11.2 RestrictedPython==8.1 -pytz==2025.2 +pytz==2026.1.post1 loguru==0.7.3 asgiref==3.11.1 @@ -44,38 +44,38 @@ mcp==1.26.0 openai anthropic -google-genai==1.62.0 +google-genai==1.66.0 -langchain==1.2.9 +langchain==1.2.10 langchain-community==0.4.1 langchain-classic==1.0.1 -langchain-text-splitters==1.1.0 +langchain-text-splitters==1.1.1 fake-useragent==2.2.0 -chromadb==1.4.1 -weaviate-client==4.19.2 +chromadb==1.5.2 +weaviate-client==4.20.3 opensearch-py==3.1.0 -transformers==5.1.0 -sentence-transformers==5.2.2 +transformers==5.3.0 +sentence-transformers==5.2.3 accelerate pyarrow==20.0.0 # fix: pin pyarrow version to 20 for rpi compatibility #15897 einops==0.8.2 ftfy==6.3.1 chardet==5.2.0 -pypdf==6.7.0 -fpdf2==2.8.5 -pymdown-extensions==10.20.1 +pypdf==6.7.5 +fpdf2==2.8.7 +pymdown-extensions==10.21 docx2txt==0.9 python-pptx==1.0.2 unstructured==0.18.31 msoffcrypto-tool==6.0.0 -nltk==3.9.2 -Markdown==3.10.1 +nltk==3.9.3 +Markdown==3.10.2 beautifulsoup4 pypandoc==1.16.2 -pandas==3.0.0 +pandas==3.0.1 openpyxl==3.1.5 pyxlsb==1.0.10 xlrd==2.0.2 @@ -84,12 +84,12 @@ psutil sentencepiece soundfile==0.13.1 -pillow==12.1.0 +pillow==12.1.1 opencv-python-headless==4.13.0.92 rapidocr-onnxruntime==1.4.4 rank-bm25==0.2.2 -onnxruntime==1.24.1 +onnxruntime==1.24.3 faster-whisper==1.2.1 black==26.1.0 @@ -97,10 +97,10 @@ youtube-transcript-api==1.2.4 pytube==15.0.0 pydub -ddgs==9.10.0 +ddgs==9.11.2 azure-ai-documentintelligence==1.0.2 -azure-identity==1.25.1 +azure-identity==1.25.2 azure-storage-blob==12.28.0 azure-search-documents==11.6.0 @@ -118,10 +118,10 @@ psycopg2-binary==2.9.11 pgvector==0.4.2 PyMySQL==1.1.2 -boto3==1.42.44 +boto3==1.42.62 -pymilvus==2.6.8 -qdrant-client==1.16.2 +pymilvus==2.6.9 +qdrant-client==1.17.0 playwright==1.58.0 # Caution: version must match docker-compose.playwright.yaml - Update the docker-compose.yaml if necessary elasticsearch==9.3.0 pinecone==6.0.2 @@ -141,18 +141,17 @@ pytest-docker~=3.2.5 ldap3==2.9.1 ## Firecrawl -firecrawl-py==4.14.0 +firecrawl-py==4.18.0 ## Trace -opentelemetry-api==1.39.1 -opentelemetry-sdk==1.39.1 -opentelemetry-exporter-otlp==1.39.1 -opentelemetry-instrumentation==0.60b1 -opentelemetry-instrumentation-fastapi==0.60b1 -opentelemetry-instrumentation-sqlalchemy==0.60b1 -opentelemetry-instrumentation-redis==0.60b1 -opentelemetry-instrumentation-requests==0.60b1 -opentelemetry-instrumentation-logging==0.60b1 -opentelemetry-instrumentation-httpx==0.60b1 -opentelemetry-instrumentation-aiohttp-client==0.60b1 -opentelemetry-instrumentation-system-metrics==0.60b1 +opentelemetry-api==1.40.0 +opentelemetry-sdk==1.40.0 +opentelemetry-exporter-otlp==1.40.0 +opentelemetry-instrumentation==0.61b0 +opentelemetry-instrumentation-fastapi==0.61b0 +opentelemetry-instrumentation-sqlalchemy==0.61b0 +opentelemetry-instrumentation-redis==0.61b0 +opentelemetry-instrumentation-requests==0.61b0 +opentelemetry-instrumentation-logging==0.61b0 +opentelemetry-instrumentation-httpx==0.61b0 +opentelemetry-instrumentation-aiohttp-client==0.61b0 diff --git a/pyproject.toml b/pyproject.toml index d240449dff..251240ac48 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,8 +6,8 @@ authors = [ ] license = { file = "LICENSE" } dependencies = [ - "fastapi==0.128.5", - "uvicorn[standard]==0.40.0", + "fastapi==0.135.1", + "uvicorn[standard]==0.41.0", "pydantic==2.12.5", "python-multipart==0.0.22", "itsdangerous==2.2.0", @@ -18,7 +18,7 @@ dependencies = [ "bcrypt==5.0.0", "argon2-cffi==25.1.0", "PyJWT[crypto]==2.11.0", - "authlib==1.6.7", + "authlib==1.6.9", "requests==2.32.5", "aiohttp==3.13.2", # do not update to 3.13.3 - broken @@ -31,15 +31,15 @@ dependencies = [ "starsessions[redis]==2.2.1", "python-mimeparse==2.0.0", - "sqlalchemy==2.0.46", - "alembic==1.18.3", + "sqlalchemy==2.0.48", + "alembic==1.18.4", "peewee==3.19.0", "peewee-migrate==1.14.3", - "pycrdt==0.12.46", + "pycrdt==0.12.47", "redis", - "pytz==2025.2", + "pytz==2026.1.post1", "APScheduler==3.11.2", "RestrictedPython==8.1", @@ -51,38 +51,38 @@ dependencies = [ "openai", "anthropic", - "google-genai==1.62.0", + "google-genai==1.66.0", - "langchain==1.2.9", + "langchain==1.2.10", "langchain-community==0.4.1", "langchain-classic==1.0.1", - "langchain-text-splitters==1.1.0", + "langchain-text-splitters==1.1.1", "fake-useragent==2.2.0", - "chromadb==1.4.1", + "chromadb==1.5.2", "opensearch-py==3.1.0", "PyMySQL==1.1.2", - "boto3==1.42.44", + "boto3==1.42.62", - "transformers==5.1.0", - "sentence-transformers==5.2.2", + "transformers==5.3.0", + "sentence-transformers==5.2.3", "accelerate", "pyarrow==20.0.0", # fix: pin pyarrow version to 20 for rpi compatibility #15897 "einops==0.8.2", "ftfy==6.3.1", "chardet==5.2.0", - "pypdf==6.7.0", - "fpdf2==2.8.5", - "pymdown-extensions==10.20.1", + "pypdf==6.7.5", + "fpdf2==2.8.7", + "pymdown-extensions==10.21", "docx2txt==0.9", "python-pptx==1.0.2", "unstructured==0.18.31", "msoffcrypto-tool==6.0.0", - "nltk==3.9.2", - "Markdown==3.10.1", + "nltk==3.9.3", + "Markdown==3.10.2", "pypandoc==1.16.2", - "pandas==3.0.0", + "pandas==3.0.1", "openpyxl==3.1.5", "pyxlsb==1.0.10", "xlrd==2.0.2", @@ -92,12 +92,12 @@ dependencies = [ "soundfile==0.13.1", "azure-ai-documentintelligence==1.0.2", - "pillow==12.1.0", + "pillow==12.1.1", "opencv-python-headless==4.13.0.92", "rapidocr-onnxruntime==1.4.4", "rank-bm25==0.2.2", - "onnxruntime==1.24.1", + "onnxruntime==1.24.3", "faster-whisper==1.2.1", "black==26.1.0", @@ -105,7 +105,7 @@ dependencies = [ "pytube==15.0.0", "pydub", - "ddgs==9.10.0", + "ddgs==9.11.2", "google-api-python-client", "google-auth-httplib2", @@ -114,7 +114,7 @@ dependencies = [ "googleapis-common-protos==1.72.0", "google-cloud-storage==3.9.0", - "azure-identity==1.25.1", + "azure-identity==1.25.2", "azure-storage-blob==12.28.0", "ldap3==2.9.1", @@ -150,15 +150,15 @@ all = [ "playwright==1.58.0", # Caution: version must match docker-compose.playwright.yaml - Update the docker-compose.yaml if necessary "elasticsearch==9.3.0", - "qdrant-client==1.16.2", + "qdrant-client==1.17.0", - "weaviate-client==4.19.2", - "pymilvus==2.6.8", + "weaviate-client==4.20.3", + "pymilvus==2.6.9", "pinecone==6.0.2", "oracledb==3.4.2", "colbert-ai==0.2.22", - "firecrawl-py==4.14.0", + "firecrawl-py==4.18.0", "azure-search-documents==11.6.0", ] From d4faa5a5eafe4159dc46aa1d19a7477401e5e7e9 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 17:13:19 -0600 Subject: [PATCH 0794/1854] refac --- backend/open_webui/tools/builtin.py | 8 ++++++-- backend/open_webui/utils/middleware.py | 11 +++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/backend/open_webui/tools/builtin.py b/backend/open_webui/tools/builtin.py index 7427592380..fe20555f9d 100644 --- a/backend/open_webui/tools/builtin.py +++ b/backend/open_webui/tools/builtin.py @@ -249,11 +249,13 @@ async def generate_image( # Persist files to DB if chat context is available if __chat_id__ and __message_id__ and images: - image_files = Chats.add_message_files_by_id_and_message_id( + db_files = Chats.add_message_files_by_id_and_message_id( __chat_id__, __message_id__, image_files, ) + if db_files is not None: + image_files = db_files # Emit the images to the UI if event emitter is available if __event_emitter__ and image_files: @@ -314,11 +316,13 @@ async def edit_image( # Persist files to DB if chat context is available if __chat_id__ and __message_id__ and images: - image_files = Chats.add_message_files_by_id_and_message_id( + db_files = Chats.add_message_files_by_id_and_message_id( __chat_id__, __message_id__, image_files, ) + if db_files is not None: + image_files = db_files # Emit the images to the UI if event emitter is available if __event_emitter__ and image_files: diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 27323742a4..f3d5d6821c 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -3777,14 +3777,17 @@ async def streaming_chat_response_handler(response, ctx): delta.get("images", []), request, metadata, user ) if image_urls: + image_file_list = [ + {"type": "image", "url": url} + for url in image_urls + ] message_files = Chats.add_message_files_by_id_and_message_id( metadata["chat_id"], metadata["message_id"], - [ - {"type": "image", "url": url} - for url in image_urls - ], + image_file_list, ) + if message_files is None: + message_files = image_file_list await event_emitter( { From dfa25111993c9e26e8ec7ed40214d13eb3887c1e Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 8 Mar 2026 00:17:36 +0100 Subject: [PATCH 0795/1854] fix: persist token usage data for non-streaming chat responses (#22166) The non-streaming response handler was saving assistant messages without their usage/token data. While the streaming handler correctly extracted and saved usage information, the non-streaming path discarded it entirely. This caused assistant messages from non-streaming completions to have NULL usage in the chat_message table, making them invisible to the analytics token aggregation queries and contributing to the '0 tokens' display in Admin Panel Analytics. Extract and normalize the usage data from the API response and include it in the database upsert, matching the pattern already used by the streaming handler. --- backend/open_webui/utils/middleware.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index f3d5d6821c..e5e75652a8 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -3093,6 +3093,9 @@ async def non_streaming_chat_response_handler(response, ctx): ) # Save message in the database + raw_usage = response_data.get("usage", {}) or {} + usage = normalize_usage(raw_usage) if raw_usage else None + Chats.upsert_message_to_chat_by_id_and_message_id( metadata["chat_id"], metadata["message_id"], @@ -3100,6 +3103,7 @@ async def non_streaming_chat_response_handler(response, ctx): "role": "assistant", "content": content, "output": response_output, + **({"usage": usage} if usage else {}), }, ) From b04de83c20ac7dab4bf9c689e1ffc3fe22238b30 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 17:18:46 -0600 Subject: [PATCH 0796/1854] refac --- backend/open_webui/utils/middleware.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index e5e75652a8..b5cf97d713 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -3093,8 +3093,7 @@ async def non_streaming_chat_response_handler(response, ctx): ) # Save message in the database - raw_usage = response_data.get("usage", {}) or {} - usage = normalize_usage(raw_usage) if raw_usage else None + usage = normalize_usage(response_data.get("usage", {}) or {}) Chats.upsert_message_to_chat_by_id_and_message_id( metadata["chat_id"], @@ -4468,7 +4467,8 @@ async def streaming_chat_response_handler(response, ctx): code = sanitize_code(code) if CODE_INTERPRETER_BLOCKED_MODULES: - blocking_code = textwrap.dedent(f""" + blocking_code = textwrap.dedent( + f""" import builtins BLOCKED_MODULES = {CODE_INTERPRETER_BLOCKED_MODULES} @@ -4484,7 +4484,8 @@ async def streaming_chat_response_handler(response, ctx): return _real_import(name, globals, locals, fromlist, level) builtins.__import__ = restricted_import - """) + """ + ) code = blocking_code + "\n" + code if ( From 7cdff6b1e25692a27cc1c2a1896cb64f3b6071aa Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 17:24:17 -0600 Subject: [PATCH 0797/1854] refac --- backend/open_webui/utils/middleware.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index b5cf97d713..1f2718ae7f 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -173,6 +173,9 @@ def get_citation_source_from_tool_result( Returns a list of sources (usually one, but query_knowledge_files may return multiple). """ + _EXPECTS_LIST = {"search_web", "query_knowledge_files"} + _EXPECTS_DICT = {"view_knowledge_file"} + try: try: tool_result = json.loads(tool_result) @@ -181,6 +184,12 @@ def get_citation_source_from_tool_result( if isinstance(tool_result, dict) and "error" in tool_result: return [] + # Validate tool_result type based on what the branch expects + if tool_name in _EXPECTS_LIST and not isinstance(tool_result, list): + return [] + elif tool_name in _EXPECTS_DICT and not isinstance(tool_result, dict): + return [] + if tool_name == "search_web": # Parse JSON array: [{"title": "...", "link": "...", "snippet": "..."}] results = tool_result From bc5d519c4f7265dac195d14047de8d08f9ece370 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 17:29:24 -0600 Subject: [PATCH 0798/1854] refac --- backend/open_webui/utils/tools.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/utils/tools.py b/backend/open_webui/utils/tools.py index 2c4b983bd8..7c55429072 100644 --- a/backend/open_webui/utils/tools.py +++ b/backend/open_webui/utils/tools.py @@ -1186,7 +1186,7 @@ async def get_tool_servers_data(servers: List[Dict[str, Any]]) -> List[Dict[str, { "id": str(id), "idx": idx, - "url": server.get("url"), + "url": (server.get("url") or "").rstrip("/"), "openapi": openapi_data, "info": response.get("info"), "specs": response.get("specs"), @@ -1250,7 +1250,7 @@ async def execute_tool_server( if params[param_name] is not None: query_params[param_name] = params[param_name] - final_url = f"{url}{route_path}" + final_url = f"{url.rstrip('/')}{route_path}" for key, value in path_params.items(): final_url = final_url.replace(f"{{{key}}}", str(value)) @@ -1320,6 +1320,8 @@ def get_tool_server_url(url: Optional[str], path: str) -> str: if "://" in path: # If it contains "://", it's a full URL return path + if url: + url = url.rstrip("/") if not path.startswith("/"): # Ensure the path starts with a slash path = f"/{path}" From e303c3da3b174da9e92a79b174f85ba574ca06ef Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 17:45:00 -0600 Subject: [PATCH 0799/1854] refac: inline codespan rich text input Co-Authored-By: Abdul Moiz <86627657+abdulmoizjawed@users.noreply.github.com> --- package-lock.json | 29 ++++++++++--------- package.json | 3 +- .../components/common/RichTextInput.svelte | 22 +++++++++++++- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 45f1f53721..8f5599767c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "@sveltejs/svelte-virtual-list": "^3.0.1", "@tiptap/core": "^3.0.7", "@tiptap/extension-bubble-menu": "^2.26.1", + "@tiptap/extension-code": "^3.0.7", "@tiptap/extension-code-block-lowlight": "^3.0.7", "@tiptap/extension-drag-handle": "^3.4.5", "@tiptap/extension-file-handler": "^3.0.7", @@ -3369,9 +3370,9 @@ } }, "node_modules/@tiptap/extension-collaboration": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-collaboration/-/extension-collaboration-3.20.0.tgz", - "integrity": "sha512-JItmI4U0i4kqorO114u24hM9k945IdaQ6Uc2DEtPBFFuS8cepJf2zw+ulAT1kAx6ZRiNvNpT9M7w+J0mWRn+Sg==", + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-collaboration/-/extension-collaboration-3.20.1.tgz", + "integrity": "sha512-JnwLvyzrutBffHp6YPnf0XyTnhAgqZ9D8JSUKFp0edvai+dxsb+UMlawesBrgAuoQXw3B8YZUo2VFDVdKas1xQ==", "license": "MIT", "peer": true, "funding": { @@ -3379,8 +3380,8 @@ "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.20.0", - "@tiptap/pm": "^3.20.0", + "@tiptap/core": "^3.20.1", + "@tiptap/pm": "^3.20.1", "@tiptap/y-tiptap": "^3.0.2", "yjs": "^13" } @@ -3628,9 +3629,9 @@ } }, "node_modules/@tiptap/extension-node-range": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-node-range/-/extension-node-range-3.20.0.tgz", - "integrity": "sha512-XeKKTV88VuJ4Mh0Rxvc/PPzG76cb44sE+rB4u0J/ms63R/WFTm6yJQlCgUVGnGeHleSlrWuZY8gGSuoljmQzqg==", + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-node-range/-/extension-node-range-3.20.1.tgz", + "integrity": "sha512-+W/mQJxlkXMcwldWUqwdoR0eniJ1S9cVJoAy2Lkis0NhILZDWVNGKl9J4WFoCOXn8Myr17IllIxRYvAXJJ4FHQ==", "license": "MIT", "peer": true, "funding": { @@ -3638,8 +3639,8 @@ "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.20.0", - "@tiptap/pm": "^3.20.0" + "@tiptap/core": "^3.20.1", + "@tiptap/pm": "^3.20.1" } }, "node_modules/@tiptap/extension-ordered-list": { @@ -3709,9 +3710,9 @@ } }, "node_modules/@tiptap/extension-text-style": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-3.20.0.tgz", - "integrity": "sha512-zyWW1a6W+kaXAn3wv2svJ1XuVMapujftvH7Xn2Q3QmKKiDkO+NiFkrGe8BhMopu8Im51nO3NylIgVA0X1mS1rQ==", + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-3.20.1.tgz", + "integrity": "sha512-3LQU92zX6tzl47EBskkAKeJXd6EWwYmBDE7jbd7InJqnt9NMAcj4DtXtXpI+e6Un5+8yzNjVA+fI5+5cFS3dSg==", "license": "MIT", "peer": true, "funding": { @@ -3719,7 +3720,7 @@ "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.20.0" + "@tiptap/core": "^3.20.1" } }, "node_modules/@tiptap/extension-typography": { diff --git a/package.json b/package.json index 74a2e04992..0e30237aee 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "@sveltejs/svelte-virtual-list": "^3.0.1", "@tiptap/core": "^3.0.7", "@tiptap/extension-bubble-menu": "^2.26.1", + "@tiptap/extension-code": "^3.0.7", "@tiptap/extension-code-block-lowlight": "^3.0.7", "@tiptap/extension-drag-handle": "^3.4.5", "@tiptap/extension-file-handler": "^3.0.7", @@ -157,4 +158,4 @@ "node": ">=18.13.0 <=22.x.x", "npm": ">=6.0.0" } -} +} \ No newline at end of file diff --git a/src/lib/components/common/RichTextInput.svelte b/src/lib/components/common/RichTextInput.svelte index aea8ca7191..07bc4680ea 100644 --- a/src/lib/components/common/RichTextInput.svelte +++ b/src/lib/components/common/RichTextInput.svelte @@ -114,7 +114,7 @@ import { Fragment, DOMParser } from 'prosemirror-model'; import { EditorState, Plugin, PluginKey, TextSelection, Selection } from 'prosemirror-state'; import { Decoration, DecorationSet } from 'prosemirror-view'; - import { Editor, Extension, mergeAttributes } from '@tiptap/core'; + import { Editor, Extension, markInputRule, mergeAttributes } from '@tiptap/core'; import { AIAutocompletion } from './RichTextInput/AutoCompletion.js'; @@ -135,8 +135,26 @@ import FileHandler from '@tiptap/extension-file-handler'; import Typography from '@tiptap/extension-typography'; import Highlight from '@tiptap/extension-highlight'; + import Code from '@tiptap/extension-code'; import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight'; + // WORKAROUND: TipTap's default Code mark input rule regex captures the + // character before the opening backtick, causing it to be deleted. + // This uses a lookbehind assertion instead so the preceding character is + // matched for position but not captured/deleted. + // Upstream fix: https://github.com/ueberdosis/tiptap/pull/7124 + const backtickInputRegex = /(?<=\s|^)`([^`]+)`(?!`)$/; + const FixedCode = Code.extend({ + addInputRules() { + return [ + markInputRule({ + find: backtickInputRegex, + type: this.type + }) + ]; + } + }); + import Mention from '@tiptap/extension-mention'; import FormattingButtons from './RichTextInput/FormattingButtons.svelte'; @@ -692,12 +710,14 @@ extensions: [ StarterKit.configure({ link: link, + code: false, // Disabled in favor of FixedCode (see workaround above) // When rich text is off, disable Strike from StarterKit so we can // re-add it below without its Mod-Shift-s shortcut (which conflicts // with the Toggle Sidebar shortcut). When rich text is on, the user // can undo strikethrough via the toolbar, so the shortcut is fine. ...(richText ? {} : { strike: false }) }), + FixedCode, ...(dragHandle ? [ListItemDragHandle] : []), Placeholder.configure({ placeholder: () => _placeholder, showOnlyWhenEditable: false }), SelectionDecoration, From 7b2f597b30c77ef300d1966e1c6a3edfdb0c465d Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 17:52:58 -0600 Subject: [PATCH 0800/1854] refac --- .../chat/MessageInput/InputVariablesModal.svelte | 6 ++++++ src/lib/components/common/RichTextInput.svelte | 13 ++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/lib/components/chat/MessageInput/InputVariablesModal.svelte b/src/lib/components/chat/MessageInput/InputVariablesModal.svelte index d2410ad80b..b50ed38395 100644 --- a/src/lib/components/chat/MessageInput/InputVariablesModal.svelte +++ b/src/lib/components/chat/MessageInput/InputVariablesModal.svelte @@ -21,6 +21,12 @@ let variableValues = {}; const submitHandler = async () => { + // Normalize Windows CRLF (\r\n) to LF (\n) for all string values + for (const key of Object.keys(variableValues)) { + if (typeof variableValues[key] === 'string') { + variableValues[key] = variableValues[key].replace(/\r\n/g, '\n'); + } + } onSave(variableValues); show = false; }; diff --git a/src/lib/components/common/RichTextInput.svelte b/src/lib/components/common/RichTextInput.svelte index 07bc4680ea..b9dd058553 100644 --- a/src/lib/components/common/RichTextInput.svelte +++ b/src/lib/components/common/RichTextInput.svelte @@ -485,6 +485,17 @@ focus(); }; + // Convert text to ProseMirror nodes, using hardBreak for newlines + const textToNodes = (state, text) => { + if (!text.includes('\n')) return state.schema.text(text); + const nodes = []; + text.split('\n').forEach((line, i) => { + if (i > 0) nodes.push(state.schema.nodes.hardBreak.create()); + if (line) nodes.push(state.schema.text(line)); + }); + return nodes; + }; + export const replaceVariables = (variables) => { if (!editor || !editor.view) return; const { state, view } = editor; @@ -519,7 +530,7 @@ // Apply replacements in reverse order to maintain correct positions replacements.reverse().forEach(({ from, to, text }) => { - tr = tr.replaceWith(from, to, text !== '' ? state.schema.text(text) : []); + tr = tr.replaceWith(from, to, text !== '' ? textToNodes(state, text) : []); }); // Only dispatch if there are changes From b4f340806a4a0157bdd258b5acaa89c8a048be07 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 8 Mar 2026 01:08:11 +0100 Subject: [PATCH 0801/1854] fix: migration streaming/batching (#21542) * fix: normalize usage tokens + migration streaming/batching - Migration: replace .fetchall() with yield_per streaming, replace per-message INSERT+SAVEPOINT with batched inserts (5k/batch) with fallback to row-by-row on error, add progress logging - Write path: call normalize_usage() in upsert_message() before saving to ensure input_tokens/output_tokens always present - Read path: analytics queries now COALESCE across input_tokens/prompt_tokens and output_tokens/completion_tokens so historical data with OpenAI-format keys is visible * fix: restore defensive timestamp conversion in migration Re-add try/except around int(float(timestamp)) that was accidentally dropped. Without this, a non-numeric timestamp string would cause a TypeError on the subsequent comparison, breaking the entire upgrade. * revert: remove changes to chat_messages.py --- .../8452d01d26d7_add_chat_message_table.py | 116 ++++++++++++------ 1 file changed, 78 insertions(+), 38 deletions(-) diff --git a/backend/open_webui/migrations/versions/8452d01d26d7_add_chat_message_table.py b/backend/open_webui/migrations/versions/8452d01d26d7_add_chat_message_table.py index 567f7d673a..ea95d08f12 100644 --- a/backend/open_webui/migrations/versions/8452d01d26d7_add_chat_message_table.py +++ b/backend/open_webui/migrations/versions/8452d01d26d7_add_chat_message_table.py @@ -21,6 +21,39 @@ down_revision: Union[str, None] = "374d2f66af06" branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None +BATCH_SIZE = 5000 + + +def _flush_batch(conn, table, batch): + """ + Insert a batch of messages, falling back to row-by-row on error. + + Tries a single bulk insert first (fast path). If that fails (e.g. due to + a duplicate key), falls back to individual inserts wrapped in savepoints + so the rest of the batch can still succeed. + """ + savepoint = conn.begin_nested() + try: + conn.execute(sa.insert(table), batch) + savepoint.commit() + return len(batch), 0 + except Exception: + savepoint.rollback() + # Batch failed - insert one-by-one to isolate the bad row(s) + inserted = 0 + failed = 0 + for msg in batch: + sp = conn.begin_nested() + try: + conn.execute(sa.insert(table).values(**msg)) + sp.commit() + inserted += 1 + except Exception as e: + sp.rollback() + failed += 1 + log.warning(f"Failed to insert message {msg['id']}: {e}") + return inserted, failed + def upgrade() -> None: # Step 1: Create table @@ -88,18 +121,21 @@ def upgrade() -> None: sa.column("updated_at", sa.BigInteger()), ) - # Fetch all chats (excluding shared chats which have user_id starting with 'shared-') - chats = conn.execute( + # Stream rows instead of loading all into memory: + # - yield_per: fetches rows in chunks via cursor.fetchmany() (all backends) + # - stream_results: enables server-side cursors on PostgreSQL (no-op on SQLite) + result = conn.execute( sa.select(chat_table.c.id, chat_table.c.user_id, chat_table.c.chat).where( ~chat_table.c.user_id.like("shared-%") - ) - ).fetchall() + ).execution_options(yield_per=1000, stream_results=True) + ) now = int(time.time()) - messages_inserted = 0 - messages_failed = 0 + messages_batch = [] + total_inserted = 0 + total_failed = 0 - for chat_row in chats: + for chat_row in result: chat_id = chat_row[0] user_id = chat_row[1] chat_data = chat_row[2] @@ -139,39 +175,43 @@ def upgrade() -> None: if timestamp < 1577836800 or timestamp > now + 86400: timestamp = now - # Use savepoint to allow individual insert failures without aborting transaction - savepoint = conn.begin_nested() - try: - conn.execute( - sa.insert(chat_message_table).values( - id=f"{chat_id}-{message_id}", - chat_id=chat_id, - user_id=user_id, - role=role, - parent_id=message.get("parentId"), - content=message.get("content"), - output=message.get("output"), - model_id=message.get("model"), - files=message.get("files"), - sources=message.get("sources"), - embeds=message.get("embeds"), - done=message.get("done", True), - status_history=message.get("statusHistory"), - error=message.get("error"), - created_at=timestamp, - updated_at=timestamp, - ) - ) - savepoint.commit() - messages_inserted += 1 - except Exception as e: - savepoint.rollback() - messages_failed += 1 - log.warning(f"Failed to insert message {message_id}: {e}") - continue + messages_batch.append({ + "id": f"{chat_id}-{message_id}", + "chat_id": chat_id, + "user_id": user_id, + "role": role, + "parent_id": message.get("parentId"), + "content": message.get("content"), + "output": message.get("output"), + "model_id": message.get("model"), + "files": message.get("files"), + "sources": message.get("sources"), + "embeds": message.get("embeds"), + "done": message.get("done", True), + "status_history": message.get("statusHistory"), + "error": message.get("error"), + "usage": message.get("usage"), + "created_at": timestamp, + "updated_at": timestamp, + }) + + # Flush batch when full + if len(messages_batch) >= BATCH_SIZE: + inserted, failed = _flush_batch(conn, chat_message_table, messages_batch) + total_inserted += inserted + total_failed += failed + if total_inserted % 50000 < BATCH_SIZE: + log.info(f"Migration progress: {total_inserted} messages inserted...") + messages_batch.clear() + + # Flush remaining messages + if messages_batch: + inserted, failed = _flush_batch(conn, chat_message_table, messages_batch) + total_inserted += inserted + total_failed += failed log.info( - f"Backfilled {messages_inserted} messages into chat_message table ({messages_failed} failed)" + f"Backfilled {total_inserted} messages into chat_message table ({total_failed} failed)" ) From 5d4505c68509242b72727e3493a5adb0f52a5530 Mon Sep 17 00:00:00 2001 From: pedro-inf-custodio <113921389+pedro-inf-custodio@users.noreply.github.com> Date: Sun, 8 Mar 2026 00:13:28 +0000 Subject: [PATCH 0802/1854] fix: add support for scope in OAuth refresh token request (#22359) * fix: add support for scope in OAuth refresh token request * add oauth refresh token include scope * Fix variable import * Fix env variables import * Added debug logs WIP * Remove debug logs --- backend/open_webui/config.py | 6 ++++++ backend/open_webui/utils/oauth.py | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index 512bfdf7aa..32dfdb7ca9 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -339,6 +339,12 @@ ENABLE_OAUTH_SIGNUP = PersistentConfig( os.environ.get("ENABLE_OAUTH_SIGNUP", "False").lower() == "true", ) +OAUTH_REFRESH_TOKEN_INCLUDE_SCOPE = PersistentConfig( + "OAUTH_REFRESH_TOKEN_INCLUDE_SCOPE", + "oauth.refresh_token_include_scope", + os.environ.get("OAUTH_REFRESH_TOKEN_INCLUDE_SCOPE", "False").lower() == "true", +) + OAUTH_MERGE_ACCOUNTS_BY_EMAIL = PersistentConfig( "OAUTH_MERGE_ACCOUNTS_BY_EMAIL", diff --git a/backend/open_webui/utils/oauth.py b/backend/open_webui/utils/oauth.py index 284917d22c..392ae74f96 100644 --- a/backend/open_webui/utils/oauth.py +++ b/backend/open_webui/utils/oauth.py @@ -36,6 +36,7 @@ from open_webui.models.groups import Groups, GroupModel, GroupUpdateForm, GroupF from open_webui.config import ( DEFAULT_USER_ROLE, ENABLE_OAUTH_SIGNUP, + OAUTH_REFRESH_TOKEN_INCLUDE_SCOPE, OAUTH_MERGE_ACCOUNTS_BY_EMAIL, OAUTH_PROVIDERS, ENABLE_OAUTH_ROLE_MANAGEMENT, @@ -113,6 +114,9 @@ log = logging.getLogger(__name__) auth_manager_config = AppConfig() auth_manager_config.DEFAULT_USER_ROLE = DEFAULT_USER_ROLE auth_manager_config.ENABLE_OAUTH_SIGNUP = ENABLE_OAUTH_SIGNUP +auth_manager_config.OAUTH_REFRESH_TOKEN_INCLUDE_SCOPE = ( + OAUTH_REFRESH_TOKEN_INCLUDE_SCOPE +) auth_manager_config.OAUTH_MERGE_ACCOUNTS_BY_EMAIL = OAUTH_MERGE_ACCOUNTS_BY_EMAIL auth_manager_config.ENABLE_OAUTH_ROLE_MANAGEMENT = ENABLE_OAUTH_ROLE_MANAGEMENT auth_manager_config.ENABLE_OAUTH_GROUP_MANAGEMENT = ENABLE_OAUTH_GROUP_MANAGEMENT @@ -787,6 +791,16 @@ class OAuthClientManager: if hasattr(client, "client_secret") and client.client_secret: refresh_data["client_secret"] = client.client_secret + # Add scope if available in client kwargs (some providers require it on refresh) + if ( + hasattr(client, "client_kwargs") + and client.client_kwargs.get("scope") + and getattr( + self.app.state.config, "OAUTH_REFRESH_TOKEN_INCLUDE_SCOPE", False + ) + ): + refresh_data["scope"] = client.client_kwargs["scope"] + # Make refresh request async with aiohttp.ClientSession(trust_env=True) as session_http: async with session_http.post( @@ -1081,6 +1095,14 @@ class OAuthManager: if hasattr(client, "client_secret") and client.client_secret: refresh_data["client_secret"] = client.client_secret + # Add scope if available in client kwargs (some providers require it on refresh) + if ( + hasattr(client, "client_kwargs") + and client.client_kwargs.get("scope") + and auth_manager_config.OAUTH_REFRESH_TOKEN_INCLUDE_SCOPE + ): + refresh_data["scope"] = client.client_kwargs["scope"] + # Make refresh request async with aiohttp.ClientSession(trust_env=True) as session_http: async with session_http.post( From 35bc8310772c222fd8a466f7d00113a84e0402d0 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 18:18:02 -0600 Subject: [PATCH 0803/1854] refac --- backend/open_webui/tools/builtin.py | 3 +++ backend/open_webui/utils/middleware.py | 1 + src/lib/utils/index.ts | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/backend/open_webui/tools/builtin.py b/backend/open_webui/tools/builtin.py index fe20555f9d..b438759e10 100644 --- a/backend/open_webui/tools/builtin.py +++ b/backend/open_webui/tools/builtin.py @@ -429,6 +429,9 @@ async def execute_code( "session_id": ( __metadata__.get("session_id") if __metadata__ else None ), + "files": ( + __metadata__.get("files", []) if __metadata__ else [] + ), }, } ) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 1f2718ae7f..a4ca8c3561 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -4510,6 +4510,7 @@ async def streaming_chat_response_handler(response, ctx): "session_id": metadata.get( "session_id", None ), + "files": metadata.get("files", []), }, } ) diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index 5a0f899ffc..61ecb75c8b 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -1679,6 +1679,10 @@ export const renderVegaVisualization = async (spec: string, i18n?: any) => { }; export const getCodeBlockContents = (content: string): object => { + // Strip thinking/reasoning and other detail blocks before extracting code + // to prevent code inside
from being treated as artifacts + content = removeAllDetails(content); + const codeBlockContents = content.match(/```[\s\S]*?```/g); let codeBlocks = []; From 95b65ff751f91131b633cb128ff2decdd87c4a85 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 18:23:52 -0600 Subject: [PATCH 0804/1854] refac --- backend/open_webui/routers/ollama.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/open_webui/routers/ollama.py b/backend/open_webui/routers/ollama.py index 580717987c..926e2c02ad 100644 --- a/backend/open_webui/routers/ollama.py +++ b/backend/open_webui/routers/ollama.py @@ -1176,7 +1176,7 @@ async def embeddings( class GenerateCompletionForm(BaseModel): model: str - prompt: str + prompt: Optional[str] = None suffix: Optional[str] = None images: Optional[list[str]] = None format: Optional[Union[dict, str]] = None From 2e1ef805ff0da372a22702009b9dd416c6633a35 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 8 Mar 2026 01:30:26 +0100 Subject: [PATCH 0805/1854] fix: banner type dropdown requires two selections to register (#22378) --- src/lib/components/admin/Settings/Interface/Banners.svelte | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/lib/components/admin/Settings/Interface/Banners.svelte b/src/lib/components/admin/Settings/Interface/Banners.svelte index 6b96374d5e..5ebf9c7685 100644 --- a/src/lib/components/admin/Settings/Interface/Banners.svelte +++ b/src/lib/components/admin/Settings/Interface/Banners.svelte @@ -64,9 +64,7 @@ bind:value={banner.type} required > - {#if banner.type == ''} - - {/if} + From 885c94bda888efc490bd9cd13ff9500fbc45d1f7 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 18:51:20 -0600 Subject: [PATCH 0806/1854] refac --- src/lib/components/layout/Sidebar/ChatItem.svelte | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib/components/layout/Sidebar/ChatItem.svelte b/src/lib/components/layout/Sidebar/ChatItem.svelte index 7134b1e94d..36a76a932c 100644 --- a/src/lib/components/layout/Sidebar/ChatItem.svelte +++ b/src/lib/components/layout/Sidebar/ChatItem.svelte @@ -79,6 +79,9 @@ let mouseOver = false; let draggable = false; + $: if (mouseOver) { + loadChat(); + } const loadChat = async () => { if (!chat) { From d7efdcce2b1cdbe1637a469294bf9d52dbacab53 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 19:02:03 -0600 Subject: [PATCH 0807/1854] refac --- backend/open_webui/utils/middleware.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index a4ca8c3561..3e993fdde6 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -3741,7 +3741,7 @@ async def streaming_chat_response_handler(response, ctx): if delta_name: current_response_tool_call[ "function" - ]["name"] += delta_name + ]["name"] = delta_name if delta_arguments: current_response_tool_call[ From 9a269ec8abc930ed45ff6a7803664d5f9131c44f Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 8 Mar 2026 02:02:59 +0100 Subject: [PATCH 0808/1854] fix: use path converter for model ID routes in analytics to support slashes (#22382) --- backend/open_webui/routers/analytics.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/routers/analytics.py b/backend/open_webui/routers/analytics.py index 61aec66332..1bd12f7bdb 100644 --- a/backend/open_webui/routers/analytics.py +++ b/backend/open_webui/routers/analytics.py @@ -278,7 +278,7 @@ class ModelChatsResponse(BaseModel): total: int -@router.get("/models/{model_id}/chats", response_model=ModelChatsResponse) +@router.get("/models/{model_id:path}/chats", response_model=ModelChatsResponse) async def get_model_chats( model_id: str, start_date: Optional[int] = Query(None), @@ -367,7 +367,7 @@ class ModelOverviewResponse(BaseModel): tags: list[TagEntry] -@router.get("/models/{model_id}/overview", response_model=ModelOverviewResponse) +@router.get("/models/{model_id:path}/overview", response_model=ModelOverviewResponse) async def get_model_overview( model_id: str, days: int = Query(30, description="Number of days of history (0 for all)"), From 459a60a24240eab33441ed50f4f68cc27e65a037 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 19:17:24 -0600 Subject: [PATCH 0809/1854] refac --- backend/open_webui/utils/middleware.py | 55 +++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 3e993fdde6..00de970ef4 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -160,6 +160,55 @@ def output_id(prefix: str) -> str: return f"{prefix}_{uuid4().hex[:24]}" +def _split_tool_calls( + tool_calls: list[dict], +) -> list[dict]: + """Expand tool calls whose arguments contain multiple back-to-back JSON objects. + + Some models (e.g. GPT-5.4) send multiple complete JSON argument objects + under the same tool call index, producing concatenated invalid JSON like: + '{"query":"A","count":5}{"query":"B","count":5}' + + Each such tool call is split into separate entries so each gets executed + independently. Single-object arguments pass through unchanged. + """ + + def split_json_objects(raw: str) -> list[str]: + decoder = json.JSONDecoder() + results = [] + position = 0 + + while position < len(raw): + while position < len(raw) and raw[position].isspace(): + position += 1 + if position >= len(raw): + break + try: + _, end = decoder.raw_decode(raw, position) + results.append(raw[position:end].strip()) + position = end + except json.JSONDecodeError: + return [raw] + + return results or [raw] + + expanded = [] + for tool_call in tool_calls: + arguments = tool_call.get("function", {}).get("arguments", "") + split_arguments = split_json_objects(arguments) + + if len(split_arguments) <= 1: + expanded.append(tool_call) + else: + for argument in split_arguments: + cloned = copy.deepcopy(tool_call) + cloned["id"] = f"call_{uuid4().hex[:24]}" + cloned["function"]["arguments"] = argument + expanded.append(cloned) + + return expanded + + def get_citation_source_from_tool_result( tool_name: str, tool_params: dict, tool_result: str, tool_id: str = "" ) -> list[dict]: @@ -4104,7 +4153,11 @@ async def streaming_chat_response_handler(response, ctx): reasoning_item["status"] = "completed" if response_tool_calls: - tool_calls.append(response_tool_calls) + tool_calls.append( + _split_tool_calls( + response_tool_calls + ) + ) if response.background: await response.background() From d1975b740b019ba1364eba7fdcf478ec99b19ca7 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 8 Mar 2026 02:19:44 +0100 Subject: [PATCH 0810/1854] fix: add deterministic ordering to chat_ids pagination query to prevent duplicates (#22383) --- backend/open_webui/models/chat_messages.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backend/open_webui/models/chat_messages.py b/backend/open_webui/models/chat_messages.py index e6e932be12..4cd868e4d4 100644 --- a/backend/open_webui/models/chat_messages.py +++ b/backend/open_webui/models/chat_messages.py @@ -292,9 +292,13 @@ class ChatMessageTable: query = query.filter(ChatMessage.created_at <= end_date) # Group by chat_id and order by most recent message in each chat + # Secondary sort on chat_id ensures deterministic pagination + # (prevents duplicates across pages when timestamps tie) chat_ids = ( query.group_by(ChatMessage.chat_id) - .order_by(func.max(ChatMessage.created_at).desc()) + .order_by( + func.max(ChatMessage.created_at).desc(), ChatMessage.chat_id + ) .offset(skip) .limit(limit) .all() From ce0ca894fea8a2904bc6f832ff186d5fe53dd0b9 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 19:23:18 -0600 Subject: [PATCH 0811/1854] enh: code interpreter pyodide fs --- backend/open_webui/config.py | 35 +- backend/open_webui/main.py | 1 + backend/open_webui/utils/middleware.py | 32 +- .../admin/Settings/CodeExecution.svelte | 4 +- src/lib/components/chat/Chat.svelte | 3 + src/lib/components/chat/ChatControls.svelte | 10 +- .../chat/FileNav/FileEntryRow.svelte | 4 +- src/lib/components/chat/MessageInput.svelte | 6 + src/lib/components/chat/PyodideFileNav.svelte | 367 ++++++++++++++++++ src/lib/stores/index.ts | 3 + src/lib/workers/pyodide.worker.ts | 260 +++++++++++-- src/routes/+layout.svelte | 79 +++- 12 files changed, 727 insertions(+), 77 deletions(-) create mode 100644 src/lib/components/chat/PyodideFileNav.svelte diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index 32dfdb7ca9..2e3254a08c 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -2296,20 +2296,31 @@ CODE_INTERPRETER_BLOCKED_MODULES = [ ] DEFAULT_CODE_INTERPRETER_PROMPT = """ -#### Tools Available +#### Code Interpreter -1. **Code Interpreter**: `` - - You have access to a Python shell that runs directly in the user's browser, enabling fast execution of code for analysis, calculations, or problem-solving. Use it in this response. - - The Python code you write can incorporate a wide array of libraries, handle data manipulation or visualization, perform API calls for web-related tasks, or tackle virtually any computational challenge. Use this flexibility to **think outside the box, craft elegant solutions, and harness Python's full potential**. - - To use it, **you must enclose your code within `` XML tags** and stop right away. If you don't, the code won't execute. - - When writing code in the code_interpreter XML tag, Do NOT use the triple backticks code block for markdown formatting, example: ```py # python code ``` will cause an error because it is markdown formatting, it is not python code. - - When coding, **always aim to print meaningful outputs** (e.g., results, tables, summaries, or visuals) to better interpret and verify the findings. Avoid relying on implicit outputs; prioritize explicit and clear print statements so the results are effectively communicated to the user. - - After obtaining the printed output, **always provide a concise analysis, interpretation, or next steps to help the user understand the findings or refine the outcome further.** - - If the results are unclear, unexpected, or require validation, refine the code and execute it again as needed. Always aim to deliver meaningful insights from the results, iterating if necessary. - - **If a link to an image, audio, or any file is provided in markdown format in the output, ALWAYS regurgitate word for word, explicitly display it as part of the response to ensure the user can access it easily, do NOT change the link.** - - All responses should be communicated in the chat's primary language, ensuring seamless understanding. If the chat is multilingual, default to English for clarity. +You have access to a Python code interpreter via: `` -Ensure that the tools are effectively utilized to achieve the highest-quality analysis for the user.""" +- The Python shell runs directly in the user's browser for fast execution of analysis, calculations, or problem-solving. Use it in this response. +- You can use a wide array of libraries for data manipulation, visualization, API calls, or any computational task. Think outside the box and harness Python's full potential. +- **You must enclose your code within `` XML tags** and stop right away. If you don't, the code won't execute. +- Do NOT use triple backticks (```py ... ```) inside the XML tags — that is markdown formatting, not executable Python code. +- **Always print meaningful outputs** (results, tables, summaries, visuals). Avoid implicit outputs; use explicit print statements. +- After obtaining output, **provide a concise analysis, interpretation, or next steps** to help the user understand the findings. +- If results are unclear or unexpected, refine the code and re-execute. Iterate until you deliver meaningful insights. +- **If a link to an image, audio, or any file appears in the output, display it exactly as-is** in your response so the user can access it. Do not modify the link. +- Respond in the chat's primary language. Default to English if multilingual. + +Ensure the code interpreter is effectively utilized to achieve the highest-quality analysis for the user.""" + +# Appended to the code interpreter prompt only when engine is pyodide (not jupyter) +CODE_INTERPRETER_PYODIDE_FS_PROMPT = """ + +##### Persistent File System + +- User-uploaded files are available at `/mnt/uploads/`. When the user asks you to work with their files, read from this directory. +- You can also write output files to `/mnt/uploads/` so the user can access and download them from the file browser. +- The file system persists across code executions within the same session. +- Use `import os; os.listdir('/mnt/uploads')` to discover available files.""" #################################### diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index 328c49b6c8..4c27e811cb 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -2193,6 +2193,7 @@ async def get_app_config(request: Request): "user_count": user_count, "code": { "engine": app.state.config.CODE_EXECUTION_ENGINE, + "interpreter_engine": app.state.config.CODE_INTERPRETER_ENGINE, }, "audio": { "tts": { diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 00de970ef4..4aa7c2f41e 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -1,3 +1,4 @@ +import copy import time import logging import sys @@ -119,6 +120,7 @@ from open_webui.config import ( DEFAULT_VOICE_MODE_PROMPT_TEMPLATE, DEFAULT_TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE, DEFAULT_CODE_INTERPRETER_PROMPT, + CODE_INTERPRETER_PYODIDE_FS_PROMPT, CODE_INTERPRETER_BLOCKED_MODULES, ) from open_webui.env import ( @@ -2352,18 +2354,36 @@ async def process_chat_payload(request, form_data, user, metadata, model): ) if "code_interpreter" in features and features["code_interpreter"]: + engine = getattr( + request.app.state.config, "CODE_INTERPRETER_ENGINE", "pyodide" + ) + # Skip XML-tag prompt injection when native FC is enabled — # execute_code will be injected as a builtin tool instead if metadata.get("params", {}).get("function_calling") != "native": + prompt = ( + request.app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE + if request.app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE + != "" + else DEFAULT_CODE_INTERPRETER_PROMPT + ) + + # Append filesystem awareness only for pyodide engine + if engine != "jupyter": + prompt += CODE_INTERPRETER_PYODIDE_FS_PROMPT + form_data["messages"] = add_or_update_user_message( - ( - request.app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE - if request.app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE - != "" - else DEFAULT_CODE_INTERPRETER_PROMPT - ), + prompt, form_data["messages"], ) + else: + # Native FC: tool docstring can't be dynamic, so inject + # filesystem context into messages for pyodide engine + if engine != "jupyter": + form_data["messages"] = add_or_update_user_message( + CODE_INTERPRETER_PYODIDE_FS_PROMPT, + form_data["messages"], + ) tool_ids = form_data.pop("tool_ids", None) terminal_id = form_data.pop("terminal_id", None) diff --git a/src/lib/components/admin/Settings/CodeExecution.svelte b/src/lib/components/admin/Settings/CodeExecution.svelte index 23388c0a45..cad7970de1 100644 --- a/src/lib/components/admin/Settings/CodeExecution.svelte +++ b/src/lib/components/admin/Settings/CodeExecution.svelte @@ -67,7 +67,7 @@ > {#each engines as engine} - + {/each}
@@ -193,7 +193,7 @@ > {#each engines as engine} - + {/each}
diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index b510dd0b65..b391cd1a51 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -148,6 +148,8 @@ let webSearchEnabled = false; let codeInterpreterEnabled = false; + + let showCommands = false; let generating = false; @@ -2924,6 +2926,7 @@ {stopResponse} {showMessage} {eventTarget} + {codeInterpreterEnabled} />
diff --git a/src/lib/components/chat/ChatControls.svelte b/src/lib/components/chat/ChatControls.svelte index 60ec1aa27d..f5957e40e4 100644 --- a/src/lib/components/chat/ChatControls.svelte +++ b/src/lib/components/chat/ChatControls.svelte @@ -10,6 +10,7 @@ import { onDestroy, onMount, tick, getContext } from 'svelte'; import { + config, terminalServers, mobile, showControls, @@ -31,6 +32,7 @@ import Artifacts from './Artifacts.svelte'; import Embeds from './ChatControls/Embeds.svelte'; import FileNav from './FileNav.svelte'; + import PyodideFileNav from './PyodideFileNav.svelte'; import Overview from './Overview.svelte'; const i18n = getContext('i18n'); @@ -50,6 +52,8 @@ export let files; export let modelId; + export let codeInterpreterEnabled = false; + export let pane: Pane | null = null; let largeScreen = false; @@ -67,7 +71,7 @@ $: hasMessages = history?.messages && Object.keys(history.messages).length > 0; $: showControlsTab = $user?.role === 'admin' || ($user?.permissions?.chat?.controls ?? true); - $: showFilesTab = !!$selectedTerminalId; + $: showFilesTab = !!$selectedTerminalId || (codeInterpreterEnabled && $config?.code?.interpreter_engine !== 'jupyter'); $: showOverviewTab = hasMessages; // Tab fallback: if active tab becomes hidden, switch to next available @@ -355,6 +359,8 @@ /> {:else if activeTab === 'files' && $selectedTerminalId} + {:else if activeTab === 'files' && codeInterpreterEnabled} + {:else} {/if} @@ -504,6 +510,8 @@ /> {:else if activeTab === 'files' && $selectedTerminalId} + {:else if activeTab === 'files' && codeInterpreterEnabled} + {:else} {/if} diff --git a/src/lib/components/chat/FileNav/FileEntryRow.svelte b/src/lib/components/chat/FileNav/FileEntryRow.svelte index b572b15255..eb217bcc9b 100644 --- a/src/lib/components/chat/FileNav/FileEntryRow.svelte +++ b/src/lib/components/chat/FileNav/FileEntryRow.svelte @@ -12,8 +12,8 @@ export let entry: FileEntry; export let currentPath: string; - export let terminalUrl: string; - export let terminalKey: string; + export let terminalUrl: string = ''; + export let terminalKey: string = ''; export let onOpen: (entry: FileEntry) => void = () => {}; export let onDownload: (path: string) => void = () => {}; diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index 2cbd0d9557..9bf3a08139 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -508,11 +508,17 @@ let showCodeInterpreterButton = false; $: showCodeInterpreterButton = + !$selectedTerminalId && (atSelectedModel?.id ? [atSelectedModel.id] : selectedModels).length === codeInterpreterCapableModels.length && $config?.features?.enable_code_interpreter && ($_user.role === 'admin' || $_user?.permissions?.features?.code_interpreter); + // Disable code interpreter when terminal is active (mutually exclusive) + $: if ($selectedTerminalId && codeInterpreterEnabled) { + codeInterpreterEnabled = false; + } + const scrollToBottom = () => { const element = document.getElementById('messages-container'); element.scrollTo({ diff --git a/src/lib/components/chat/PyodideFileNav.svelte b/src/lib/components/chat/PyodideFileNav.svelte new file mode 100644 index 0000000000..45e9693207 --- /dev/null +++ b/src/lib/components/chat/PyodideFileNav.svelte @@ -0,0 +1,367 @@ + + + + + + +
(isDragOver = false)} + on:drop={handleDrop} + role="region" + aria-label={$i18n.t('Pyodide file browser')} +> + {#if isDragOver} +
+ + + + {$i18n.t('Drop files here')} +
+ {/if} + + {#if overlay} +
+ {/if} + + + loadDir(path)} + onRefresh={() => { + if (selectedFile) { + const name = selectedFile.split('/').pop() ?? ''; + openEntry({ name, type: 'file', size: 0 }); + } else { + loadDir(currentPath); + } + }} + onNewFolder={createFolder} + onNewFile={() => {}} + onUploadFiles={uploadFiles} + onMove={() => {}} + > + + + + + + +
+ {#if selectedFile} + + {:else if loading} +
+ +
+ {:else if error} +
+
{error}
+
+ {:else if entries.length === 0} +
+ +
+ {$i18n.t('No files yet. Upload files or run Python code to create them.')} +
+
+ {:else} +
    + {#each entries as entry (entry.name)} + + {/each} +
+ {/if} +
+
diff --git a/src/lib/stores/index.ts b/src/lib/stores/index.ts index bdc8fe31ca..6361dcab80 100644 --- a/src/lib/stores/index.ts +++ b/src/lib/stores/index.ts @@ -72,6 +72,9 @@ export const functions = writable(null); export const toolServers = writable([]); export const terminalServers = writable([]); +// Persistent Pyodide worker for code interpreter FS +export const pyodideWorker: Writable = writable(null); + export const banners: Writable = writable([]); export const settings: Writable = writable({}); diff --git a/src/lib/workers/pyodide.worker.ts b/src/lib/workers/pyodide.worker.ts index 221effca5e..a9334b4faf 100644 --- a/src/lib/workers/pyodide.worker.ts +++ b/src/lib/workers/pyodide.worker.ts @@ -13,6 +13,12 @@ declare global { } } +// --------------------------------------------------------------------------- +// Pyodide bootstrap +// --------------------------------------------------------------------------- + +let pyodideReady: Promise | null = null; + async function loadPyodideAndPackages(packages: string[] = []) { self.stdout = null; self.stderr = null; @@ -40,41 +46,148 @@ async function loadPyodideAndPackages(packages: string[] = []) { packages: ['micropip'] }); - const mountDir = '/mnt'; - self.pyodide.FS.mkdirTree(mountDir); - // self.pyodide.FS.mount(self.pyodide.FS.filesystems.IDBFS, {}, mountDir); + // Create the upload directory and mount IDBFS for persistence + const uploadDir = '/mnt/uploads'; + self.pyodide.FS.mkdirTree(uploadDir); + self.pyodide.FS.mount(self.pyodide.FS.filesystems.IDBFS, {}, '/mnt'); - // // Load persisted files from IndexedDB (Initial Sync) - // await new Promise((resolve, reject) => { - // self.pyodide.FS.syncfs(true, (err) => { - // if (err) { - // console.error('Error syncing from IndexedDB:', err); - // reject(err); - // } else { - // console.log('Successfully loaded from IndexedDB.'); - // resolve(); - // } - // }); - // }); + // Load persisted files from IndexedDB + await new Promise((resolve) => { + (self.pyodide.FS as any).syncfs(true, (err: Error | null) => { + if (err) { + console.error('Error syncing from IndexedDB:', err); + } + // Always resolve — missing data is fine on first run + resolve(); + }); + }); + + // Ensure /mnt/uploads still exists after sync (first-time init) + try { + self.pyodide.FS.stat(uploadDir); + } catch { + self.pyodide.FS.mkdirTree(uploadDir); + } const micropip = self.pyodide.pyimport('micropip'); - - // await micropip.set_index_urls('https://pypi.org/pypi/{package_name}/json'); await micropip.install(packages); } -self.onmessage = async (event) => { - const { id, code, ...context } = event.data; +/** + * Ensure Pyodide is loaded. On the first call, loads and installs packages. + * Subsequent calls reuse the already-loaded instance (persistent worker). + */ +async function ensurePyodide(packages: string[] = []) { + if (!pyodideReady) { + pyodideReady = loadPyodideAndPackages(packages); + } + await pyodideReady; - console.log(event.data); + // Install any additional packages not loaded on init + if (packages.length > 0 && self.pyodide) { + const micropip = self.pyodide.pyimport('micropip'); + await micropip.install(packages); + } +} - // The worker copies the context in its own "memory" (an object mapping name to values) - for (const key of Object.keys(context)) { - self[key] = context[key]; +/** + * Persist the in-memory FS to IndexedDB (fire-and-forget with logging). + */ +function persistFS() { + if (!self.pyodide) return; + (self.pyodide.FS as any).syncfs(false, (err: Error | null) => { + if (err) { + console.error('Error syncing to IndexedDB:', err); + } else { + console.log('Successfully synced to IndexedDB.'); + } + }); +} + +// --------------------------------------------------------------------------- +// FS operations +// --------------------------------------------------------------------------- + +function fsUploadFiles(files: { name: string; data: ArrayBuffer }[], dir = '/mnt/uploads') { + try { + self.pyodide.FS.stat(dir); + } catch { + self.pyodide.FS.mkdirTree(dir); } - // make sure loading is done - await loadPyodideAndPackages(self.packages); + for (const file of files) { + self.pyodide.FS.writeFile(`${dir}/${file.name}`, new Uint8Array(file.data)); + } +} + +function fsList(path: string) { + const entries: { name: string; type: 'file' | 'directory'; size: number }[] = []; + try { + const items = self.pyodide.FS.readdir(path).filter( + (n: string) => n !== '.' && n !== '..' + ); + for (const name of items) { + try { + const stat = self.pyodide.FS.stat(`${path}/${name}`); + const isDir = self.pyodide.FS.isDir(stat.mode); + entries.push({ + name, + type: isDir ? 'directory' : 'file', + size: isDir ? 0 : stat.size + }); + } catch { + // skip inaccessible entries + } + } + } catch { + // directory doesn't exist + } + return entries; +} + +function fsRead(path: string): ArrayBuffer { + const data: Uint8Array = (self.pyodide.FS as any).readFile(path) as Uint8Array; + return data.buffer as ArrayBuffer; +} + +function fsDelete(path: string) { + try { + const stat = self.pyodide.FS.stat(path); + if (self.pyodide.FS.isDir(stat.mode)) { + // Recursively delete directory contents + const items = self.pyodide.FS.readdir(path).filter( + (n: string) => n !== '.' && n !== '..' + ); + for (const item of items) { + fsDelete(`${path}/${item}`); + } + self.pyodide.FS.rmdir(path); + } else { + self.pyodide.FS.unlink(path); + } + } catch { + // already gone + } +} + +function fsMkdir(path: string) { + self.pyodide.FS.mkdirTree(path); +} + +// --------------------------------------------------------------------------- +// Code execution +// --------------------------------------------------------------------------- + +async function executeCode(id: string, code: string, files?: { name: string; data: ArrayBuffer }[]) { + self.stdout = null; + self.stderr = null; + self.result = null; + + // Upload any accompanying files before execution + if (files && files.length > 0) { + fsUploadFiles(files); + persistFS(); + } try { // check if matplotlib is imported in the code @@ -113,25 +226,90 @@ matplotlib.pyplot.show = show`); console.log('Python result:', self.result); - // Persist any changes to IndexedDB - // await new Promise((resolve, reject) => { - // self.pyodide.FS.syncfs(false, (err) => { - // if (err) { - // console.error('Error syncing to IndexedDB:', err); - // reject(err); - // } else { - // console.log('Successfully synced to IndexedDB.'); - // resolve(); - // } - // }); - // }); - } catch (error) { - self.stderr = error.toString(); + // Persist any files the code may have written + persistFS(); + } catch (error: unknown) { + self.stderr = error instanceof Error ? error.message : String(error); } self.postMessage({ id, result: self.result, stdout: self.stdout, stderr: self.stderr }); +} + +// --------------------------------------------------------------------------- +// Message handler +// --------------------------------------------------------------------------- + +self.onmessage = async (event) => { + const data = event.data; + const { id, type } = data; + + // Backward compatibility: messages without a `type` field are execute requests + if (!type || type === 'execute') { + const { code, files, ...context } = data; + + // Copy context keys (packages, etc.) into worker scope + for (const key of Object.keys(context)) { + if (key !== 'id' && key !== 'type') { + self[key] = context[key]; + } + } + + await ensurePyodide(self.packages); + await executeCode(id, code, files); + return; + } + + // FS operations require Pyodide to be loaded + await ensurePyodide(); + + switch (type) { + case 'fs:upload': { + const { files, dir } = data; + fsUploadFiles(files, dir); + persistFS(); + self.postMessage({ id, type: 'fs:upload', success: true }); + break; + } + + case 'fs:list': { + const entries = fsList(data.path); + self.postMessage({ id, type: 'fs:list', entries }); + break; + } + + case 'fs:read': { + try { + const buffer = fsRead(data.path); + self.postMessage({ id, type: 'fs:read', data: buffer }, { transfer: [buffer] }); + } catch (err: unknown) { + self.postMessage({ id, type: 'fs:read', error: err instanceof Error ? err.message : String(err) }); + } + break; + } + + case 'fs:delete': { + fsDelete(data.path); + persistFS(); + self.postMessage({ id, type: 'fs:delete', success: true }); + break; + } + + case 'fs:mkdir': { + fsMkdir(data.path); + persistFS(); + self.postMessage({ id, type: 'fs:mkdir', success: true }); + break; + } + + default: + console.warn('Unknown message type:', type); + } }; +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + function processResult(result: any): any { // Catch and always return JSON-safe string representations try { @@ -167,9 +345,9 @@ function processResult(result: any): any { } // Stringify anything that's left (e.g., Proxy objects that cannot be directly processed) return JSON.stringify(result); - } catch (err) { + } catch (err: unknown) { // In case something unexpected happens, we return a stringified fallback - return `[processResult error]: ${err.message || err.toString()}`; + return `[processResult error]: ${err instanceof Error ? err.message : String(err)}`; } } diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 42768ca99d..36fd7b22d5 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -34,8 +34,10 @@ terminalServers, showControls, showFileNavPath, - showFileNavDir + showFileNavDir, + pyodideWorker } from '$lib/stores'; + import { getFileContentById } from '$lib/apis/files'; import { goto } from '$app/navigation'; import { page } from '$app/stores'; import { beforeNavigate } from '$app/navigation'; @@ -184,7 +186,20 @@ }); }; - const executePythonAsWorker = async (id, code, cb) => { + /** + * Get or create the persistent Pyodide worker. + * The worker persists across executions so the virtual FS (IDBFS) is preserved. + */ + const getOrCreateWorker = () => { + let worker = $pyodideWorker; + if (!worker) { + worker = new PyodideWorker(); + pyodideWorker.set(worker); + } + return worker; + }; + + const executePythonAsWorker = async (id, code, cb, files = []) => { let result = null; let stdout = null; let stderr = null; @@ -206,19 +221,44 @@ /\bimport\s+pytz\b|\bfrom\s+pytz\b/.test(code) ? 'pytz' : null ].filter(Boolean); - const pyodideWorker = new PyodideWorker(); + const worker = getOrCreateWorker(); - pyodideWorker.postMessage({ + // Fetch file content from the server and prepare for the worker + let filePayloads = []; + if (files && files.length > 0) { + for (const file of files) { + try { + const fileId = file?.id; + const fileName = file?.filename || file?.name || 'file'; + if (fileId) { + const content = await getFileContentById(fileId); + if (content) { + filePayloads.push({ name: fileName, data: content }); + } + } + } catch (e) { + console.error('Failed to fetch file for Pyodide:', e); + } + } + } + + worker.postMessage({ + type: 'execute', id: id, code: code, - packages: packages + packages: packages, + files: filePayloads.length > 0 ? filePayloads : undefined }); - setTimeout(() => { + // Timeout for this specific execution (not the worker itself) + let timeoutId = setTimeout(() => { if (executing) { executing = false; stderr = 'Execution Time Limit Exceeded'; - pyodideWorker.terminate(); + + // Terminate and recreate the worker on timeout + worker.terminate(); + pyodideWorker.set(null); if (cb) { cb( @@ -237,11 +277,18 @@ } }, 60000); - pyodideWorker.onmessage = (event) => { - console.log('pyodideWorker.onmessage', event); - const { id, ...data } = event.data; + // Use addEventListener so multiple concurrent executions don't clobber each other + const onMessage = (event) => { + const { id: eventId, ...data } = event.data; + // Only handle responses for this execution ID + if (eventId !== id) return; + // Ignore FS responses (they use a type field) + if (data.type && data.type.startsWith('fs:')) return; - console.log(id, data); + console.log('pyodideWorker.onmessage', event); + clearTimeout(timeoutId); + worker.removeEventListener('message', onMessage); + worker.removeEventListener('error', onError); data['stdout'] && (stdout = data['stdout']); data['stderr'] && (stderr = data['stderr']); @@ -265,8 +312,11 @@ executing = false; }; - pyodideWorker.onerror = (event) => { + const onError = (event) => { console.log('pyodideWorker.onerror', event); + clearTimeout(timeoutId); + worker.removeEventListener('message', onMessage); + worker.removeEventListener('error', onError); if (cb) { cb( @@ -284,6 +334,9 @@ } executing = false; }; + + worker.addEventListener('message', onMessage); + worker.addEventListener('error', onError); }; const resolveToolServer = (serverUrl) => { @@ -423,7 +476,7 @@ } else if (data?.session_id === $socket.id) { if (type === 'execute:python') { console.log('execute:python', data); - executePythonAsWorker(data.id, data.code, cb); + executePythonAsWorker(data.id, data.code, cb, data.files || []); } else if (type === 'execute:tool') { console.log('execute:tool', data); executeTool(data, cb); From 8cd3bd7997d25877c2d316d8aa3058b01c7d6660 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 19:28:57 -0600 Subject: [PATCH 0812/1854] refac --- src/lib/components/chat/PyodideFileNav.svelte | 99 +++++++++++++++++-- 1 file changed, 92 insertions(+), 7 deletions(-) diff --git a/src/lib/components/chat/PyodideFileNav.svelte b/src/lib/components/chat/PyodideFileNav.svelte index 45e9693207..3afbd7bbe4 100644 --- a/src/lib/components/chat/PyodideFileNav.svelte +++ b/src/lib/components/chat/PyodideFileNav.svelte @@ -3,7 +3,7 @@ @@ -47,6 +49,18 @@ {align} transition={flyAndScale} > + { + onCreateSub(); + }} + > + +
{$i18n.t('Create Folder')}
+
+ +
+ { diff --git a/src/lib/components/layout/Sidebar/Folders/FolderModal.svelte b/src/lib/components/layout/Sidebar/Folders/FolderModal.svelte index f1d0975282..73248a59c2 100644 --- a/src/lib/components/layout/Sidebar/Folders/FolderModal.svelte +++ b/src/lib/components/layout/Sidebar/Folders/FolderModal.svelte @@ -19,6 +19,7 @@ export let onSubmit: Function = (e) => {}; export let folderId = null; + export let parentId = null; export let edit = false; let folder = null; @@ -55,7 +56,8 @@ await onSubmit({ name, meta, - data + data, + parent_id: edit ? undefined : parentId }); show = false; loading = false; diff --git a/src/lib/components/layout/Sidebar/RecursiveFolder.svelte b/src/lib/components/layout/Sidebar/RecursiveFolder.svelte index f800cfe9ba..3557a4fd5d 100644 --- a/src/lib/components/layout/Sidebar/RecursiveFolder.svelte +++ b/src/lib/components/layout/Sidebar/RecursiveFolder.svelte @@ -18,7 +18,8 @@ updateFolderIsExpandedById, updateFolderById, updateFolderParentIdById, - getFolderById + getFolderById, + createNewFolder } from '$lib/apis/folders'; import { getChatById, @@ -64,6 +65,9 @@ let showFolderModal = false; let edit = false; + let showCreateSubFolderModal = false; + let createSubFolderParentId = null; + let draggedOver = false; let dragged = false; @@ -414,6 +418,30 @@ saveAs(blob, `folder-${folders[folderId].name}-export-${Date.now()}.json`); }; + + const createSubFolderHandler = async ({ name, meta, data, parent_id }) => { + if (name === '') { + toast.error($i18n.t('Folder name cannot be empty.')); + return; + } + + name = name.trim(); + + const res = await createNewFolder(localStorage.token, { + name, + data, + meta, + parent_id + }).catch((error) => { + toast.error(`${error}`); + return null; + }); + + if (res) { + toast.success($i18n.t('Folder created successfully')); + dispatch('update'); + } + }; + + {#if dragged && x && y}
@@ -593,6 +627,10 @@ onExport={() => { exportHandler(); }} + onCreateSub={() => { + createSubFolderParentId = folderId; + showCreateSubFolderModal = true; + }} >
diff --git a/src/lib/i18n/locales/en-US/translation.json b/src/lib/i18n/locales/en-US/translation.json index dced0f6c92..ae23cad549 100644 --- a/src/lib/i18n/locales/en-US/translation.json +++ b/src/lib/i18n/locales/en-US/translation.json @@ -897,6 +897,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "", "Folder Max File Count": "", "Folder name": "", @@ -2135,4 +2136,4 @@ "YouTube": "", "Youtube Language": "", "Youtube Proxy URL": "" -} +} \ No newline at end of file From 989938856fdb4b4afa584ae2d18c88d5be614ae2 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 20:05:18 -0600 Subject: [PATCH 0816/1854] refac --- backend/open_webui/config.py | 7 ++++++- backend/open_webui/utils/middleware.py | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index 2e3254a08c..f029b6ba2b 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -2313,7 +2313,12 @@ You have access to a Python code interpreter via: ` Date: Sat, 7 Mar 2026 20:12:35 -0600 Subject: [PATCH 0817/1854] refac --- backend/open_webui/utils/middleware.py | 117 ++++++++++++++++--------- 1 file changed, 74 insertions(+), 43 deletions(-) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 389ae9a90b..256b21aa5e 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -890,6 +890,27 @@ def handle_responses_streaming_event( return current_output, None +def get_source_context(sources: list, include_content: bool = True) -> str: + """ + Build tag context string from citation sources. + """ + context_string = "" + citation_idx = {} + for source in sources: + for doc, meta in zip(source.get("document", []), source.get("metadata", [])): + src_id = meta.get("source") or source.get("source", {}).get("id") or "N/A" + if src_id not in citation_idx: + citation_idx[src_id] = len(citation_idx) + 1 + src_name = source.get("source", {}).get("name") + body = doc if include_content else "" + context_string += ( + f'{body}\n" + ) + return context_string + + def apply_source_context_to_messages( request: Request, messages: list, @@ -908,21 +929,7 @@ def apply_source_context_to_messages( if not sources or not user_message: return messages - context_string = "" - citation_idx = {} - - for source in sources: - for doc, meta in zip(source.get("document", []), source.get("metadata", [])): - src_id = meta.get("source") or source.get("source", {}).get("id") or "N/A" - if src_id not in citation_idx: - citation_idx[src_id] = len(citation_idx) + 1 - src_name = source.get("source", {}).get("name") - body = doc if include_content else "" - context_string += ( - f'{body}\n" - ) + context_string = get_source_context(sources, include_content) context_string = context_string.strip() if not context_string: @@ -2741,6 +2748,18 @@ async def process_chat_payload(request, form_data, user, metadata, model): except Exception as e: log.exception(e) + # Save the pre-RAG message state so the native tool call loop can + # restore to the true original (before file-source injection) rather + # than a snapshot that already has the RAG template baked in. + system_message = get_system_message(form_data["messages"]) + metadata["system_prompt"] = ( + get_content_from_message(system_message) if system_message else None + ) + metadata["user_prompt"] = get_last_user_message( + form_data["messages"] + ) + metadata["sources"] = sources[:] if sources else [] + # If context is not empty, insert it into the messages if sources and prompt: form_data["messages"] = apply_source_context_to_messages( @@ -4202,16 +4221,21 @@ async def streaming_chat_response_handler(response, ctx): model.get("info", {}).get("meta", {}).get("capabilities") or {} ).get("citations", True) - # Save original system message so we can restore it before - # re-applying source context (prevents duplication when - # RAG_SYSTEM_CONTEXT is enabled and the template is appended - # to the system message on each iteration). - original_system_message = get_system_message(form_data["messages"]) - original_system_content = ( - get_content_from_message(original_system_message) - if original_system_message - else None + # Use the pre-RAG system content captured before the + # initial file-source injection in process_chat_payload. + # This ensures restore truly undoes the RAG template. + original_system_content = metadata.get( + "system_prompt" ) + if original_system_content is None: + original_system_message = get_system_message( + form_data["messages"] + ) + original_system_content = ( + get_content_from_message(original_system_message) + if original_system_message + else None + ) while ( len(tool_calls) > 0 @@ -4459,33 +4483,40 @@ async def streaming_chat_response_handler(response, ctx): } ) - # Emit citation sources and apply source context to messages + # Emit citation sources to the frontend for display if citations_enabled: for source in tool_call_sources: await event_emitter({"type": "source", "data": source}) - # Apply source context to messages for model. - # Use include_content=False to avoid duplicating content - # that is already in the tool result message. + # Apply tool source context to messages for the model. + # Restoring to pre-RAG original prevents duplicating + # the RAG template across file and tool sources. all_tool_call_sources.extend(tool_call_sources) if all_tool_call_sources and user_message: - # Restore original messages before re-applying to - # avoid recursive nesting (user message) and - # duplication (system message with RAG_SYSTEM_CONTEXT). + # Restore pre-RAG message state before re-applying + # to prevent RAG template duplication. + original_user_message = metadata.get( + "user_prompt" + ) or user_message set_last_user_message_content( - user_message, form_data["messages"] - ) - if original_system_content is not None: - replace_system_message_content( - original_system_content, - form_data["messages"], - ) - form_data["messages"] = apply_source_context_to_messages( - request, + original_user_message, form_data["messages"], - all_tool_call_sources, - user_message, - include_content=False, + ) + replace_system_message_content( + original_system_content or "", + form_data["messages"], + ) + + # Combine file and tool sources into one RAG + # template application. + form_data["messages"] = ( + apply_source_context_to_messages( + request, + form_data["messages"], + metadata.get("sources", []) + + all_tool_call_sources, + user_message, + ) ) tool_call_sources.clear() From 3ceaa107ab51b13795ddbcc35feb41f8bdc5be23 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 20:14:32 -0600 Subject: [PATCH 0818/1854] chore: format --- .../8452d01d26d7_add_chat_message_table.py | 54 ++++++++------- backend/open_webui/models/chat_messages.py | 4 +- backend/open_webui/routers/folders.py | 8 ++- backend/open_webui/utils/middleware.py | 51 +++++--------- backend/open_webui/utils/models.py | 4 +- package-lock.json | 4 +- package.json | 4 +- .../admin/Settings/CodeExecution.svelte | 7 +- src/lib/components/chat/Chat.svelte | 2 - src/lib/components/chat/ChatControls.svelte | 4 +- src/lib/components/chat/PyodideFileNav.svelte | 69 ++++++++++++------- src/lib/components/layout/Sidebar.svelte | 8 +-- .../workspace/Models/ModelEditor.svelte | 4 +- src/lib/i18n/locales/ar-BH/translation.json | 6 ++ src/lib/i18n/locales/ar/translation.json | 6 ++ src/lib/i18n/locales/bg-BG/translation.json | 6 ++ src/lib/i18n/locales/bn-BD/translation.json | 6 ++ src/lib/i18n/locales/bo-TB/translation.json | 6 ++ src/lib/i18n/locales/bs-BA/translation.json | 6 ++ src/lib/i18n/locales/ca-ES/translation.json | 6 ++ src/lib/i18n/locales/ceb-PH/translation.json | 6 ++ src/lib/i18n/locales/cs-CZ/translation.json | 6 ++ src/lib/i18n/locales/da-DK/translation.json | 6 ++ src/lib/i18n/locales/de-DE/translation.json | 6 ++ src/lib/i18n/locales/dg-DG/translation.json | 6 ++ src/lib/i18n/locales/el-GR/translation.json | 6 ++ src/lib/i18n/locales/en-GB/translation.json | 6 ++ src/lib/i18n/locales/en-US/translation.json | 7 +- src/lib/i18n/locales/es-ES/translation.json | 6 ++ src/lib/i18n/locales/et-EE/translation.json | 6 ++ src/lib/i18n/locales/eu-ES/translation.json | 6 ++ src/lib/i18n/locales/fa-IR/translation.json | 6 ++ src/lib/i18n/locales/fi-FI/translation.json | 6 ++ src/lib/i18n/locales/fr-CA/translation.json | 6 ++ src/lib/i18n/locales/fr-FR/translation.json | 6 ++ src/lib/i18n/locales/gl-ES/translation.json | 6 ++ src/lib/i18n/locales/he-IL/translation.json | 6 ++ src/lib/i18n/locales/hi-IN/translation.json | 6 ++ src/lib/i18n/locales/hr-HR/translation.json | 6 ++ src/lib/i18n/locales/hu-HU/translation.json | 6 ++ src/lib/i18n/locales/id-ID/translation.json | 6 ++ src/lib/i18n/locales/ie-GA/translation.json | 6 ++ src/lib/i18n/locales/it-IT/translation.json | 6 ++ src/lib/i18n/locales/ja-JP/translation.json | 6 ++ src/lib/i18n/locales/ka-GE/translation.json | 6 ++ src/lib/i18n/locales/kab-DZ/translation.json | 6 ++ src/lib/i18n/locales/ko-KR/translation.json | 6 ++ src/lib/i18n/locales/lt-LT/translation.json | 6 ++ src/lib/i18n/locales/lv-LV/translation.json | 6 ++ src/lib/i18n/locales/ms-MY/translation.json | 6 ++ src/lib/i18n/locales/nb-NO/translation.json | 6 ++ src/lib/i18n/locales/nl-NL/translation.json | 6 ++ src/lib/i18n/locales/pa-IN/translation.json | 6 ++ src/lib/i18n/locales/pl-PL/translation.json | 6 ++ src/lib/i18n/locales/pt-BR/translation.json | 6 ++ src/lib/i18n/locales/pt-PT/translation.json | 6 ++ src/lib/i18n/locales/ro-RO/translation.json | 6 ++ src/lib/i18n/locales/ru-RU/translation.json | 6 ++ src/lib/i18n/locales/sk-SK/translation.json | 6 ++ src/lib/i18n/locales/sr-RS/translation.json | 6 ++ src/lib/i18n/locales/sv-SE/translation.json | 6 ++ src/lib/i18n/locales/th-TH/translation.json | 6 ++ src/lib/i18n/locales/tk-TM/translation.json | 6 ++ src/lib/i18n/locales/tr-TR/translation.json | 6 ++ src/lib/i18n/locales/ug-CN/translation.json | 6 ++ src/lib/i18n/locales/uk-UA/translation.json | 6 ++ src/lib/i18n/locales/ur-PK/translation.json | 6 ++ .../i18n/locales/uz-Cyrl-UZ/translation.json | 6 ++ .../i18n/locales/uz-Latn-Uz/translation.json | 6 ++ src/lib/i18n/locales/vi-VN/translation.json | 6 ++ src/lib/i18n/locales/zh-CN/translation.json | 6 ++ src/lib/i18n/locales/zh-TW/translation.json | 6 ++ src/lib/workers/pyodide.worker.ts | 20 +++--- 73 files changed, 482 insertions(+), 116 deletions(-) diff --git a/backend/open_webui/migrations/versions/8452d01d26d7_add_chat_message_table.py b/backend/open_webui/migrations/versions/8452d01d26d7_add_chat_message_table.py index ea95d08f12..aa9b0a4c26 100644 --- a/backend/open_webui/migrations/versions/8452d01d26d7_add_chat_message_table.py +++ b/backend/open_webui/migrations/versions/8452d01d26d7_add_chat_message_table.py @@ -125,9 +125,9 @@ def upgrade() -> None: # - yield_per: fetches rows in chunks via cursor.fetchmany() (all backends) # - stream_results: enables server-side cursors on PostgreSQL (no-op on SQLite) result = conn.execute( - sa.select(chat_table.c.id, chat_table.c.user_id, chat_table.c.chat).where( - ~chat_table.c.user_id.like("shared-%") - ).execution_options(yield_per=1000, stream_results=True) + sa.select(chat_table.c.id, chat_table.c.user_id, chat_table.c.chat) + .where(~chat_table.c.user_id.like("shared-%")) + .execution_options(yield_per=1000, stream_results=True) ) now = int(time.time()) @@ -175,33 +175,39 @@ def upgrade() -> None: if timestamp < 1577836800 or timestamp > now + 86400: timestamp = now - messages_batch.append({ - "id": f"{chat_id}-{message_id}", - "chat_id": chat_id, - "user_id": user_id, - "role": role, - "parent_id": message.get("parentId"), - "content": message.get("content"), - "output": message.get("output"), - "model_id": message.get("model"), - "files": message.get("files"), - "sources": message.get("sources"), - "embeds": message.get("embeds"), - "done": message.get("done", True), - "status_history": message.get("statusHistory"), - "error": message.get("error"), - "usage": message.get("usage"), - "created_at": timestamp, - "updated_at": timestamp, - }) + messages_batch.append( + { + "id": f"{chat_id}-{message_id}", + "chat_id": chat_id, + "user_id": user_id, + "role": role, + "parent_id": message.get("parentId"), + "content": message.get("content"), + "output": message.get("output"), + "model_id": message.get("model"), + "files": message.get("files"), + "sources": message.get("sources"), + "embeds": message.get("embeds"), + "done": message.get("done", True), + "status_history": message.get("statusHistory"), + "error": message.get("error"), + "usage": message.get("usage"), + "created_at": timestamp, + "updated_at": timestamp, + } + ) # Flush batch when full if len(messages_batch) >= BATCH_SIZE: - inserted, failed = _flush_batch(conn, chat_message_table, messages_batch) + inserted, failed = _flush_batch( + conn, chat_message_table, messages_batch + ) total_inserted += inserted total_failed += failed if total_inserted % 50000 < BATCH_SIZE: - log.info(f"Migration progress: {total_inserted} messages inserted...") + log.info( + f"Migration progress: {total_inserted} messages inserted..." + ) messages_batch.clear() # Flush remaining messages diff --git a/backend/open_webui/models/chat_messages.py b/backend/open_webui/models/chat_messages.py index 4cd868e4d4..b707ab358b 100644 --- a/backend/open_webui/models/chat_messages.py +++ b/backend/open_webui/models/chat_messages.py @@ -296,9 +296,7 @@ class ChatMessageTable: # (prevents duplicates across pages when timestamps tie) chat_ids = ( query.group_by(ChatMessage.chat_id) - .order_by( - func.max(ChatMessage.created_at).desc(), ChatMessage.chat_id - ) + .order_by(func.max(ChatMessage.created_at).desc(), ChatMessage.chat_id) .offset(skip) .limit(limit) .all() diff --git a/backend/open_webui/routers/folders.py b/backend/open_webui/routers/folders.py index 602173e4c1..f6269e7b72 100644 --- a/backend/open_webui/routers/folders.py +++ b/backend/open_webui/routers/folders.py @@ -129,7 +129,9 @@ def create_folder( ) try: - folder = Folders.insert_new_folder(user.id, form_data, form_data.parent_id, db=db) + folder = Folders.insert_new_folder( + user.id, form_data, form_data.parent_id, db=db + ) return folder except Exception as e: log.exception(e) @@ -317,7 +319,9 @@ async def delete_folder_by_id( folder = folders.pop() if folder: try: - folder_ids = Folders.delete_folder_by_id_and_user_id(folder.id, user.id, db=db) + folder_ids = Folders.delete_folder_by_id_and_user_id( + folder.id, user.id, db=db + ) for folder_id in folder_ids: if delete_contents: diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 256b21aa5e..40b8dc78a3 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -2248,10 +2248,7 @@ async def process_chat_payload(request, form_data, user, metadata, model): folder.data["system_prompt"], form_data, metadata, user ) if "files" in folder.data: - if ( - metadata.get("params", {}).get("function_calling") - != "native" - ): + if metadata.get("params", {}).get("function_calling") != "native": form_data["files"] = [ *folder.data["files"], *form_data.get("files", []), @@ -2378,8 +2375,7 @@ async def process_chat_payload(request, form_data, user, metadata, model): if metadata.get("params", {}).get("function_calling") != "native": prompt = ( request.app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE - if request.app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE - != "" + if request.app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE != "" else DEFAULT_CODE_INTERPRETER_PROMPT ) @@ -2755,9 +2751,7 @@ async def process_chat_payload(request, form_data, user, metadata, model): metadata["system_prompt"] = ( get_content_from_message(system_message) if system_message else None ) - metadata["user_prompt"] = get_last_user_message( - form_data["messages"] - ) + metadata["user_prompt"] = get_last_user_message(form_data["messages"]) metadata["sources"] = sources[:] if sources else [] # If context is not empty, insert it into the messages @@ -4200,11 +4194,7 @@ async def streaming_chat_response_handler(response, ctx): reasoning_item["status"] = "completed" if response_tool_calls: - tool_calls.append( - _split_tool_calls( - response_tool_calls - ) - ) + tool_calls.append(_split_tool_calls(response_tool_calls)) if response.background: await response.background() @@ -4224,13 +4214,9 @@ async def streaming_chat_response_handler(response, ctx): # Use the pre-RAG system content captured before the # initial file-source injection in process_chat_payload. # This ensures restore truly undoes the RAG template. - original_system_content = metadata.get( - "system_prompt" - ) + original_system_content = metadata.get("system_prompt") if original_system_content is None: - original_system_message = get_system_message( - form_data["messages"] - ) + original_system_message = get_system_message(form_data["messages"]) original_system_content = ( get_content_from_message(original_system_message) if original_system_message @@ -4495,9 +4481,9 @@ async def streaming_chat_response_handler(response, ctx): if all_tool_call_sources and user_message: # Restore pre-RAG message state before re-applying # to prevent RAG template duplication. - original_user_message = metadata.get( - "user_prompt" - ) or user_message + original_user_message = ( + metadata.get("user_prompt") or user_message + ) set_last_user_message_content( original_user_message, form_data["messages"], @@ -4509,14 +4495,11 @@ async def streaming_chat_response_handler(response, ctx): # Combine file and tool sources into one RAG # template application. - form_data["messages"] = ( - apply_source_context_to_messages( - request, - form_data["messages"], - metadata.get("sources", []) - + all_tool_call_sources, - user_message, - ) + form_data["messages"] = apply_source_context_to_messages( + request, + form_data["messages"], + metadata.get("sources", []) + all_tool_call_sources, + user_message, ) tool_call_sources.clear() @@ -4588,8 +4571,7 @@ async def streaming_chat_response_handler(response, ctx): code = sanitize_code(code) if CODE_INTERPRETER_BLOCKED_MODULES: - blocking_code = textwrap.dedent( - f""" + blocking_code = textwrap.dedent(f""" import builtins BLOCKED_MODULES = {CODE_INTERPRETER_BLOCKED_MODULES} @@ -4605,8 +4587,7 @@ async def streaming_chat_response_handler(response, ctx): return _real_import(name, globals, locals, fromlist, level) builtins.__import__ = restricted_import - """ - ) + """) code = blocking_code + "\n" + code if ( diff --git a/backend/open_webui/utils/models.py b/backend/open_webui/utils/models.py index cb5865d88c..108cd0b4b0 100644 --- a/backend/open_webui/utils/models.py +++ b/backend/open_webui/utils/models.py @@ -199,7 +199,9 @@ async def get_all_models(request, refresh: bool = False, user: UserModel = None) base_model = base_model_lookup.get(custom_model.base_model_id) if base_model is None: - base_model = base_model_lookup.get(custom_model.base_model_id.split(":")[0]) + base_model = base_model_lookup.get( + custom_model.base_model_id.split(":")[0] + ) if base_model: owned_by = base_model.get("owned_by", "unknown") if "pipe" in base_model: diff --git a/package-lock.json b/package-lock.json index 8f5599767c..5a359dd054 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "open-webui", - "version": "0.8.8", + "version": "0.8.9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "open-webui", - "version": "0.8.8", + "version": "0.8.9", "dependencies": { "@azure/msal-browser": "^4.5.0", "@codemirror/lang-javascript": "^6.2.2", diff --git a/package.json b/package.json index 0e30237aee..49a72efa37 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "open-webui", - "version": "0.8.8", + "version": "0.8.9", "private": true, "scripts": { "dev": "npm run pyodide:fetch && vite dev --host", @@ -158,4 +158,4 @@ "node": ">=18.13.0 <=22.x.x", "npm": ">=6.0.0" } -} \ No newline at end of file +} diff --git a/src/lib/components/admin/Settings/CodeExecution.svelte b/src/lib/components/admin/Settings/CodeExecution.svelte index cad7970de1..6195672869 100644 --- a/src/lib/components/admin/Settings/CodeExecution.svelte +++ b/src/lib/components/admin/Settings/CodeExecution.svelte @@ -67,7 +67,8 @@ > {#each engines as engine} - + {/each}
@@ -193,7 +194,9 @@ > {#each engines as engine} - + {/each}
diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index b391cd1a51..8ea8641f39 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -148,8 +148,6 @@ let webSearchEnabled = false; let codeInterpreterEnabled = false; - - let showCommands = false; let generating = false; diff --git a/src/lib/components/chat/ChatControls.svelte b/src/lib/components/chat/ChatControls.svelte index f5957e40e4..aea9fa83cf 100644 --- a/src/lib/components/chat/ChatControls.svelte +++ b/src/lib/components/chat/ChatControls.svelte @@ -71,7 +71,9 @@ $: hasMessages = history?.messages && Object.keys(history.messages).length > 0; $: showControlsTab = $user?.role === 'admin' || ($user?.permissions?.chat?.controls ?? true); - $: showFilesTab = !!$selectedTerminalId || (codeInterpreterEnabled && $config?.code?.interpreter_engine !== 'jupyter'); + $: showFilesTab = + !!$selectedTerminalId || + (codeInterpreterEnabled && $config?.code?.interpreter_engine !== 'jupyter'); $: showOverviewTab = hasMessages; // Tab fallback: if active tab becomes hidden, switch to next available diff --git a/src/lib/components/chat/PyodideFileNav.svelte b/src/lib/components/chat/PyodideFileNav.svelte index 3afbd7bbe4..73a10325d0 100644 --- a/src/lib/components/chat/PyodideFileNav.svelte +++ b/src/lib/components/chat/PyodideFileNav.svelte @@ -108,7 +108,10 @@ savedPyodidePath = currentPath; try { - const res = await sendWorkerMessage({ type: 'fs:list', path: currentPath.replace(/\/$/, '') || '/' }); + const res = await sendWorkerMessage({ + type: 'fs:list', + path: currentPath.replace(/\/$/, '') || '/' + }); entries = (res.entries || []).sort((a: FileEntry, b: FileEntry) => { if (a.type !== b.type) return a.type === 'directory' ? -1 : 1; return a.name.localeCompare(b.name); @@ -247,7 +250,11 @@ payloads.push({ name: file.name, data: await file.arrayBuffer() }); } try { - await sendWorkerMessage({ type: 'fs:upload', files: payloads, dir: currentPath.replace(/\/$/, '') || '/' }); + await sendWorkerMessage({ + type: 'fs:upload', + files: payloads, + dir: currentPath.replace(/\/$/, '') || '/' + }); } catch (e) { console.error('Upload failed:', e); } @@ -347,9 +354,18 @@ on:click={() => selectedFile && downloadFile(selectedFile)} aria-label={$i18n.t('Download')} > - - - + + + @@ -370,13 +395,7 @@
{#if selectedFile} - + {:else if loading}
@@ -435,17 +454,17 @@ {/if} {#if entries.length > 0 || creatingFolder || creatingFile} -
    - {#each entries as entry (entry.name)} - - {/each} -
+
    + {#each entries as entry (entry.name)} + + {/each} +
{/if} {/if}
diff --git a/src/lib/components/layout/Sidebar.svelte b/src/lib/components/layout/Sidebar.svelte index 27e03a7869..253ba18ded 100644 --- a/src/lib/components/layout/Sidebar.svelte +++ b/src/lib/components/layout/Sidebar.svelte @@ -150,16 +150,12 @@ } // Check for duplicate names in the same parent - const siblings = Object.values(folders).filter( - (folder) => folder.parent_id === parent_id - ); + const siblings = Object.values(folders).filter((folder) => folder.parent_id === parent_id); if (siblings.find((folder) => folder.name.toLowerCase() === name.toLowerCase())) { // If a folder with the same name already exists, append a number to the name let i = 1; while ( - siblings.find( - (folder) => folder.name.toLowerCase() === `${name} ${i}`.toLowerCase() - ) + siblings.find((folder) => folder.name.toLowerCase() === `${name} ${i}`.toLowerCase()) ) { i++; } diff --git a/src/lib/components/workspace/Models/ModelEditor.svelte b/src/lib/components/workspace/Models/ModelEditor.svelte index 8978c0c00a..9deeff1027 100644 --- a/src/lib/components/workspace/Models/ModelEditor.svelte +++ b/src/lib/components/workspace/Models/ModelEditor.svelte @@ -219,8 +219,8 @@ info.params.system = system.trim() === '' ? null : system; info.params.stop = params.stop - ? (typeof params.stop === 'string' ? params.stop.split(',') : params.stop).filter( - (s) => s.trim() + ? (typeof params.stop === 'string' ? params.stop.split(',') : params.stop).filter((s) => + s.trim() ) : null; Object.keys(info.params).forEach((key) => { diff --git a/src/lib/i18n/locales/ar-BH/translation.json b/src/lib/i18n/locales/ar-BH/translation.json index 3adfdfc6d5..dff6be6fe7 100644 --- a/src/lib/i18n/locales/ar-BH/translation.json +++ b/src/lib/i18n/locales/ar-BH/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "", "Are you sure you want to delete this message?": "", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "", "Arena Models": "", "Artifacts": "", @@ -486,6 +487,7 @@ "Default User Role": "الإفتراضي صلاحيات المستخدم", "Defaults": "", "Delete": "حذف", + "Delete {{name}}": "", "Delete a model": "حذف الموديل", "Delete All": "", "Delete All Chats": "حذف جميع الدردشات", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "e.g. '30s','10m'. الوحدات الزمنية الصالحة هي 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Ollama.com \"{{searchValue}}\" أسحب من ", "Pull a model from Ollama.com": "Ollama.com سحب الموديل من ", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/ar/translation.json b/src/lib/i18n/locales/ar/translation.json index 4d6927b51c..c98f286a19 100644 --- a/src/lib/i18n/locales/ar/translation.json +++ b/src/lib/i18n/locales/ar/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "هل أنت متأكد من رغبتك في حذف هذه القناة؟", "Are you sure you want to delete this message?": "هل أنت متأكد من رغبتك في حذف هذه الرسالة؟", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "هل أنت متأكد من رغبتك في إلغاء أرشفة جميع المحادثات المؤرشفة؟", "Arena Models": "نماذج الساحة", "Artifacts": "القطع الأثرية", @@ -486,6 +487,7 @@ "Default User Role": "الإفتراضي صلاحيات المستخدم", "Defaults": "", "Delete": "حذف", + "Delete {{name}}": "", "Delete a model": "حذف الموديل", "Delete All": "", "Delete All Chats": "حذف جميع الدردشات", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "ارسم", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "e.g. '30s','10m'. الوحدات الزمنية الصالحة هي 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "تم حذف المجلد بنجاح", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "لم يتم تحديد ملف", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Ollama.com \"{{searchValue}}\" أسحب من ", "Pull a model from Ollama.com": "Ollama.com سحب الموديل من ", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "توجيه إنشاء الاستعلام", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/bg-BG/translation.json b/src/lib/i18n/locales/bg-BG/translation.json index f6792cb8fd..9d1d0ec7a1 100644 --- a/src/lib/i18n/locales/bg-BG/translation.json +++ b/src/lib/i18n/locales/bg-BG/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Сигурни ли сте, че искате да изтриете този канал?", "Are you sure you want to delete this message?": "Сигурни ли сте, че искате да изтриете това съобщение?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Сигурни ли сте, че искате да разархивирате всички архивирани чатове?", "Arena Models": "Арена Модели", "Artifacts": "Артефакти", @@ -486,6 +487,7 @@ "Default User Role": "Ролята на потребителя по подразбиране", "Defaults": "", "Delete": "Изтриване", + "Delete {{name}}": "", "Delete a model": "Изтриване на модела", "Delete All": "", "Delete All Chats": "Изтриване на всички чатове", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Рисуване", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "напр. '30с','10м'. Валидни единици са 'с', 'м', 'ч'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "Папката е изтрита успешно", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Не е избран файл", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Извади \"{{searchValue}}\" от Ollama.com", "Pull a model from Ollama.com": "Издърпайте модела от Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "Промпт за генериране на запитвания", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/bn-BD/translation.json b/src/lib/i18n/locales/bn-BD/translation.json index a348795018..df3b6aaea8 100644 --- a/src/lib/i18n/locales/bn-BD/translation.json +++ b/src/lib/i18n/locales/bn-BD/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "", "Are you sure you want to delete this message?": "", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "", "Arena Models": "", "Artifacts": "", @@ -486,6 +487,7 @@ "Default User Role": "ইউজারের ডিফল্ট পদবি", "Defaults": "", "Delete": "মুছে ফেলুন", + "Delete {{name}}": "", "Delete a model": "একটি মডেল মুছে ফেলুন", "Delete All": "", "Delete All Chats": "সব চ্যাট মুছে ফেলুন", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "যেমন '30s','10m'. সময়ের অনুমোদিত অনুমোদিত এককগুলি হচ্ছে 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Ollama.com থেকে \"{{searchValue}}\" টানুন", "Pull a model from Ollama.com": "Ollama.com থেকে একটি টেনে আনুন আনুন", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/bo-TB/translation.json b/src/lib/i18n/locales/bo-TB/translation.json index 8288ca9fcc..6a4fe45090 100644 --- a/src/lib/i18n/locales/bo-TB/translation.json +++ b/src/lib/i18n/locales/bo-TB/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "ཁྱེད་ཀྱིས་བགྲོ་གླེང་འདི་བསུབ་འདོད་ངེས་ཡིན་ནམ།", "Are you sure you want to delete this message?": "འཕྲིན་འདི་བསུབ་འདོད་ངེས་ཡིན་ནམ།", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "ཁྱེད་ཀྱིས་ཡིག་མཛོད་དུ་བཞག་པའི་ཁ་བརྡ་ཡོངས་རྫོགས་ཕྱིར་འདོན་འདོད་ངེས་ཡིན་ནམ།", "Arena Models": "Arena དཔེ་དབྱིབས།", "Artifacts": "རྫས་རྟེན།", @@ -486,6 +487,7 @@ "Default User Role": "སྔོན་སྒྲིག་བེད་སྤྱོད་མཁན་གྱི་གནས་ཚད།", "Defaults": "", "Delete": "བསུབ་པ།", + "Delete {{name}}": "", "Delete a model": "དཔེ་དབྱིབས་ཤིག་བསུབ་པ།", "Delete All": "", "Delete All Chats": "ཁ་བརྡ་ཡོངས་རྫོགས་བསུབ་པ།", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "རི་མོ་འབྲི་བ།", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "དཔེར་ན། '30s','10m'. ནུས་ལྡན་དུས་ཚོད་ཀྱི་ཚན་པ་ནི། 's', 'm', 'h' ཡིན།", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "ཡིག་སྣོད་ལེགས་པར་བསུབས་ཟིན།", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "ཡིག་ཆ་གདམ་ག་མ་བྱས།", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Ollama.com ནས་ \"{{searchValue}}\" འཐེན་པ།", "Pull a model from Ollama.com": "Ollama.com ནས་དཔེ་དབྱིབས་ཤིག་འཐེན་པ།", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "འདྲི་བ་བཟོ་སྐྲུན་གྱི་འགུལ་སློང་།", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/bs-BA/translation.json b/src/lib/i18n/locales/bs-BA/translation.json index bc8773f0d1..a62d7e5d24 100644 --- a/src/lib/i18n/locales/bs-BA/translation.json +++ b/src/lib/i18n/locales/bs-BA/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "", "Are you sure you want to delete this message?": "", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "", "Arena Models": "", "Artifacts": "", @@ -486,6 +487,7 @@ "Default User Role": "Zadana korisnička uloga", "Defaults": "", "Delete": "Izbriši", + "Delete {{name}}": "", "Delete a model": "Izbriši model", "Delete All": "", "Delete All Chats": "Izbriši sve razgovore", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "npr. '30s','10m'. Važeće vremenske jedinice su 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Povucite \"{{searchValue}}\" s Ollama.com", "Pull a model from Ollama.com": "Povucite model s Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/ca-ES/translation.json b/src/lib/i18n/locales/ca-ES/translation.json index b1b621ebfe..89228d5a78 100644 --- a/src/lib/i18n/locales/ca-ES/translation.json +++ b/src/lib/i18n/locales/ca-ES/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Estàs segur que vols eliminar aquest canal?", "Are you sure you want to delete this message?": "Estàs segur que vols eliminar aquest missatge?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "Estàs segur que vols suprimir aquesta versió? Les versions filles es tornaran a enllaçar amb la versió principal d'aquesta versió.", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Estàs segur que vols desarxivar tots els xats arxivats?", "Arena Models": "Models de l'Arena", "Artifacts": "Artefactes", @@ -486,6 +487,7 @@ "Default User Role": "Rol d'usuari per defecte", "Defaults": "Valors per defecte", "Delete": "Eliminar", + "Delete {{name}}": "", "Delete a model": "Eliminar un model", "Delete All": "Eliminar tot", "Delete All Chats": "Eliminar tots els xats", @@ -578,6 +580,7 @@ "Downloading stats...": "Descarregant estadístiques...", "Draw": "Dibuixar", "Drop any files here to upload": "Arrossega aquí qualsevol fitxer per pujar-lo", + "Drop files here": "", "Drop files here to upload": "Deixa anar els arxius aquí per pujar-los", "DuckDuckGo": "DuckDuckGo", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "p. ex. '30s','10m'. Les unitats de temps vàlides són 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "Posa el focus en l'entrada del xat", "Folder": "Carpeta", "Folder Background Image": "Imatge del fons de la carpeta", + "Folder created successfully": "", "Folder deleted successfully": "Carpeta eliminada correctament", "Folder Max File Count": "Nombre màxim d'arxius per carpeta", "Folder name": "Nom de carpeta", @@ -1304,6 +1308,7 @@ "No file selected": "No s'ha escollit cap fitxer", "No files found": "No s'han trobat arxius", "No files in this knowledge base.": "No hi ha arxius a la base de coneixement.", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "No s'han trobat funcions", "No groups found": "No s'han trobat grups", "No history available": "No hi ha historial disponible", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Obtenir \"{{searchValue}}\" de Ollama.com", "Pull a model from Ollama.com": "Obtenir un model d'Ollama.com", "Pull Model": "Obtenir un model", + "Pyodide file browser": "", "Query Generation Prompt": "Indicació per a generació de consulta", "Querying": "Consultes", "Quick Actions": "Accions ràpides", diff --git a/src/lib/i18n/locales/ceb-PH/translation.json b/src/lib/i18n/locales/ceb-PH/translation.json index 098776cc6d..b0ff5202f2 100644 --- a/src/lib/i18n/locales/ceb-PH/translation.json +++ b/src/lib/i18n/locales/ceb-PH/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "", "Are you sure you want to delete this message?": "", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "", "Arena Models": "", "Artifacts": "", @@ -486,6 +487,7 @@ "Default User Role": "Default nga Papel sa Gumagamit", "Defaults": "", "Delete": "", + "Delete {{name}}": "", "Delete a model": "Pagtangtang sa usa ka template", "Delete All": "", "Delete All Chats": "", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "p. ", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "", "Pull a model from Ollama.com": "Pagkuha ug template gikan sa Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/cs-CZ/translation.json b/src/lib/i18n/locales/cs-CZ/translation.json index e3d2f4ba85..8941640667 100644 --- a/src/lib/i18n/locales/cs-CZ/translation.json +++ b/src/lib/i18n/locales/cs-CZ/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Opravdu chcete smazat tento kanál?", "Are you sure you want to delete this message?": "Opravdu chcete smazat tuto zprávu?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Opravdu chcete zrušit archivaci všech archivovaných konverzací?", "Arena Models": "Modely pro arénu", "Artifacts": "Artefakty", @@ -486,6 +487,7 @@ "Default User Role": "Výchozí role uživatele", "Defaults": "", "Delete": "Smazat", + "Delete {{name}}": "", "Delete a model": "Smazat model", "Delete All": "", "Delete All Chats": "Smazat všechny konverzace", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Kreslit", "Drop any files here to upload": "Přetáhněte sem soubory pro nahrání", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "např. '30s','10m'. Platné časové jednotky jsou 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "Složka", "Folder Background Image": "Obrázek na pozadí složky", + "Folder created successfully": "", "Folder deleted successfully": "Složka byla úspěšně smazána", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Nebyl vybrán žádný soubor", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "Žádné funkce nenalezeny", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Stáhnout \"{{searchValue}}\" z Ollama.com", "Pull a model from Ollama.com": "Stáhnout model z Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "Instrukce pro generování dotazu", "Querying": "", "Quick Actions": "Rychlé akce", diff --git a/src/lib/i18n/locales/da-DK/translation.json b/src/lib/i18n/locales/da-DK/translation.json index ecb07cafa5..27e62191dc 100644 --- a/src/lib/i18n/locales/da-DK/translation.json +++ b/src/lib/i18n/locales/da-DK/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Er du sikker på du vil slette denne kanal?", "Are you sure you want to delete this message?": "Er du sikker på du vil slette denne besked?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Er du sikker på du vil fjerne alle arkiverede chats?", "Arena Models": "Arena Modeller", "Artifacts": "Artifakter", @@ -486,6 +487,7 @@ "Default User Role": "Brugers rolle som standard", "Defaults": "", "Delete": "Slet", + "Delete {{name}}": "", "Delete a model": "Slet en model", "Delete All": "", "Delete All Chats": "Slet alle chats", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Tegn", "Drop any files here to upload": "Drop nogen filer her for at uploade", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "f.eks. '30s', '10m'. Tilladte værdier er 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "Fokus chat-input", "Folder": "Mappe", "Folder Background Image": "Mappe baggrundsbillede", + "Folder created successfully": "", "Folder deleted successfully": "Mappe fjernet.", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Ingen fil valgt", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "Ingen funktioner fundet", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Hent \"{{searchValue}}\" fra Ollama.com", "Pull a model from Ollama.com": "Hent en model fra Ollama.com", "Pull Model": "Hent model", + "Pyodide file browser": "", "Query Generation Prompt": "Forespørgsel genererings prompt", "Querying": "Undersøger", "Quick Actions": "Hurtig-handlinger", diff --git a/src/lib/i18n/locales/de-DE/translation.json b/src/lib/i18n/locales/de-DE/translation.json index 94d544d1bf..673bcaaba4 100644 --- a/src/lib/i18n/locales/de-DE/translation.json +++ b/src/lib/i18n/locales/de-DE/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Sind Sie sicher, dass Sie diesen Kanal löschen möchten?", "Are you sure you want to delete this message?": "Sind Sie sicher, dass Sie diese Nachricht löschen möchten?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "Sind Sie sicher, dass Sie diese Version löschen wollen? Child-Versionen werden zu dem Parent dieser Version verlinkt.", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Sind Sie sicher, dass Sie alle archivierten Chats wiederherstellen möchten?", "Arena Models": "Arena-Modelle", "Artifacts": "Artefakte", @@ -486,6 +487,7 @@ "Default User Role": "Standard-Benutzerrolle", "Defaults": "Standardwerte", "Delete": "Löschen", + "Delete {{name}}": "", "Delete a model": "Ein Modell löschen", "Delete All": "Alle löschen", "Delete All Chats": "Alle Chats löschen", @@ -578,6 +580,7 @@ "Downloading stats...": "Statistik wird heruntergeladen...", "Draw": "Zeichnen", "Drop any files here to upload": "Dateien zum Hochladen hier ablegen", + "Drop files here": "", "Drop files here to upload": "Dateien zum Hochladen hier fallen lassen", "DuckDuckGo": "DuckDuckGo", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "z. B. '30s', '10m'. Gültig: 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "Chat-Eingabe fokussieren", "Folder": "Ordner", "Folder Background Image": "Ordner-Hintergrundbild", + "Folder created successfully": "", "Folder deleted successfully": "Ordner erfolgreich gelöscht", "Folder Max File Count": "Maximale Dateianzahl pro Ordner", "Folder name": "Ordnername", @@ -1304,6 +1308,7 @@ "No file selected": "Keine Datei ausgewählt", "No files found": "Keine Dateien gefunden", "No files in this knowledge base.": "Keine Dateien in diesem Wissensspeicher", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "Keine Funktionen gefunden", "No groups found": "Keine Gruppen gefunden", "No history available": "Keine History verfügbar", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "\"{{searchValue}}\" von Ollama.com laden", "Pull a model from Ollama.com": "Ein Modell von Ollama.com laden", "Pull Model": "Modell laden", + "Pyodide file browser": "", "Query Generation Prompt": "Abfrage-Generierungs-Prompt", "Querying": "Frage ab...", "Quick Actions": "Schnellaktionen", diff --git a/src/lib/i18n/locales/dg-DG/translation.json b/src/lib/i18n/locales/dg-DG/translation.json index f530299954..8774cee65e 100644 --- a/src/lib/i18n/locales/dg-DG/translation.json +++ b/src/lib/i18n/locales/dg-DG/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "", "Are you sure you want to delete this message?": "", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "", "Arena Models": "", "Artifacts": "", @@ -486,6 +487,7 @@ "Default User Role": "Default User Role", "Defaults": "", "Delete": "", + "Delete {{name}}": "", "Delete a model": "Delete a model", "Delete All": "", "Delete All Chats": "", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "e.g. '30s','10m'. Much time units are 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "", "Pull a model from Ollama.com": "Pull a wowdel from Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/el-GR/translation.json b/src/lib/i18n/locales/el-GR/translation.json index 66db5bd86c..21441dc201 100644 --- a/src/lib/i18n/locales/el-GR/translation.json +++ b/src/lib/i18n/locales/el-GR/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Είστε σίγουροι ότι θέλετε να διαγράψετε αυτό το κανάλι;", "Are you sure you want to delete this message?": "Είστε σίγουροι ότι θέλετε να διαγράψετε αυτό το μήνυμα;", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Είστε σίγουροι ότι θέλετε να απο-αρχειοθετήσετε όλες τις αρχειοθετημένες συνομιλίες;", "Arena Models": "Μοντέλα Arena", "Artifacts": "Αρχεία", @@ -486,6 +487,7 @@ "Default User Role": "Προεπιλεγμένος Ρόλος Χρήστη", "Defaults": "", "Delete": "Διαγραφή", + "Delete {{name}}": "", "Delete a model": "Διαγραφή ενός μοντέλου", "Delete All": "", "Delete All Chats": "Διαγραφή Όλων των Συνομιλιών", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Σχεδίαση", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "π.χ. '30s','10m'. Οι έγκυρες μονάδες χρόνου είναι 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "Φάκελος", "Folder Background Image": "Εικόνα Φόντου Φακέλου", + "Folder created successfully": "", "Folder deleted successfully": "Ο φάκελος διαγράφηκε με επιτυχία", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Δεν έχει επιλεγεί αρχείο", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "Δεν βρέθηκαν λειτουργίες", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Τραβήξτε \"{{searchValue}}\" από το Ollama.com", "Pull a model from Ollama.com": "Τραβήξτε ένα μοντέλο από το Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "Προτροπή Δημιουργίας Ερωτήσεων", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/en-GB/translation.json b/src/lib/i18n/locales/en-GB/translation.json index 4cc97d93cd..06b8ac6a1c 100644 --- a/src/lib/i18n/locales/en-GB/translation.json +++ b/src/lib/i18n/locales/en-GB/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "", "Are you sure you want to delete this message?": "", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "", "Arena Models": "", "Artifacts": "", @@ -486,6 +487,7 @@ "Default User Role": "", "Defaults": "", "Delete": "", + "Delete {{name}}": "", "Delete a model": "", "Delete All": "", "Delete All Chats": "", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "", "Pull a model from Ollama.com": "", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/en-US/translation.json b/src/lib/i18n/locales/en-US/translation.json index ae23cad549..77d52c6446 100644 --- a/src/lib/i18n/locales/en-US/translation.json +++ b/src/lib/i18n/locales/en-US/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "", "Are you sure you want to delete this message?": "", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "", "Arena Models": "", "Artifacts": "", @@ -486,6 +487,7 @@ "Default User Role": "", "Defaults": "", "Delete": "", + "Delete {{name}}": "", "Delete a model": "", "Delete All": "", "Delete All Chats": "", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "", @@ -1305,6 +1308,7 @@ "No file selected": "", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1512,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "", "Pull a model from Ollama.com": "", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", @@ -2136,4 +2141,4 @@ "YouTube": "", "Youtube Language": "", "Youtube Proxy URL": "" -} \ No newline at end of file +} diff --git a/src/lib/i18n/locales/es-ES/translation.json b/src/lib/i18n/locales/es-ES/translation.json index d9877b5d3b..76765f0047 100644 --- a/src/lib/i18n/locales/es-ES/translation.json +++ b/src/lib/i18n/locales/es-ES/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "¿Seguro de que quieres eliminar este canal?", "Are you sure you want to delete this message?": "¿Seguro de que quieres eliminar este mensaje? ", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "¿Seguro que desea eliminar esta versión? Las versiones secundarias se vincularán a la versión principal de esta.", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "¿Seguro de que quieres desarchivar todos los chats archivados?", "Arena Models": "Arena de Modelos", "Artifacts": "Artefactos", @@ -486,6 +487,7 @@ "Default User Role": "Rol predeterminado de los nuevos usuarios", "Defaults": "Predeterminados", "Delete": "Borrar", + "Delete {{name}}": "", "Delete a model": "Borrar un modelo", "Delete All": "Borrar Todo", "Delete All Chats": "Borrar todos los chats", @@ -578,6 +580,7 @@ "Downloading stats...": "Descargando estadísticas...", "Draw": "Dibujar", "Drop any files here to upload": "Arrastra aquí los archivos a subir.", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "DuckDuckGo", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "p.ej. '30s','10m'. Unidades de tiempo válidas son 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "Enfocar a la Entrada del Chat", "Folder": "Carpeta", "Folder Background Image": "Imagen de Fondo de la Carpeta", + "Folder created successfully": "", "Folder deleted successfully": "Carpeta eliminada correctamente", "Folder Max File Count": "Máximo Número de Ficheros en Carpeta", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "No se seleccionó archivo", "No files found": "No se encontraron archivos", "No files in this knowledge base.": "Ningún archivo en esta base de conocimiento.", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "No se encontraron funciones", "No groups found": "No se encontraron grupos", "No history available": "No hay historial disponible", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Extraer \"{{searchValue}}\" desde Ollama.com", "Pull a model from Ollama.com": "Extraer un modelo desde Ollama.com", "Pull Model": "Extraer Modelo", + "Pyodide file browser": "", "Query Generation Prompt": "Indicador para la Consulta de Generación", "Querying": "Consultando", "Quick Actions": "Acciones Rápida", diff --git a/src/lib/i18n/locales/et-EE/translation.json b/src/lib/i18n/locales/et-EE/translation.json index b133d638e7..535e195b29 100644 --- a/src/lib/i18n/locales/et-EE/translation.json +++ b/src/lib/i18n/locales/et-EE/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Kas olete kindel, et soovite selle kanali kustutada?", "Are you sure you want to delete this message?": "Kas olete kindel, et soovite selle sõnumi kustutada?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Kas olete kindel, et soovite kõik arhiveeritud vestlused arhiivist eemaldada?", "Arena Models": "Areena mudelid", "Artifacts": "Tekkinud objektid", @@ -486,6 +487,7 @@ "Default User Role": "Vaikimisi kasutaja roll", "Defaults": "", "Delete": "Kustuta", + "Delete {{name}}": "", "Delete a model": "Kustuta mudel", "Delete All": "", "Delete All Chats": "Kustuta kõik vestlused", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Joonista", "Drop any files here to upload": "Lohistage siia failid üleslaadimiseks", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "nt '30s', '10m'. Kehtivad ajaühikud on 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "Kaust", "Folder Background Image": "Kausta taustpilt", + "Folder created successfully": "", "Folder deleted successfully": "Kaust edukalt kustutatud", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Faili pole valitud", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "No functions found", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Tõmba \"{{searchValue}}\" Ollama.com-ist", "Pull a model from Ollama.com": "Tõmba mudel Ollama.com-ist", "Pull Model": "Pull Mudel", + "Pyodide file browser": "", "Query Generation Prompt": "Päringu genereerimise vihje", "Querying": "Querying", "Quick Actions": "Quick Actions", diff --git a/src/lib/i18n/locales/eu-ES/translation.json b/src/lib/i18n/locales/eu-ES/translation.json index 117a260c60..d46fe503b7 100644 --- a/src/lib/i18n/locales/eu-ES/translation.json +++ b/src/lib/i18n/locales/eu-ES/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "", "Are you sure you want to delete this message?": "", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Ziur zaude artxibatutako txat guztiak desartxibatu nahi dituzula?", "Arena Models": "Arena Ereduak", "Artifacts": "Artefaktuak", @@ -486,6 +487,7 @@ "Default User Role": "Erabiltzaile Rol Lehenetsia", "Defaults": "", "Delete": "Ezabatu", + "Delete {{name}}": "", "Delete a model": "Ezabatu eredu bat", "Delete All": "", "Delete All Chats": "Ezabatu Txat Guztiak", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Marraztu", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "adib. '30s','10m'. Denbora unitate baliodunak dira 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "Karpeta ongi ezabatu da", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Ez da fitxategirik hautatu", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Ekarri \"{{searchValue}}\" Ollama.com-etik", "Pull a model from Ollama.com": "Ekarri modelo bat Ollama.com-etik", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "Kontsulta sortzeko prompt-a", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/fa-IR/translation.json b/src/lib/i18n/locales/fa-IR/translation.json index 1bc4077445..f01fb5f7a5 100644 --- a/src/lib/i18n/locales/fa-IR/translation.json +++ b/src/lib/i18n/locales/fa-IR/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "آیا مطمئن هستید که می\u200cخواهید این کانال را حذف کنید؟", "Are you sure you want to delete this message?": "آیا مطمئن هستید که می\u200cخواهید این پیام را حذف کنید؟", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "آیا مطمئن هستید که می\u200cخواهید همه گفتگوهای بایگانی شده را از بایگانی خارج کنید؟", "Arena Models": "مدل\u200cهای آرنا", "Artifacts": "مصنوعات", @@ -486,6 +487,7 @@ "Default User Role": "نقش کاربر پیش فرض", "Defaults": "", "Delete": "حذف", + "Delete {{name}}": "", "Delete a model": "حذف یک مدل", "Delete All": "", "Delete All Chats": "حذف همه گفتگوها", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "رسم کردن", "Drop any files here to upload": "فایل\u200cها را برای آپلود به اینجا بکشید و رها کنید", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "به طور مثال '30s','10m'. واحد\u200cهای زمانی معتبر 's', 'm', 'h' هستند.", @@ -897,6 +900,7 @@ "Focus Chat Input": "فوکوس روی ورودی چت", "Folder": "پوشه", "Folder Background Image": "تصویر پس\u200cزمینه پوشه", + "Folder created successfully": "", "Folder deleted successfully": "پوشه با موفقیت حذف شد", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "فایلی انتخاب نشده است", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "هیچ تابعی یافت نشد", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "بازگرداندن \"{{searchValue}}\" از Ollama.com", "Pull a model from Ollama.com": "دریافت یک مدل از Ollama.com", "Pull Model": "کشیدن مدل", + "Pyodide file browser": "", "Query Generation Prompt": "پرامپت تولید کوئری", "Querying": "در حال پرس\u200cوجو", "Quick Actions": "اقدامات سریع", diff --git a/src/lib/i18n/locales/fi-FI/translation.json b/src/lib/i18n/locales/fi-FI/translation.json index 78d02d0aa2..a3a549fba2 100644 --- a/src/lib/i18n/locales/fi-FI/translation.json +++ b/src/lib/i18n/locales/fi-FI/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Haluatko varmasti poistaa tämän kanavan?", "Are you sure you want to delete this message?": "Haluatko varmasti poistaa tämän viestin?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "Haluatko varamsti poistaa tämän version? Alaversiot linkitetään uudelleen tämän version ylätason versioon.", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Haluatko varmasti purkaa kaikkien arkistoitujen keskustelujen arkistoinnin?", "Arena Models": "Arena-mallit", "Artifacts": "Artefaktit", @@ -486,6 +487,7 @@ "Default User Role": "Oletuskäyttäjärooli", "Defaults": "Oletukset", "Delete": "Poista", + "Delete {{name}}": "", "Delete a model": "Poista malli", "Delete All": "Poista kaikki", "Delete All Chats": "Poista kaikki keskustelut", @@ -578,6 +580,7 @@ "Downloading stats...": "Ladataa tilastoja...", "Draw": "Piirros", "Drop any files here to upload": "Pudota tähän ladattavat tiedostot", + "Drop files here": "", "Drop files here to upload": "Pudota tiedostot tähän ladataksesi", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "esim. '30s', '10m'. Kelpoiset aikayksiköt ovat 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "Kohdista keskustelu tekstikenttään", "Folder": "Kansio", "Folder Background Image": "Kansion taustakuva", + "Folder created successfully": "", "Folder deleted successfully": "Kansio poistettu onnistuneesti", "Folder Max File Count": "Kansion tiedostojen enimmäismäärä", "Folder name": "Kansion nimi", @@ -1304,6 +1308,7 @@ "No file selected": "Tiedostoa ei ole valittu", "No files found": "Tiedostoja ei löytynyt", "No files in this knowledge base.": "Tässä tietokannassa ei ole tiedostoja.", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "Funktioita ei löytynyt", "No groups found": "Ryhmiä ei löytynyt", "No history available": "Historiaa ei saatavilla", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Lataa \"{{searchValue}}\" Ollama.comista", "Pull a model from Ollama.com": "Lataa malli Ollama.comista", "Pull Model": "Lataa malli", + "Pyodide file browser": "", "Query Generation Prompt": "Kyselytulosten luontikehote", "Querying": "Kysely", "Quick Actions": "Pikatoiminnot", diff --git a/src/lib/i18n/locales/fr-CA/translation.json b/src/lib/i18n/locales/fr-CA/translation.json index d7a80ee90b..903522f047 100644 --- a/src/lib/i18n/locales/fr-CA/translation.json +++ b/src/lib/i18n/locales/fr-CA/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Êtes-vous sûr de vouloir supprimer ce canal ?", "Are you sure you want to delete this message?": "Êtes-vous sûr de vouloir supprimer ce message ?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Êtes-vous sûr de vouloir désarchiver toutes les conversations archivées?", "Arena Models": "Modèles d'arène", "Artifacts": "Artéfacts", @@ -486,6 +487,7 @@ "Default User Role": "Rôle utilisateur par défaut", "Defaults": "", "Delete": "Supprimer", + "Delete {{name}}": "", "Delete a model": "Supprimer un modèle", "Delete All": "", "Delete All Chats": "Supprimer toutes les conversations", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Match nul", "Drop any files here to upload": "Déposez des fichiers ici pour les téléverser", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "par ex. '30s', '10 min'. Les unités de temps valides sont 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "Dossier supprimé avec succès", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Aucun fichier sélectionné", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Récupérer « {{searchValue}} » depuis Ollama.com", "Pull a model from Ollama.com": "Télécharger un modèle depuis Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "Prompt de génération de requête", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/fr-FR/translation.json b/src/lib/i18n/locales/fr-FR/translation.json index c123b3d967..a226b43bc5 100644 --- a/src/lib/i18n/locales/fr-FR/translation.json +++ b/src/lib/i18n/locales/fr-FR/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Êtes-vous sûr de vouloir supprimer ce canal ?", "Are you sure you want to delete this message?": "Êtes-vous sûr de vouloir supprimer ce message ?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Êtes-vous sûr de vouloir désarchiver toutes les conversations ?", "Arena Models": "Modèles d'arène", "Artifacts": "Artéfacts", @@ -486,6 +487,7 @@ "Default User Role": "Rôle utilisateur par défaut", "Defaults": "", "Delete": "Supprimer", + "Delete {{name}}": "", "Delete a model": "Supprimer un modèle", "Delete All": "Tout supprimer", "Delete All Chats": "Supprimer toutes les conversations", @@ -578,6 +580,7 @@ "Downloading stats...": "Téléchargement des statistiques...", "Draw": "Match nul", "Drop any files here to upload": "Déposez des fichiers ici pour les téléverser", + "Drop files here": "", "Drop files here to upload": "Déposez des fichiers ici pour les téléverser", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "par ex. '30s', '10 min'. Les unités de temps valides sont 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "Activer la zone de saisie", "Folder": "Dossier", "Folder Background Image": "Image d'arrière-plan du dossier", + "Folder created successfully": "", "Folder deleted successfully": "Dossier supprimé avec succès", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Aucun fichier sélectionné", "No files found": "", "No files in this knowledge base.": "Aucun fichier dans cette base de connaissances.", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "Aucun historique disponible", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Récupérer « {{searchValue}} » depuis Ollama.com", "Pull a model from Ollama.com": "Télécharger un modèle depuis Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "Prompt de génération de requête", "Querying": "Requête en cours", "Quick Actions": "Actions rapide", diff --git a/src/lib/i18n/locales/gl-ES/translation.json b/src/lib/i18n/locales/gl-ES/translation.json index 27c9b3d58b..63b37f9391 100644 --- a/src/lib/i18n/locales/gl-ES/translation.json +++ b/src/lib/i18n/locales/gl-ES/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "¿Seguro que queres eliminar este canal?", "Are you sure you want to delete this message?": "¿Seguro que queres eliminar este mensaxe? ", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "¿Estás seguro de que quieres desArquivar todos os chats arquivados?", "Arena Models": "Area de Modelos", "Artifacts": "Artefactos", @@ -486,6 +487,7 @@ "Default User Role": "Rol por defecto para os usuarios", "Defaults": "", "Delete": "Borrar", + "Delete {{name}}": "", "Delete a model": "Borra un modelo", "Delete All": "", "Delete All Chats": "Eliminar todos os chats", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Dibujar", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "p.ej. '30s','10m'. Unidades válidas detempo son 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "Carpeta eliminada correctamente", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Ningún arquivo fué seleccionado", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Extraer \"{{searchValue}}\" de Ollama.com", "Pull a model from Ollama.com": "Obter un modelo de Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "Prompt de xeneración de consulta", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/he-IL/translation.json b/src/lib/i18n/locales/he-IL/translation.json index a6b061d054..ab44c359e8 100644 --- a/src/lib/i18n/locales/he-IL/translation.json +++ b/src/lib/i18n/locales/he-IL/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "", "Are you sure you want to delete this message?": "", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "", "Arena Models": "", "Artifacts": "", @@ -486,6 +487,7 @@ "Default User Role": "תפקיד משתמש ברירת מחדל", "Defaults": "", "Delete": "מחק", + "Delete {{name}}": "", "Delete a model": "מחק מודל", "Delete All": "", "Delete All Chats": "מחק את כל הצ'אטים", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "למשל '30s', '10m'. יחידות זמן חוקיות הן 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "משוך \"{{searchValue}}\" מ-Ollama.com", "Pull a model from Ollama.com": "משוך מודל מ-Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/hi-IN/translation.json b/src/lib/i18n/locales/hi-IN/translation.json index d1576fca2d..54938dabca 100644 --- a/src/lib/i18n/locales/hi-IN/translation.json +++ b/src/lib/i18n/locales/hi-IN/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "", "Are you sure you want to delete this message?": "", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "", "Arena Models": "", "Artifacts": "", @@ -486,6 +487,7 @@ "Default User Role": "डिफ़ॉल्ट उपयोगकर्ता भूमिका", "Defaults": "", "Delete": "डिलीट", + "Delete {{name}}": "", "Delete a model": "एक मॉडल हटाएँ", "Delete All": "", "Delete All Chats": "सभी चैट हटाएं", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "जैसे '30s', '10m', मान्य समय इकाइयाँ 's', 'm', 'h' हैं।", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "\"{{searchValue}}\" को Ollama.com से खींचें", "Pull a model from Ollama.com": "Ollama.com से एक मॉडल खींचें", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/hr-HR/translation.json b/src/lib/i18n/locales/hr-HR/translation.json index e6dadaba52..5bacffb41f 100644 --- a/src/lib/i18n/locales/hr-HR/translation.json +++ b/src/lib/i18n/locales/hr-HR/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "", "Are you sure you want to delete this message?": "", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "", "Arena Models": "", "Artifacts": "", @@ -486,6 +487,7 @@ "Default User Role": "Zadana korisnička uloga", "Defaults": "", "Delete": "Izbriši", + "Delete {{name}}": "", "Delete a model": "Izbriši model", "Delete All": "", "Delete All Chats": "Izbriši sve razgovore", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "npr. '30s','10m'. Važeće vremenske jedinice su 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Povucite \"{{searchValue}}\" s Ollama.com", "Pull a model from Ollama.com": "Povucite model s Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/hu-HU/translation.json b/src/lib/i18n/locales/hu-HU/translation.json index 0a210ed323..da7cdd4481 100644 --- a/src/lib/i18n/locales/hu-HU/translation.json +++ b/src/lib/i18n/locales/hu-HU/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Biztosan törölni szeretnéd ezt a csatornát?", "Are you sure you want to delete this message?": "Biztosan törölni szeretnéd ezt az üzenetet?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Biztosan vissza szeretnéd állítani az összes archivált csevegést?", "Arena Models": "Arena modellek", "Artifacts": "Műtermékek", @@ -486,6 +487,7 @@ "Default User Role": "Alapértelmezett felhasználói szerep", "Defaults": "", "Delete": "Törlés", + "Delete {{name}}": "", "Delete a model": "Modell törlése", "Delete All": "", "Delete All Chats": "Minden beszélgetés törlése", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Rajzolás", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "pl. '30s','10m'. Érvényes időegységek: 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "Mappa sikeresen törölve", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Nincs kiválasztva fájl", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "\"{{searchValue}}\" letöltése az Ollama.com-ról", "Pull a model from Ollama.com": "Modell letöltése az Ollama.com-ról", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "Lekérdezés generálási prompt", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/id-ID/translation.json b/src/lib/i18n/locales/id-ID/translation.json index 6e78717c3f..2ce4e232bb 100644 --- a/src/lib/i18n/locales/id-ID/translation.json +++ b/src/lib/i18n/locales/id-ID/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "", "Are you sure you want to delete this message?": "", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "", "Arena Models": "", "Artifacts": "", @@ -486,6 +487,7 @@ "Default User Role": "Peran Pengguna Default", "Defaults": "", "Delete": "Menghapus", + "Delete {{name}}": "", "Delete a model": "Menghapus model", "Delete All": "", "Delete All Chats": "Menghapus Semua Obrolan", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "misalnya '30-an', '10m'. Satuan waktu yang valid adalah 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Tidak ada file yang dipilih", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Tarik \"{{searchValue}}\" dari Ollama.com", "Pull a model from Ollama.com": "Tarik model dari Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/ie-GA/translation.json b/src/lib/i18n/locales/ie-GA/translation.json index d711c5fbe1..e12c645495 100644 --- a/src/lib/i18n/locales/ie-GA/translation.json +++ b/src/lib/i18n/locales/ie-GA/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "An bhfuil tú cinnte gur mhaith leat an cainéal seo a scriosadh?", "Are you sure you want to delete this message?": "An bhfuil tú cinnte gur mhaith leat an teachtaireacht seo a scriosadh?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "An bhfuil tú cinnte gur mian leat an leagan seo a scriosadh? Déanfar leaganacha linbh a athnascadh le tuismitheoir an leagain seo.", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "An bhfuil tú cinnte gur mhaith leat gach comhrá cartlainne a dhíchartlannú?", "Arena Models": "Samhlacha Réimse", "Artifacts": "Déantáin", @@ -486,6 +487,7 @@ "Default User Role": "Ról Úsáideora Réamhshocraithe", "Defaults": "Réamhshocruithe", "Delete": "Scrios", + "Delete {{name}}": "", "Delete a model": "Scrios samhail", "Delete All": "Scrios Gach Rud", "Delete All Chats": "Scrios Gach Comhrá", @@ -578,6 +580,7 @@ "Downloading stats...": "Ag íoslódáil staitisticí...", "Draw": "Tarraing", "Drop any files here to upload": "Scaoil aon chomhaid anseo le huaslódáil", + "Drop files here": "", "Drop files here to upload": "Scaoil comhaid anseo le huaslódáil", "DuckDuckGo": "DuckDuckGo", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "m.sh. '30s', '10m'. Is iad aonaid ama bailí ná 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "Dírigh ar Ionchur Comhrá", "Folder": "Fillteán", "Folder Background Image": "Íomhá Chúlra Fillteáin", + "Folder created successfully": "", "Folder deleted successfully": "Scriosadh an fillteán go rathúil", "Folder Max File Count": "Uasmhéid Líon Comhad Fillteán", "Folder name": "Ainm fillteáin", @@ -1304,6 +1308,7 @@ "No file selected": "Níl aon chomhad roghnaithe", "No files found": "Níor aimsíodh aon chomhaid", "No files in this knowledge base.": "Níl aon chomhaid sa bhunachar eolais seo.", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "Níor aimsíodh aon fheidhmeanna", "No groups found": "Níor aimsíodh aon ghrúpaí", "No history available": "Níl aon stair ar fáil", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Tarraing \"{{searchValue}}\" ó Ollama.com", "Pull a model from Ollama.com": "Tarraing samhail ó Ollama.com", "Pull Model": "Samhail Tarraingthe", + "Pyodide file browser": "", "Query Generation Prompt": "Cuirí Ginearáil Ceisteanna", "Querying": "Ag fiosrú", "Quick Actions": "Gníomhartha Tapa", diff --git a/src/lib/i18n/locales/it-IT/translation.json b/src/lib/i18n/locales/it-IT/translation.json index 56cd7836b3..135cca43b6 100644 --- a/src/lib/i18n/locales/it-IT/translation.json +++ b/src/lib/i18n/locales/it-IT/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Sei sicuro di voler eliminare questo canale?", "Are you sure you want to delete this message?": "Sei sicuro di voler eliminare questo messaggio?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Sei sicuro di voler disarchiviare tutte le chat archiviate?", "Arena Models": "Modelli Arena", "Artifacts": "Artefatti", @@ -486,6 +487,7 @@ "Default User Role": "Ruolo utente predefinito", "Defaults": "", "Delete": "Elimina", + "Delete {{name}}": "", "Delete a model": "Elimina un modello", "Delete All": "", "Delete All Chats": "Elimina tutte le chat", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Disegna", "Drop any files here to upload": "Rilascia qui i file per caricarli", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "ad esempio '30s','10m'. Le unità di tempo valide sono 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "Cartella rimossa con successo", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Nessun file selezionato", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Estrai \"{{searchValue}}\" da Ollama.com", "Pull a model from Ollama.com": "Estrai un modello da Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "Prompt di Generazione Query", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/ja-JP/translation.json b/src/lib/i18n/locales/ja-JP/translation.json index 0532d958b8..71a84cbf04 100644 --- a/src/lib/i18n/locales/ja-JP/translation.json +++ b/src/lib/i18n/locales/ja-JP/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "このチャンネルを削除しますか?", "Are you sure you want to delete this message?": "このメッセージを削除しますか?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "すべてのアーカイブされたチャットをアンアーカイブしますか?", "Arena Models": "Arenaモデル", "Artifacts": "アーティファクト", @@ -486,6 +487,7 @@ "Default User Role": "デフォルトのユーザー役割", "Defaults": "", "Delete": "削除", + "Delete {{name}}": "", "Delete a model": "モデルを削除", "Delete All": "", "Delete All Chats": "すべてのチャットを削除", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "引き分け", "Drop any files here to upload": "ここにファイルをドロップしてアップロード", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "例: '30s'、'10m'。有効な時間単位は 's'、'm'、'h' です。", @@ -897,6 +900,7 @@ "Focus Chat Input": "チャット入力欄にフォーカス", "Folder": "フォルダー", "Folder Background Image": "フォルダーの背景画像", + "Folder created successfully": "", "Folder deleted successfully": "フォルダー削除が成功しました。", "Folder Max File Count": "フォルダー内の最大ファイル数", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "ファイルが選択されていません", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "functionsが見つかりません", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Ollama.com から \"{{searchValue}}\" をプル", "Pull a model from Ollama.com": "Ollama.com からモデルをプル", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "クエリ生成プロンプト", "Querying": "照会中", "Quick Actions": "クイックアクション", diff --git a/src/lib/i18n/locales/ka-GE/translation.json b/src/lib/i18n/locales/ka-GE/translation.json index 78cf199339..5775c767e4 100644 --- a/src/lib/i18n/locales/ka-GE/translation.json +++ b/src/lib/i18n/locales/ka-GE/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "მართლა გნებავთ ამ არხის წაშლა?", "Are you sure you want to delete this message?": "მართლა გნებავთ ამ შეტყობინების წასლა?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "", "Arena Models": "არენის მოდელები", "Artifacts": "არტეფაქტები", @@ -486,6 +487,7 @@ "Default User Role": "მომხმარებლის ნაგულისხმევი როლი", "Defaults": "", "Delete": "წაშლა", + "Delete {{name}}": "", "Delete a model": "მოდელის წაშლა", "Delete All": "", "Delete All Chats": "ყველა ჩატის წაშლა", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "ხატვა", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "მაგ: '30წ', '10მ'. მოქმედი დროის ერთეულები: 'წ', 'წთ', 'სთ'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "საქაღალდე", "Folder Background Image": "საქაღალდის ფონის სურათი", + "Folder created successfully": "", "Folder deleted successfully": "საქაღალდე წარმატებით წაიშალა", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "ფაილი არჩეული არაა", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "ფუნქციები აღმოჩენილი არაა", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "\"{{searchValue}}\"-ის გადმოწერა Ollama.com-იდან", "Pull a model from Ollama.com": "მოდელის გადმოწერა Ollama.com-დან", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "მოთხოვნა", "Quick Actions": "სწრაფი მოქმედებები", diff --git a/src/lib/i18n/locales/kab-DZ/translation.json b/src/lib/i18n/locales/kab-DZ/translation.json index ee36320599..7132052c02 100644 --- a/src/lib/i18n/locales/kab-DZ/translation.json +++ b/src/lib/i18n/locales/kab-DZ/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Tetḥeqqeḍ tebɣiḍ ad tekkseḍ targa-a?", "Are you sure you want to delete this message?": "Tetḥeqqeḍ tebɣiḍ ad tekkseḍ izen-a?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Tetḥeqqemt tebɣamt ad d-tekksemt akk iqecwalen iarkasen?", "Arena Models": "Timudmiwin n Arena", "Artifacts": "Tarkisant", @@ -486,6 +487,7 @@ "Default User Role": "Tamlilt n useqdac amezwar", "Defaults": "", "Delete": "Kkes", + "Delete {{name}}": "", "Delete a model": "Kkes tamudemt", "Delete All": "", "Delete All Chats": "Kkes akk idiwenniyen", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Suneɣ", "Drop any files here to upload": "Ssers-d ifuyla da akken ad ten-tessaliḍ", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "e.g. '30s','10m'. Tiyunin n wakud ameɣtu d 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "Akaram", "Folder Background Image": "Tugna n ugilal n ukaram", + "Folder created successfully": "", "Folder deleted successfully": "Akaram-nni yettwakkes akken iwata", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Ulac afaylu i yettwafernen", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Awway n \"{{searchValue}}\" seg Ollama.com", "Pull a model from Ollama.com": "Zdem-d tamudemt seg Ollama.com", "Pull Model": "Zdem-d tamudemt", + "Pyodide file browser": "", "Query Generation Prompt": "Aneftaɣ n usirew n tuttra", "Querying": "", "Quick Actions": "Tigawin tiruradin", diff --git a/src/lib/i18n/locales/ko-KR/translation.json b/src/lib/i18n/locales/ko-KR/translation.json index 234638867c..cd847b89ce 100644 --- a/src/lib/i18n/locales/ko-KR/translation.json +++ b/src/lib/i18n/locales/ko-KR/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "정말 이 채널을 삭제하시겠습니까?", "Are you sure you want to delete this message?": "정말 이 메시지를 삭제하시겠습니까?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "정말 보관된 모든 채팅을 보관 해제하시겠습니까?", "Arena Models": "Arena 모델", "Artifacts": "아티팩트", @@ -486,6 +487,7 @@ "Default User Role": "기본 사용자 역할", "Defaults": "", "Delete": "삭제", + "Delete {{name}}": "", "Delete a model": "모델 삭제", "Delete All": "", "Delete All Chats": "모든 채팅 삭제", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "그리기", "Drop any files here to upload": "여기에 파일을 끌어다 놓아 업로드하세요", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "예: '30초','10분'. 올바른 시간 단위는 '초', '분', '시'입니다.", @@ -897,6 +900,7 @@ "Focus Chat Input": "채팅 입력창에 포커스", "Folder": "폴더", "Folder Background Image": "폴더 배경 이미지", + "Folder created successfully": "", "Folder deleted successfully": "성공적으로 폴더가 삭제되었습니다", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "파일이 선택되지 않았습니다", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "함수를 찾을 수 없습니다", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Ollama.com에서 \"{{searchValue}}\" 가져오기", "Pull a model from Ollama.com": "Ollama.com에서 모델 가져오기(pull)", "Pull Model": "모델 pull", + "Pyodide file browser": "", "Query Generation Prompt": "쿼리 생성 프롬프트", "Querying": "쿼리 진행중", "Quick Actions": "빠른 작업", diff --git a/src/lib/i18n/locales/lt-LT/translation.json b/src/lib/i18n/locales/lt-LT/translation.json index b6195ff803..8479aa0f6d 100644 --- a/src/lib/i18n/locales/lt-LT/translation.json +++ b/src/lib/i18n/locales/lt-LT/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "", "Are you sure you want to delete this message?": "", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "", "Arena Models": "", "Artifacts": "", @@ -486,6 +487,7 @@ "Default User Role": "Numatytoji naudotojo rolė", "Defaults": "", "Delete": "ištrinti", + "Delete {{name}}": "", "Delete a model": "Ištrinti modėlį", "Delete All": "", "Delete All Chats": "Ištrinti visus pokalbius", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "pvz. '30s', '10m'. Laiko vienetai yra 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Nėra pasirinktų dokumentų", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Rasti \"{{searchValue}}\" iš Ollama.com", "Pull a model from Ollama.com": "Gauti modelį iš Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/lv-LV/translation.json b/src/lib/i18n/locales/lv-LV/translation.json index 1d1f4724ae..07202c58a6 100644 --- a/src/lib/i18n/locales/lv-LV/translation.json +++ b/src/lib/i18n/locales/lv-LV/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Vai tiešām vēlaties dzēst šo kanālu?", "Are you sure you want to delete this message?": "Vai tiešām vēlaties dzēst šo ziņojumu?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Vai tiešām vēlaties atarhivēt visas arhivētās tērzēšanas?", "Arena Models": "Arēnas modeļi", "Artifacts": "Artefakti", @@ -486,6 +487,7 @@ "Default User Role": "Noklusējuma lietotāja loma", "Defaults": "", "Delete": "Dzēst", + "Delete {{name}}": "", "Delete a model": "Dzēst modeli", "Delete All": "", "Delete All Chats": "Dzēst visas tērzēšanas", @@ -578,6 +580,7 @@ "Downloading stats...": "Lejupielādē statistiku...", "Draw": "Zīmēt", "Drop any files here to upload": "Nometiet jebkurus failus šeit, lai augšupielādētu", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "DuckDuckGo", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "piem., '30s','10m'. Derīgas laika vienības ir 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "Fokusēt tērzēšanas ievadi", "Folder": "Mape", "Folder Background Image": "Mapes fona attēls", + "Folder created successfully": "", "Folder deleted successfully": "Mape veiksmīgi dzēsta", "Folder Max File Count": "Mapes maksimālais failu skaits", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Fails nav izvēlēts", "No files found": "", "No files in this knowledge base.": "Šajā zināšanu bāzē nav failu.", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "Funkcijas nav atrastas", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Lejupielādēt \"{{searchValue}}\" no Ollama.com", "Pull a model from Ollama.com": "Lejupielādēt modeli no Ollama.com", "Pull Model": "Lejupielādēt modeli", + "Pyodide file browser": "", "Query Generation Prompt": "Vaicājuma ģenerēšanas uzvedne", "Querying": "Vaicā", "Quick Actions": "Ātrās darbības", diff --git a/src/lib/i18n/locales/ms-MY/translation.json b/src/lib/i18n/locales/ms-MY/translation.json index b6459c4817..4f05a58d67 100644 --- a/src/lib/i18n/locales/ms-MY/translation.json +++ b/src/lib/i18n/locales/ms-MY/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "", "Are you sure you want to delete this message?": "", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "", "Arena Models": "", "Artifacts": "", @@ -486,6 +487,7 @@ "Default User Role": "Peranan Pengguna Lalai", "Defaults": "", "Delete": "Padam", + "Delete {{name}}": "", "Delete a model": "Padam Model", "Delete All": "", "Delete All Chats": "Padam Semua Perbualan", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "cth '30s','10m'. Unit masa yang sah ialah 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Tiada fail dipilih", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Tarik \"{{ searchValue }}\" daripada Ollama.com", "Pull a model from Ollama.com": "Tarik model dari Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/nb-NO/translation.json b/src/lib/i18n/locales/nb-NO/translation.json index d4ced2a235..b7e521cd93 100644 --- a/src/lib/i18n/locales/nb-NO/translation.json +++ b/src/lib/i18n/locales/nb-NO/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Er du sikker på at du vil slette denne kanalen?", "Are you sure you want to delete this message?": "Er du sikker på at du vil slette denne meldingen?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Er du sikker på at du vil oppheve arkiveringen av alle arkiverte chatter?", "Arena Models": "Arena-modeller", "Artifacts": "Artifakter", @@ -486,6 +487,7 @@ "Default User Role": "Standard brukerrolle", "Defaults": "", "Delete": "Slett", + "Delete {{name}}": "", "Delete a model": "Slett en modell", "Delete All": "", "Delete All Chats": "Slett alle chatter", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Tegne", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "f.eks. '30s','10m'. Gyldige tidsenheter er 's', 'm', 't'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "Mappe slettet", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Ingen fil valgt", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Hent {{searchValue}} fra Ollama.com", "Pull a model from Ollama.com": "Hent en modell fra Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "Ledetekst for genering av spørringer", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/nl-NL/translation.json b/src/lib/i18n/locales/nl-NL/translation.json index 886395fea4..7013db4a44 100644 --- a/src/lib/i18n/locales/nl-NL/translation.json +++ b/src/lib/i18n/locales/nl-NL/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Weet je zeker dat je dit kanaal wil verwijderen?", "Are you sure you want to delete this message?": "Weet je zeker dat je dit bericht wil verwijderen?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Weet je zeker dat je alle gearchiveerde chats wil onarchiveren?", "Arena Models": "Arenamodellen", "Artifacts": "Artefacten", @@ -486,6 +487,7 @@ "Default User Role": "Standaard gebruikersrol", "Defaults": "", "Delete": "Verwijderen", + "Delete {{name}}": "", "Delete a model": "Verwijder een model", "Delete All": "", "Delete All Chats": "Verwijder alle chats", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Teken", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "bijv. '30s', '10m'. Geldige tijdseenheden zijn 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "Map succesvol verwijderd", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Geen bestand geselecteerd", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Haal \"{{searchValue}}\" uit Ollama.com", "Pull a model from Ollama.com": "Haal een model van Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "Vraaggeneratieprompt", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/pa-IN/translation.json b/src/lib/i18n/locales/pa-IN/translation.json index 3edbf74bd8..b824faf43d 100644 --- a/src/lib/i18n/locales/pa-IN/translation.json +++ b/src/lib/i18n/locales/pa-IN/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "", "Are you sure you want to delete this message?": "", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "", "Arena Models": "", "Artifacts": "", @@ -486,6 +487,7 @@ "Default User Role": "ਮੂਲ ਉਪਭੋਗਤਾ ਭੂਮਿਕਾ", "Defaults": "", "Delete": "ਮਿਟਾਓ", + "Delete {{name}}": "", "Delete a model": "ਇੱਕ ਮਾਡਲ ਮਿਟਾਓ", "Delete All": "", "Delete All Chats": "ਸਾਰੀਆਂ ਚੈਟਾਂ ਨੂੰ ਮਿਟਾਓ", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "ਉਦਾਹਰਣ ਲਈ '30ਸ','10ਮਿ'. ਸਹੀ ਸਮਾਂ ਇਕਾਈਆਂ ਹਨ 'ਸ', 'ਮ', 'ਘੰ'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "ਓਲਾਮਾ.ਕਾਮ ਤੋਂ \"{{searchValue}}\" ਖਿੱਚੋ", "Pull a model from Ollama.com": "ਓਲਾਮਾ.ਕਾਮ ਤੋਂ ਇੱਕ ਮਾਡਲ ਖਿੱਚੋ", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/pl-PL/translation.json b/src/lib/i18n/locales/pl-PL/translation.json index da19789867..d2420efd8c 100644 --- a/src/lib/i18n/locales/pl-PL/translation.json +++ b/src/lib/i18n/locales/pl-PL/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Czy na pewno chcesz usunąć ten kanał?", "Are you sure you want to delete this message?": "Czy na pewno chcesz usunąć tę wiadomość?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Czy na pewno chcesz przywrócić wszystkie czaty?", "Arena Models": "Modele Arena", "Artifacts": "Artefakty", @@ -486,6 +487,7 @@ "Default User Role": "Domyślna rola użytkownika", "Defaults": "", "Delete": "Usuń", + "Delete {{name}}": "", "Delete a model": "Usuń model", "Delete All": "", "Delete All Chats": "Usuń wszystkie czaty", @@ -578,6 +580,7 @@ "Downloading stats...": "Pobieranie statystyk...", "Draw": "Remis", "Drop any files here to upload": "Upuść pliki tutaj, aby przesłać", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "DuckDuckGo", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "np. '30s','10m'. Jednostki: 's' (sek), 'm' (min), 'h' (godz).", @@ -897,6 +900,7 @@ "Focus Chat Input": "Skupienie na polu czatu", "Folder": "Folder", "Folder Background Image": "Tło folderu", + "Folder created successfully": "", "Folder deleted successfully": "Folder usunięty pomyślnie", "Folder Max File Count": "Maks. liczba plików w folderze", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Nie wybrano pliku", "No files found": "", "No files in this knowledge base.": "Brak plików w tej bazie wiedzy.", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "Nie znaleziono funkcji", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Pobierz \"{{searchValue}}\" z Ollama.com", "Pull a model from Ollama.com": "Pobierz model z Ollama.com", "Pull Model": "Pobierz Model", + "Pyodide file browser": "", "Query Generation Prompt": "Prompt generowania zapytania", "Querying": "Odpytywanie", "Quick Actions": "Szybkie akcje", diff --git a/src/lib/i18n/locales/pt-BR/translation.json b/src/lib/i18n/locales/pt-BR/translation.json index 74d0febaf7..2d69ed5a3a 100644 --- a/src/lib/i18n/locales/pt-BR/translation.json +++ b/src/lib/i18n/locales/pt-BR/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Tem certeza de que deseja excluir este canal?", "Are you sure you want to delete this message?": "Tem certeza de que deseja excluir esta mensagem?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "Tem certeza de que deseja excluir esta versão? As versões filhas serão vinculadas novamente à versão pai.", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Você tem certeza que deseja desarquivar todos os chats arquivados?", "Arena Models": "Arena de Modelos", "Artifacts": "Artefatos", @@ -486,6 +487,7 @@ "Default User Role": "Padrão para novos usuários", "Defaults": "Padrões", "Delete": "Excluir", + "Delete {{name}}": "", "Delete a model": "Excluir um modelo", "Delete All": "Excluir tudo", "Delete All Chats": "Excluir Todos os Chats", @@ -578,6 +580,7 @@ "Downloading stats...": "Baixando estatísticas...", "Draw": "Empate", "Drop any files here to upload": "Solte qualquer arquivo aqui para fazer upload", + "Drop files here": "", "Drop files here to upload": "Solte os arquivos aqui para fazer upload", "DuckDuckGo": "DuckDuckGo", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "por exemplo, '30s', '10m'. Unidades de tempo válidas são 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "Foco na janela do Chat", "Folder": "Pasta", "Folder Background Image": "Imagem de fundo da pasta", + "Folder created successfully": "", "Folder deleted successfully": "Pasta excluída com sucesso", "Folder Max File Count": "Contagem máxima de arquivos por pasta", "Folder name": "Nome da pasta", @@ -1304,6 +1308,7 @@ "No file selected": "Nenhum arquivo selecionado", "No files found": "Nenhum arquivo encontrado", "No files in this knowledge base.": "Não existem arquivos nesta base de conhecimento.", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "Nenhuma função encontrada", "No groups found": "Nenhum grupo encontrado", "No history available": "Não há histórico disponível.", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Obter \"{{searchValue}}\" de Ollama.com", "Pull a model from Ollama.com": "Obter um modelo de Ollama.com", "Pull Model": "Obter Modelo", + "Pyodide file browser": "", "Query Generation Prompt": "Prompt de Geração de Consulta", "Querying": "Consultando", "Quick Actions": "Ações rápidas", diff --git a/src/lib/i18n/locales/pt-PT/translation.json b/src/lib/i18n/locales/pt-PT/translation.json index dc7efc5700..b45ec49cc1 100644 --- a/src/lib/i18n/locales/pt-PT/translation.json +++ b/src/lib/i18n/locales/pt-PT/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "", "Are you sure you want to delete this message?": "", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "", "Arena Models": "", "Artifacts": "", @@ -486,6 +487,7 @@ "Default User Role": "Função de Utilizador Padrão", "Defaults": "", "Delete": "Apagar", + "Delete {{name}}": "", "Delete a model": "Apagar um modelo", "Delete All": "", "Delete All Chats": "Apagar todas as conversas", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "por exemplo, '30s', '10m'. Unidades de tempo válidas são 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Puxar \"{{searchValue}}\" do Ollama.com", "Pull a model from Ollama.com": "Puxar um modelo do Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/ro-RO/translation.json b/src/lib/i18n/locales/ro-RO/translation.json index 2b953f16bb..37cc71aa3c 100644 --- a/src/lib/i18n/locales/ro-RO/translation.json +++ b/src/lib/i18n/locales/ro-RO/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Ești sigur că vrei să ștergi acest canal?", "Are you sure you want to delete this message?": "Ești sigur că vrei să ștergi acest mesaj?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Ești sigur că vrei să dezarhivezi toate conversațiile arhivate?", "Arena Models": "Arena Models", "Artifacts": "Artefacte", @@ -486,6 +487,7 @@ "Default User Role": "Rolul Implicit al Utilizatorului", "Defaults": "", "Delete": "Șterge", + "Delete {{name}}": "", "Delete a model": "Șterge un model", "Delete All": "", "Delete All Chats": "Șterge Toate Conversațiile", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Desenează", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "de ex. '30s', '10m'. Unitățile de timp valide sunt 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "Folder șters cu succes", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Nu a fost selectat niciun fișier", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Extrage \"{{searchValue}}\" de pe Ollama.com", "Pull a model from Ollama.com": "Extrage un model de pe Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/ru-RU/translation.json b/src/lib/i18n/locales/ru-RU/translation.json index 7e36725824..99a5189ae0 100644 --- a/src/lib/i18n/locales/ru-RU/translation.json +++ b/src/lib/i18n/locales/ru-RU/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Вы уверены, что хотите удалить этот канал?", "Are you sure you want to delete this message?": "Вы уверены, что хотите удалить это сообщение?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Вы уверены, что хотите разархивировать все заархивированные чаты?", "Arena Models": "Арена моделей", "Artifacts": "Артефакты", @@ -486,6 +487,7 @@ "Default User Role": "Роль пользователя по умолчанию", "Defaults": "", "Delete": "Удалить", + "Delete {{name}}": "", "Delete a model": "Удалить модель", "Delete All": "Удалить ВСЕ", "Delete All Chats": "Удалить ВСЕ Чаты", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Рисовать", "Drop any files here to upload": "Переместите сюда любые файлы для загрузки", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "например, '30s','10m'. Допустимые единицы времени: 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "Фоновое изображение папки", + "Folder created successfully": "", "Folder deleted successfully": "Папка успешно удалена", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Файлы не выбраны", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Загрузить \"{{searchValue}}\" с Ollama.com", "Pull a model from Ollama.com": "Загрузить модель с Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "Запрос на генерацию промпта", "Querying": "Запрос", "Quick Actions": "Быстрые действия", diff --git a/src/lib/i18n/locales/sk-SK/translation.json b/src/lib/i18n/locales/sk-SK/translation.json index 631818be15..693e6734fb 100644 --- a/src/lib/i18n/locales/sk-SK/translation.json +++ b/src/lib/i18n/locales/sk-SK/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "", "Are you sure you want to delete this message?": "", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "", "Arena Models": "Arena modely", "Artifacts": "Artefakty", @@ -486,6 +487,7 @@ "Default User Role": "Predvolená rola užívateľa", "Defaults": "", "Delete": "Odstrániť", + "Delete {{name}}": "", "Delete a model": "Odstrániť model.", "Delete All": "", "Delete All Chats": "Odstrániť všetky konverzácie", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Nakresliť", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "napr. '30s','10m'. Platné časové jednotky sú 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "Priečinok", "Folder Background Image": "Obrázok pozadia priečinku", + "Folder created successfully": "", "Folder deleted successfully": "Priečinok bol úspešne vymazaný", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Nebola vybratá žiadna súbor", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Stiahnite \"{{searchValue}}\" z Ollama.com", "Pull a model from Ollama.com": "Stiahnite model z Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/sr-RS/translation.json b/src/lib/i18n/locales/sr-RS/translation.json index 1a0a7bd106..2146eec353 100644 --- a/src/lib/i18n/locales/sr-RS/translation.json +++ b/src/lib/i18n/locales/sr-RS/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Да ли сигурно желите обрисати овај канал?", "Are you sure you want to delete this message?": "Да ли сигурно желите обрисати ову поруку?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Да ли сигурно желите деархивирати све архиве?", "Arena Models": "Модели са Арене", "Artifacts": "Артефакти", @@ -486,6 +487,7 @@ "Default User Role": "Подразумевана улога корисника", "Defaults": "", "Delete": "Обриши", + "Delete {{name}}": "", "Delete a model": "Обриши модел", "Delete All": "", "Delete All Chats": "Обриши сва ћаскања", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Нацртај", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "нпр. '30s', '10m'. Важеће временске јединице су 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Повуците \"{{searchValue}}\" са Ollama.com", "Pull a model from Ollama.com": "Повуците модел са Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/sv-SE/translation.json b/src/lib/i18n/locales/sv-SE/translation.json index 1459d67bf8..2bd95feb58 100644 --- a/src/lib/i18n/locales/sv-SE/translation.json +++ b/src/lib/i18n/locales/sv-SE/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Är du säker på att du vill radera denna kanal?", "Are you sure you want to delete this message?": "Är du säker på att du vill radera detta meddelande?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Är du säker på att du vill avarkivera alla arkiverade chattar?", "Arena Models": "Arenamodeller", "Artifacts": "Artefakter", @@ -486,6 +487,7 @@ "Default User Role": "Standardanvändarroll", "Defaults": "", "Delete": "Radera", + "Delete {{name}}": "", "Delete a model": "Ta bort en modell", "Delete All": "", "Delete All Chats": "Ta bort alla chattar", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Rita", "Drop any files here to upload": "Släpp alla filer här för att ladda upp", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "t.ex. '30s', '10m'. Giltiga tidsenheter är 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "Mapp", "Folder Background Image": "Bakgrundsbild till mappen", + "Folder created successfully": "", "Folder deleted successfully": "Mappen har tagits bort", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Ingen fil vald", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "Inga funktioner hittades", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Ladda ner \"{{searchValue}}\" från Ollama.com", "Pull a model from Ollama.com": "Ladda ner en modell från Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "Prompt för frågegenerering", "Querying": "Frågar", "Quick Actions": "Snabbåtgärder", diff --git a/src/lib/i18n/locales/th-TH/translation.json b/src/lib/i18n/locales/th-TH/translation.json index 4092f0e7fd..e2b451c7c2 100644 --- a/src/lib/i18n/locales/th-TH/translation.json +++ b/src/lib/i18n/locales/th-TH/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "คุณแน่ใจหรือว่าต้องการลบช่องนี้?", "Are you sure you want to delete this message?": "คุณแน่ใจหรือว่าต้องการลบข้อความนี้?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "คุณแน่ใจหรือว่าต้องการยกเลิกการเก็บถาวรแชททั้งหมด?", "Arena Models": "โมเดลใน Arena", "Artifacts": "Artifacts", @@ -486,6 +487,7 @@ "Default User Role": "บทบาทผู้ใช้เริ่มต้น", "Defaults": "", "Delete": "ลบ", + "Delete {{name}}": "", "Delete a model": "ลบโมเดล", "Delete All": "", "Delete All Chats": "ลบการแชททั้งหมด", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "วาด", "Drop any files here to upload": "วางไฟล์ที่นี่เพื่ออัปโหลด", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "เช่น '30s', '10m' หน่วยเวลาที่ใช้ได้คือ 's', 'm', 'h'", @@ -897,6 +900,7 @@ "Focus Chat Input": "โฟกัสช่องป้อนแชท", "Folder": "โฟลเดอร์", "Folder Background Image": "รูปภาพพื้นหลังโฟลเดอร์", + "Folder created successfully": "", "Folder deleted successfully": "ลบโฟลเดอร์สำเร็จแล้ว", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "ไม่ได้เลือกไฟล์", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "ไม่พบฟังก์ชัน", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "ดึง \"{{searchValue}}\" จาก Ollama.com", "Pull a model from Ollama.com": "ดึงโมเดลจาก Ollama.com", "Pull Model": "ดึงโมเดล", + "Pyodide file browser": "", "Query Generation Prompt": "พรอมต์สร้างคิวรี", "Querying": "กำลังค้นหา", "Quick Actions": "การกระทำด่วน", diff --git a/src/lib/i18n/locales/tk-TM/translation.json b/src/lib/i18n/locales/tk-TM/translation.json index b8d605fa9c..651254fa29 100644 --- a/src/lib/i18n/locales/tk-TM/translation.json +++ b/src/lib/i18n/locales/tk-TM/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "", "Are you sure you want to delete this message?": "", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "", "Arena Models": "", "Artifacts": "", @@ -486,6 +487,7 @@ "Default User Role": "", "Defaults": "", "Delete": "Öçür", + "Delete {{name}}": "", "Delete a model": "", "Delete All": "", "Delete All Chats": "Ähli Çatlary Öçür", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "", "Pull a model from Ollama.com": "", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/tr-TR/translation.json b/src/lib/i18n/locales/tr-TR/translation.json index 42c2b98fed..9c0d3c9bd6 100644 --- a/src/lib/i18n/locales/tr-TR/translation.json +++ b/src/lib/i18n/locales/tr-TR/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Bu kanalı silmek istediğinizden emin misiniz?", "Are you sure you want to delete this message?": "Bu mesajı silmek istediğinizden emin misiniz?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "Bu sürümü silmek istediğinizden emin misiniz? Alt sürümler bu sürümün üst sürümüne yeniden bağlanacaktır.", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Arşivlenmiş tüm sohbetlerin arşivini kaldırmak istediğinizden emin misiniz?", "Arena Models": "Arena Modelleri", "Artifacts": "Eserler", @@ -486,6 +487,7 @@ "Default User Role": "Varsayılan Kullanıcı Rolü", "Defaults": "Varsayılanlar", "Delete": "Sil", + "Delete {{name}}": "", "Delete a model": "Bir modeli sil", "Delete All": "Tümünü Sil", "Delete All Chats": "Tüm Sohbetleri Sil", @@ -578,6 +580,7 @@ "Downloading stats...": "İstatistikler indiriliyor...", "Draw": "Çiz", "Drop any files here to upload": "Yüklemek için dosyaları buraya bırakın", + "Drop files here": "", "Drop files here to upload": "Yüklemek için dosyaları buraya bırakın", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "örn. '30s', '10m'. Geçerli zaman birimleri 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "Klasör", "Folder Background Image": "Klasör Arka Plan Resmi", + "Folder created successfully": "", "Folder deleted successfully": "Klasör başarıyla silindi", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Hiçbir dosya seçilmedi", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Ollama.com'dan \"{{searchValue}}\" çekin", "Pull a model from Ollama.com": "Ollama.com'dan bir model çekin", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "Sorgu Oluşturma Promptu", "Querying": "", "Quick Actions": "Hızlı Eylemler", diff --git a/src/lib/i18n/locales/ug-CN/translation.json b/src/lib/i18n/locales/ug-CN/translation.json index 56dccac739..3b45c2202c 100644 --- a/src/lib/i18n/locales/ug-CN/translation.json +++ b/src/lib/i18n/locales/ug-CN/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "بۇ قانالنى ئۆچۈرەمسىز؟", "Are you sure you want to delete this message?": "بۇ ئۇچۇرنى ئۆچۈرەمسىز؟", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "بارلىق ئارخىپلانغان سۆھبەتلەرنى قايتا ئەسلىگە كەلتۈرەمسىز؟", "Arena Models": "Arena مودېللىرى", "Artifacts": "ئۇزۇقلار", @@ -486,6 +487,7 @@ "Default User Role": "كۆڭۈلدىكى ئىشلەتكۈچى رولى", "Defaults": "", "Delete": "ئۆچۈرۈش", + "Delete {{name}}": "", "Delete a model": "مودېل ئۆچۈرۈش", "Delete All": "", "Delete All Chats": "بارلىق سۆھبەتلەرنى ئۆچۈرۈش", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "سىزىش", "Drop any files here to upload": "ھەر قانداق ھۆججەتنى بۇ يەرگە قويۇپ يۈكلەڭ", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "مەسىلەن: '30s', '10m'. توغرا ۋاقىت بىرلىكى: 's' (سېكۇنت), 'm' (مىنۇت), 'h' (سائەت).", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "قىسقۇچ مۇۋەپپەقىيەتلىك ئۆچۈرۈلدى", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "ھۆججەت تاللانمىدى", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Ollama.com دىن \"{{searchValue}}\" نى تارتىش", "Pull a model from Ollama.com": "Ollama.com دىن مودېل تارتىش", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "ئىزدەش سۇئالى تۈرتكەسى", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/uk-UA/translation.json b/src/lib/i18n/locales/uk-UA/translation.json index 4d6f5c2060..6c949f2fee 100644 --- a/src/lib/i18n/locales/uk-UA/translation.json +++ b/src/lib/i18n/locales/uk-UA/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Ви впевнені, що хочете видалити цей канал?", "Are you sure you want to delete this message?": "Ви впевнені, що хочете видалити це повідомлення?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Ви впевнені, що хочете розархівувати усі архівовані чати?", "Arena Models": "Моделі Arena", "Artifacts": "Артефакти", @@ -486,6 +487,7 @@ "Default User Role": "Роль користувача за замовчуванням", "Defaults": "", "Delete": "Видалити", + "Delete {{name}}": "", "Delete a model": "Видалити модель", "Delete All": "", "Delete All Chats": "Видалити усі чати", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Малювати", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "напр., '30s','10m'. Дійсні одиниці часу: 'с', 'хв', 'г'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "Папку успішно видалено", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Файл не обрано", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Завантажити \"{{searchValue}}\" з Ollama.com", "Pull a model from Ollama.com": "Завантажити модель з Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "Підказка для генерації запиту", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/ur-PK/translation.json b/src/lib/i18n/locales/ur-PK/translation.json index 679bfa601b..b165ac17fe 100644 --- a/src/lib/i18n/locales/ur-PK/translation.json +++ b/src/lib/i18n/locales/ur-PK/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "", "Are you sure you want to delete this message?": "", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "", "Arena Models": "ارینا ماڈلز", "Artifacts": "نوادرات", @@ -486,6 +487,7 @@ "Default User Role": "ڈیفالٹ صارف کا کردار", "Defaults": "", "Delete": "حذف کریں", + "Delete {{name}}": "", "Delete a model": "ایک ماڈل حذف کریں", "Delete All": "", "Delete All Chats": "تمام چیٹس حذف کریں", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "ڈرائنگ کریں", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "مثلاً '30s'، '10m' درست وقت کی اکائیاں ہیں 's'، 'm'، 'h'", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "پوشہ کامیابی سے حذف ہو گیا", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "کوئی فائل منتخب نہیں کی گئی", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Ollama.com سے \"{{searchValue}}\" کو کھینچیں", "Pull a model from Ollama.com": "Ollama.com سے ماڈل حاصل کریں", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/uz-Cyrl-UZ/translation.json b/src/lib/i18n/locales/uz-Cyrl-UZ/translation.json index f35c516c93..b1168b60df 100644 --- a/src/lib/i18n/locales/uz-Cyrl-UZ/translation.json +++ b/src/lib/i18n/locales/uz-Cyrl-UZ/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Ҳақиқатан ҳам бу канални ўчириб ташламоқчимисиз?", "Are you sure you want to delete this message?": "Ҳақиқатан ҳам бу хабарни ўчириб ташламоқчимисиз?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Ҳақиқатан ҳам барча архивланган чатларни архивдан чиқармоқчимисиз?", "Arena Models": "Арена моделлари", "Artifacts": "Артефактлар", @@ -486,6 +487,7 @@ "Default User Role": "Стандарт фойдаланувчи роли", "Defaults": "", "Delete": "Ўчириш", + "Delete {{name}}": "", "Delete a model": "Моделни ўчириш", "Delete All": "", "Delete All Chats": "Барча суҳбатларни ўчириш", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Чизиш", "Drop any files here to upload": "Юклаш учун исталган файлни шу ерга ташланг", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "масалан. 30s, 10m. Яроқли вақт бирликлари 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "Жилд муваффақиятли ўчирилди", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Ҳеч қандай файл танланмаган", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Ollama.cом сайтидан “{{сеарчВалуе}}”ни тортинг", "Pull a model from Ollama.com": "Ollama.cом дан моделни тортинг", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "Сўровни яратиш таклифи", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/uz-Latn-Uz/translation.json b/src/lib/i18n/locales/uz-Latn-Uz/translation.json index 2af10b56d4..9087fe70e0 100644 --- a/src/lib/i18n/locales/uz-Latn-Uz/translation.json +++ b/src/lib/i18n/locales/uz-Latn-Uz/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Haqiqatan ham bu kanalni oʻchirib tashlamoqchimisiz?", "Are you sure you want to delete this message?": "Haqiqatan ham bu xabarni oʻchirib tashlamoqchimisiz?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Haqiqatan ham barcha arxivlangan chatlarni arxivdan chiqarmoqchimisiz?", "Arena Models": "Arena modellari", "Artifacts": "Artefaktlar", @@ -486,6 +487,7 @@ "Default User Role": "Odatiy foydalanuvchi roli", "Defaults": "", "Delete": "Oʻchirish", + "Delete {{name}}": "", "Delete a model": "Modelni o'chirish", "Delete All": "", "Delete All Chats": "Barcha suhbatlarni o'chirish", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Chizish", "Drop any files here to upload": "Yuklash uchun istalgan faylni shu yerga tashlang", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "masalan. '30s', '10m'. Yaroqli vaqt birliklari 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "Jild muvaffaqiyatli oʻchirildi", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Hech qanday fayl tanlanmagan", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Ollama.com saytidan “{{searchValue}}”ni torting", "Pull a model from Ollama.com": "Ollama.com dan modelni torting", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "So'rovni yaratish taklifi", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/vi-VN/translation.json b/src/lib/i18n/locales/vi-VN/translation.json index 637321ef3a..5b190c6b1c 100644 --- a/src/lib/i18n/locales/vi-VN/translation.json +++ b/src/lib/i18n/locales/vi-VN/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "Bạn có chắc chắn muốn xóa kênh này không?", "Are you sure you want to delete this message?": "Bạn có chắc chắn muốn xóa tin nhắn này không?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "Bạn có chắc chắn muốn bỏ lưu trữ tất cả các cuộc trò chuyện đã lưu trữ không?", "Arena Models": "Các Mô hình Arena", "Artifacts": "Kết quả tạo ra", @@ -486,6 +487,7 @@ "Default User Role": "Vai trò mặc định", "Defaults": "", "Delete": "Xóa", + "Delete {{name}}": "", "Delete a model": "Xóa mô hình", "Delete All": "", "Delete All Chats": "Xóa mọi cuộc Chat", @@ -578,6 +580,7 @@ "Downloading stats...": "", "Draw": "Vẽ", "Drop any files here to upload": "", + "Drop files here": "", "Drop files here to upload": "", "DuckDuckGo": "", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "vd: '30s','10m'. Đơn vị thời gian hợp lệ là 's', 'm', 'h'.", @@ -897,6 +900,7 @@ "Focus Chat Input": "", "Folder": "", "Folder Background Image": "", + "Folder created successfully": "", "Folder deleted successfully": "Xóa thư mục thành công", "Folder Max File Count": "", "Folder name": "", @@ -1304,6 +1308,7 @@ "No file selected": "Chưa có tệp nào được chọn", "No files found": "", "No files in this knowledge base.": "", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "", "No groups found": "", "No history available": "", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Tải \"{{searchValue}}\" từ Ollama.com", "Pull a model from Ollama.com": "Tải mô hình từ Ollama.com", "Pull Model": "", + "Pyodide file browser": "", "Query Generation Prompt": "Prompt Tạo Truy vấn", "Querying": "", "Quick Actions": "", diff --git a/src/lib/i18n/locales/zh-CN/translation.json b/src/lib/i18n/locales/zh-CN/translation.json index 744785c78a..6ca92acdc0 100644 --- a/src/lib/i18n/locales/zh-CN/translation.json +++ b/src/lib/i18n/locales/zh-CN/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "您确认要删除此频道吗?", "Are you sure you want to delete this message?": "您确认要删除此消息吗?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "您确认要删除此版本吗?其子版本将重新链接到该版本的上一级。", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "您确认要取消所有已归档的对话吗?", "Arena Models": "启用竞技场匿名评价模型", "Artifacts": "产物", @@ -486,6 +487,7 @@ "Default User Role": "默认用户角色", "Defaults": "默认值", "Delete": "删除", + "Delete {{name}}": "", "Delete a model": "删除模型", "Delete All": "全部删除", "Delete All Chats": "删除所有对话记录", @@ -578,6 +580,7 @@ "Downloading stats...": "正在下载统计数据...", "Draw": "平局", "Drop any files here to upload": "拖拽文件至此上传", + "Drop files here": "", "Drop files here to upload": "将文件拖到此处即可上传", "DuckDuckGo": "DuckDuckGo", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "例如:“30s”,“10m”。有效的时间单位包括:“s”(秒), “m”(分), “h”(时)", @@ -897,6 +900,7 @@ "Focus Chat Input": "聚焦对话框", "Folder": "分组", "Folder Background Image": "分组背景图", + "Folder created successfully": "", "Folder deleted successfully": "分组删除成功", "Folder Max File Count": "分组最大文件数量", "Folder name": "文件夹名称", @@ -1304,6 +1308,7 @@ "No file selected": "未选中文件", "No files found": "未找到文件", "No files in this knowledge base.": "此知识库中没有文件。", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "未找到函数", "No groups found": "暂无权限组", "No history available": "暂无历史记录", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "从 Ollama.com 下载 “{{searchValue}}”", "Pull a model from Ollama.com": "从 Ollama.com 下载模型", "Pull Model": "下载模型", + "Pyodide file browser": "", "Query Generation Prompt": "查询生成提示词", "Querying": "查询中", "Quick Actions": "快捷操作", diff --git a/src/lib/i18n/locales/zh-TW/translation.json b/src/lib/i18n/locales/zh-TW/translation.json index eba4340e1b..dcff1e5746 100644 --- a/src/lib/i18n/locales/zh-TW/translation.json +++ b/src/lib/i18n/locales/zh-TW/translation.json @@ -183,6 +183,7 @@ "Are you sure you want to delete this channel?": "您確定要刪除此頻道嗎?", "Are you sure you want to delete this message?": "您確定要刪除此訊息嗎?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "您確定要刪除此版本嗎?子版本將重新連結至上一層版本。", + "Are you sure you want to delete this?": "", "Are you sure you want to unarchive all archived chats?": "您確定要解除封存所有封存的對話記錄嗎?", "Arena Models": "競技場模型", "Artifacts": "產物", @@ -486,6 +487,7 @@ "Default User Role": "預設使用者角色", "Defaults": "預設值", "Delete": "刪除", + "Delete {{name}}": "", "Delete a model": "刪除模型", "Delete All": "全部刪除", "Delete All Chats": "刪除所有對話紀錄", @@ -578,6 +580,7 @@ "Downloading stats...": "正在下載統計資料...", "Draw": "平手", "Drop any files here to upload": "拖曳檔案至此處進行上傳", + "Drop files here": "", "Drop files here to upload": "將檔案拖曳至此即可上傳", "DuckDuckGo": "DuckDuckGo", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "例如:'30s'、'10m'。有效的時間單位為 's'、'm'、'h'。", @@ -897,6 +900,7 @@ "Focus Chat Input": "聚焦對話輸入框", "Folder": "分組", "Folder Background Image": "分組背景圖", + "Folder created successfully": "", "Folder deleted successfully": "成功刪除分組", "Folder Max File Count": "分組最大檔案數量", "Folder name": "資料夾名稱", @@ -1304,6 +1308,7 @@ "No file selected": "未選取檔案", "No files found": "找不到檔案", "No files in this knowledge base.": "此知識庫中沒有檔案。", + "No files yet. Upload files or run Python code to create them.": "", "No functions found": "未找到函式", "No groups found": "暫無權限群組", "No history available": "暫無歷史紀錄", @@ -1511,6 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "從 Ollama.com 下載「{{searchValue}}」", "Pull a model from Ollama.com": "從 Ollama.com 下載模型", "Pull Model": "下載模型", + "Pyodide file browser": "", "Query Generation Prompt": "查詢生成提示詞", "Querying": "查詢中", "Quick Actions": "快速操作", diff --git a/src/lib/workers/pyodide.worker.ts b/src/lib/workers/pyodide.worker.ts index a9334b4faf..7ef3916731 100644 --- a/src/lib/workers/pyodide.worker.ts +++ b/src/lib/workers/pyodide.worker.ts @@ -123,9 +123,7 @@ function fsUploadFiles(files: { name: string; data: ArrayBuffer }[], dir = '/mnt function fsList(path: string) { const entries: { name: string; type: 'file' | 'directory'; size: number }[] = []; try { - const items = self.pyodide.FS.readdir(path).filter( - (n: string) => n !== '.' && n !== '..' - ); + const items = self.pyodide.FS.readdir(path).filter((n: string) => n !== '.' && n !== '..'); for (const name of items) { try { const stat = self.pyodide.FS.stat(`${path}/${name}`); @@ -155,9 +153,7 @@ function fsDelete(path: string) { const stat = self.pyodide.FS.stat(path); if (self.pyodide.FS.isDir(stat.mode)) { // Recursively delete directory contents - const items = self.pyodide.FS.readdir(path).filter( - (n: string) => n !== '.' && n !== '..' - ); + const items = self.pyodide.FS.readdir(path).filter((n: string) => n !== '.' && n !== '..'); for (const item of items) { fsDelete(`${path}/${item}`); } @@ -178,7 +174,11 @@ function fsMkdir(path: string) { // Code execution // --------------------------------------------------------------------------- -async function executeCode(id: string, code: string, files?: { name: string; data: ArrayBuffer }[]) { +async function executeCode( + id: string, + code: string, + files?: { name: string; data: ArrayBuffer }[] +) { self.stdout = null; self.stderr = null; self.result = null; @@ -282,7 +282,11 @@ self.onmessage = async (event) => { const buffer = fsRead(data.path); self.postMessage({ id, type: 'fs:read', data: buffer }, { transfer: [buffer] }); } catch (err: unknown) { - self.postMessage({ id, type: 'fs:read', error: err instanceof Error ? err.message : String(err) }); + self.postMessage({ + id, + type: 'fs:read', + error: err instanceof Error ? err.message : String(err) + }); } break; } From d0c318037646e8b19cad6b7aa5c13c13d150e218 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 8 Mar 2026 03:15:00 +0100 Subject: [PATCH 0819/1854] changelog: 0.8.9 (#22186) * changelog: terminal keepalive fix * changelog: add chat archive handler fix * changelog: terminal keepalive, chat archive handler, BeautifulSoup4 dependency * changelog: button spinner, terminal keepalive, chat archive, beautifulsoup4 * changelog: group users sort, button spinner, terminal keepalive, chat archive, beautifulsoup4 * changelog: add event call timeout configuration * changelog: add general improvements and French translations * changelog: file refresh button, group sort, event timeout, translations * changelog: add office file previews support * changelog: add Open Terminal port viewing feature * changelog: add Open Terminal video previews entry * changelog: Open Terminal syntax highlighting and XLSX improvements * changelog: add JSON tree view and SVG rendering entry * changelog: add Open Terminal Jupyter Notebook previews entry * changelog: update chat performance entry to reflect broader markdown rendering improvements * changelog: add SQLite browser feature to Open Terminal * changelog: add Open Terminal file copy button entry * changelog: add Open Terminal auto-refresh entry * changelog: open terminal, mermaid, diagrams * changelog: add Open Terminal notebook cell execution entry * changelog: reorder Open Terminal entries by impact * changelog: add initial page load speed entry * changelog: opentelemetry, metrics, telemetry * changelog: fix artifacts memory leak (PR #22303) * changelog: message list performance, array operations optimization * changelog: streaming markdown performance fix * changelog: sqlcipher, stability, memory leak * changelog: chat streaming performance * changelog: fix Floating Quick Actions for unavailable models * changelog: follow-up suggestions, prompt template, JSON format * changelog: banner, navigation, homepage * changelog: api middleware, streaming performance * changelog: tts, thinking content, playback * changelog: add system metrics via OpenTelemetry * changelog: tool access permissions fix * changelog: source list performance fix * changelog: source list performance optimization * changelog: chat message tree performance, #22194 * changelog: add Finnish translations, update version date * changelog: fix parameterless tool calls during streaming * changelog: add stale pinned models cleanup fix * changelog: move performance entries from Fixed to Added section * changelog: android, photo capture, canvas * changelog: action priority query optimization (PR #22301) * changelog: move action priority query to Added section * changelog: group Open Terminal entries together * changelog: group Open Terminal entries together * changelog: move API key middleware entry to Added section * changelog: open-terminal, html-editing * changelog: web search tool guidance update * changelog: add Turkish translations to v0.8.9 * changelog: add German translations * changelog: fix stop sequence error handling * changelog: Open Terminal permission fix for issue #22374 * changelog: add Windows path fix for Open Terminal * changelog: add Simplified Chinese and Traditional Chinese to translations * changelog: fix profile image sizing in chat overview * changelog: queued messages display fix (#22176) * changelog: model list loading performance optimization * changelog: model list performance optimization update * changelog: artifacts reactive loop fix * changelog: artifact navigation fix * changelog: fix image generation in temporary chats * changelog: non-streaming token tracking, admin analytics * changelog: add citation parser error handling fix * changelog: tool server URL trailing slash fix * changelog: inline code typing fix (#20417) * changelog: variable input newlines fix * changelog: add migration memory usage fix for large deployments * changelog: Microsoft OAuth refresh token fix * changelog: add issue link to variable input newlines entry * changelog: tool files access, artifact thinking block fix * changelog: ollama, model unload, proxy fix * changelog: fix banner type dropdown requiring two clicks * changelog: move migration memory fix to top of Fixed section * changelog: fix analytics URL encoding for models with slashes * changelog: fix tool call streaming for GPT-5 models * changelog: fix analytics chat list duplicate error * changelog: pyodide file system support for code interpreter * changelog: fix folder knowledge base native tool call duplicate query * changelog: folder knowledge base native tool call fix with follow-up commit * changelog: nested folders support * changelog: update Pyodide file system entry with pip guidance --- CHANGELOG.md | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 92a9dee71c..8e945a6769 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,86 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.8.9] - 2026-03-09 + +### Added + +- 📁 **Pyodide file system support.** Users can now upload files for Python code execution in the code interpreter. Uploaded files are available in the `/mnt/uploads/` directory, and code can write output files there for download. The file system persists across code executions within the same session. The code interpreter now also informs models that pip install is not available in the Pyodide environment, guiding them to use alternative approaches with available modules. [#3583](https://github.com/open-webui/open-webui/issues/3583), [Commit](https://github.com/open-webui/open-webui/commit/ce0ca894fea8a2904bc6f832ff186d5fe53dd0b9), [Commit](https://github.com/open-webui/open-webui/commit/989938856fdb4b4afa584ae2d18c88d5be614ae2) +- ▶️ **Open Terminal notebook cell execution.** Users can now run Jupyter Notebook code cells directly in the Open Terminal file navigator, execute entire notebooks with a single click, edit and modify cells before running, and control the kernel - bringing full interactive notebook execution to the browser. [Commit](https://github.com/open-webui/open-webui/commit/4b3ed3e802d6f2ec8ee7caf358af810b7d09f789) +- 🗃️ **Open Terminal SQLite browser.** Users can now browse SQLite database files directly in the Open Terminal file navigator, viewing tables and running queries without downloading them first. [Commit](https://github.com/open-webui/open-webui/commit/a181b4a731a9ec7856be08d0b045a454d1341cf4) +- 📊 **Open Terminal Mermaid diagram rendering.** Markdown files with Mermaid code blocks are now rendered as diagrams directly in the Open Terminal file navigator, making it easier to visualize flowcharts and other diagrams. [Commit](https://github.com/open-webui/open-webui/commit/aaa49bdd6d6e5c10e8be554039d3cac673008fc2) +- 📓 **Open Terminal Jupyter Notebook previews.** Users can now preview Jupyter Notebook files directly in the Open Terminal file navigator, making it easier to view notebook content without downloading them first. [Commit](https://github.com/open-webui/open-webui/commit/b081e33c0a37585a1ee60b6e0e1ea03457f1e5f4) +- 🔃 **Open Terminal auto-refresh.** The Open Terminal file navigator now automatically refreshes when the model writes or modifies files, keeping the view in sync without manual refresh. [Commit](https://github.com/open-webui/open-webui/commit/828656b35f04bf486609183799cf8aa2e9850a76) +- 📋 **Open Terminal file copy button.** Users can now copy file contents directly to clipboard in the Open Terminal file navigator with a single click, making it easier to quickly grab file content without downloading. [Commit](https://github.com/open-webui/open-webui/commit/f5ea1ce250cb02fbc583c6cb3f52a923912d0178) +- 💻 **Code syntax highlighting and XLSX improvements in Open Terminal.** Code files now display with syntax highlighting in the Open Terminal file navigator, and XLSX spreadsheets now show column headers and row numbers for easier navigation. [Commit](https://github.com/open-webui/open-webui/commit/f962bae98306ea9264967b78b803397f4821f9b0) +- 🌳 **Open Terminal JSON tree view.** JSON, JSONC, JSONL, and JSON5 files now display as interactive collapsible tree views in the Open Terminal file navigator, and SVG files render as preview images with syntax highlighting support. [Commit](https://github.com/open-webui/open-webui/commit/f4c38e6001dd9d4853ed923e0bc5e790c4fd9941) +- 🔌 **Open Terminal port viewing.** Users can now view listening ports in the Open Terminal file navigator and open proxy connections to them directly from the UI. [Commit](https://github.com/open-webui/open-webui/commit/e08341dab3bb10e26a64eb44cbebd2d507087b03) +- 🎬 **Open Terminal video previews.** Users can now preview video and audio files directly in the Open Terminal file navigator, making it easier to view media without downloading them first. [Commit](https://github.com/open-webui/open-webui/commit/c40f26946f2eaeb1587a1f8b0c643b4a5121fc06) +- ✏️ **Open Terminal HTML editing.** Users can now edit HTML source files in Open Terminal with CodeMirror editor, and the save button is properly hidden in preview mode. [Commit](https://github.com/open-webui/open-webui/commit/7806cd5aef9fb0505b2c642ef70599a403cf14ba) +- 🧰 **Tool files access.** Tools can now access the files from the current chat context via the files property in their metadata, enabling more powerful tool integrations. [Commit](https://github.com/open-webui/open-webui/commit/35bc8310772c222fd8a466f7d00113a84e0402d0) +- ⚡ **Chat performance.** Chat messages now load and display significantly faster thanks to optimized markdown rendering, eliminating delays when viewing messages with mathematical expressions. [#22196](https://github.com/open-webui/open-webui/pull/22196), [#20878](https://github.com/open-webui/open-webui/discussions/20878) +- ⚡ **Message list performance.** Improved message list rendering performance by optimizing array operations, reducing complexity from O(n²) to O(n). [#22280](https://github.com/open-webui/open-webui/pull/22280) +- ⚡ **Streaming markdown performance.** Improved chat responsiveness during streaming by skipping unnecessary markdown re-parsing when the content hasn't changed, eliminating wasted processing during model pauses. [#22183](https://github.com/open-webui/open-webui/pull/22183) +- ⚡ **Chat streaming performance.** Chat streaming is now faster for users not using the voice call feature by skipping unnecessary text parsing that was running on every token. [#22195](https://github.com/open-webui/open-webui/pull/22195) +- ⚡ **Source list performance.** Source lists in chat now render faster thanks to optimized computation that avoids unnecessary recalculations. [#22279](https://github.com/open-webui/open-webui/pull/22279), [Commit](https://github.com/open-webui/open-webui/commit/88af78c) +- ⚡ **Source list performance.** Optimized source list rendering by moving sourceIds computation to a reactive variable, reducing unnecessary recomputations. [Commit](https://github.com/open-webui/open-webui/commit/339ed1d72e100c89d8eb26de761dfefe842ef90c) +- 💨 **Chat message tree operations.** Chat message tree operations are now significantly faster, improving overall chat responsiveness. [#22194](https://github.com/open-webui/open-webui/pull/22194) +- 🚀 **Initial page load speed.** Page load is now significantly faster thanks to deferred loading of the syntax highlighting library, reducing the initial JavaScript bundle by several megabytes. [#22304](https://github.com/open-webui/open-webui/pull/22304) +- ⚡ **Action priority query optimization.** Improved performance of action priority resolution by fixing an N+1 query pattern, reducing database round-trips when loading model actions. [#22301](https://github.com/open-webui/open-webui/pull/22301) +- ⚡ **API key middleware optimization.** The API key restriction middleware was converted to a pure ASGI middleware for improved streaming performance, removing per-chunk call overhead. [#22188](https://github.com/open-webui/open-webui/pull/22188) +- 🏎️ **Model list loading performance.** Model lists now load significantly faster thanks to optimized custom model matching that uses dictionary lookups instead of nested loops. [#22299](https://github.com/open-webui/open-webui/pull/22299), [Commit](https://github.com/open-webui/open-webui/commit/29160741a3defa8768a43100cb6e63c56400279c), [Commit](https://github.com/open-webui/open-webui/commit/03c6caac1fc8625f85cf1164f5a977be8005c1bc) +- ⏱️ **Event call timeout configuration.** Administrators can now configure the WebSocket event call timeout via the WEBSOCKET_EVENT_CALLER_TIMEOUT environment variable, giving users more time to respond to event_call forms instead of timing out after 60 seconds. [#22222](https://github.com/open-webui/open-webui/pull/22222), [#22220](https://github.com/open-webui/open-webui/issues/22220) +- 📑 **Office file previews.** Users can now preview DOCX, XLSX, and PPTX files directly in the chat file navigator, making it easier to view documents without downloading them first. [Commit](https://github.com/open-webui/open-webui/commit/890949abe6b01d201355a86c50317e20da07dd34) +- 📁 **File refresh button visibility.** The refresh button in the chat file navigator now appears when viewing files as well as directories, allowing users to refresh the file view at any time. [Commit](https://github.com/open-webui/open-webui/commit/49a2e5bf573415dae6d4c7e5bd635e499c8de77a) +- 📂 **Nested folders support.** Users can now create subfolders within parent folders, improving organization of chats. A new "Create Subfolder" option is available in the folder context menu. [#22073](https://github.com/open-webui/open-webui/pull/22073), [Commit](https://github.com/open-webui/open-webui/commit/8913f37c3d8fde7dea6d54a550357f1d495b3941) +- 📢 **Banner loading on navigation.** Admin-configured banners now load when navigating to the homepage, not just on page refresh, ensuring users see new banners immediately. [#22340](https://github.com/open-webui/open-webui/pull/22340), [#22180](https://github.com/open-webui/open-webui/issues/22180) +- 📊 **System metrics via OpenTelemetry.** Administrators can now monitor Python runtime and system metrics including CPU, memory, garbage collection, and thread counts through the existing OpenTelemetry pipeline. [#22265](https://github.com/open-webui/open-webui/pull/22265) +- 🔄 **General improvements.** Various improvements were implemented across the application to enhance performance, stability, and security. +- 🌐 Translations for French, Finnish, Turkish, German, Simplified Chinese, and Traditional Chinese were enhanced and expanded. +- 🔍 **Web search tool guidance.** The web search tool description was updated to encourage direct usage without first checking knowledge bases, making it clearer for users who want to search the web immediately. [#22264](https://github.com/open-webui/open-webui/pull/22264) + +### Fixed + +- 🗄️ **Migration memory usage.** Database migration on large deployments now processes messages in batches instead of loading everything into memory, preventing out-of-memory errors during upgrades. [#21542](https://github.com/open-webui/open-webui/pull/21542), [#21539](https://github.com/open-webui/open-webui/discussions/21539) +- 🔒 **SQLCipher connection stability.** Fixed a crash that occurred when using database encryption with SQLCipher by changing the default connection pool behavior, ensuring stable operation during multi-threaded operations like user signup. [#22273](https://github.com/open-webui/open-webui/pull/22273), [#22258](https://github.com/open-webui/open-webui/issues/22258) +- 🛑 **Stop sequence error.** Fixed a bug where setting stop sequences on a model caused the chat to fail with a split error, preventing any responses from being returned. The fix handles both string and array formats for stop tokens. [#22251](https://github.com/open-webui/open-webui/issues/22251), [Commit](https://github.com/open-webui/open-webui/commit/c7d1d1e390a79c6c86d4bfe439fd7de6f5fb060f) +- 🔐 **Microsoft OAuth refresh token fix.** Fixed a bug where Microsoft OAuth refresh token requests failed with error AADSTS90009 by adding support for the required scope parameter. Users can now stay logged in reliably with Microsoft OAuth. [#22359](https://github.com/open-webui/open-webui/pull/22359) +- 🔧 **Parameterless tool calls.** Fixed parameterless tool calls failing during streaming by correcting the default arguments initialization, eliminating unnecessary model retries. [#22189](https://github.com/open-webui/open-webui/pull/22189) +- 🔧 **Tool call streaming fixes.** Fixed two bugs where streaming tool calls failed silently for models like GPT-5: function names were incorrectly duplicated when sent in multiple delta chunks, and arguments containing multiple JSON objects were not properly split. Tools now execute correctly instead of failing without explanation. [#22177](https://github.com/open-webui/open-webui/issues/22177), [Commit](https://github.com/open-webui/open-webui/commit/d7efdcce2b1cdbe1637a469294bf9d52dbacab53), [Commit](https://github.com/open-webui/open-webui/commit/459a60a24240eab33441ed50f4f68cc27e65a037) +- 🔗 **Tool server URL trailing slash.** Fixed tool server connection failures when URLs have trailing slashes by stripping them before path concatenation. Previously, URLs like "http://host:8080/v1/" + "/openapi.json" produced double-slash URLs that some servers rejected. [#22116](https://github.com/open-webui/open-webui/pull/22116), [#21917](https://github.com/open-webui/open-webui/issues/21917) +- 🔧 **Citation parser error handling.** Fixed crashes when tools return error strings instead of expected data structures by adding type guards to the citation parser. The system now returns an empty source list instead of crashing with AttributeError. [#22118](https://github.com/open-webui/open-webui/pull/22118) +- 🧠 **Artifacts memory leak.** Fixed a memory leak where Svelte store subscriptions in the Artifacts component were not properly cleaned up when the component unmounted, causing memory to accumulate over time. [#22303](https://github.com/open-webui/open-webui/pull/22303) +- ♾️ **Artifacts reactive loop fix.** Fixed an infinite reactive loop in chat when artifacts are present by moving the animation frame logic outside the reactive block, preventing continuous re-rendering and CPU usage. [#22238](https://github.com/open-webui/open-webui/pull/22238), [Commit](https://github.com/open-webui/open-webui/commit/626fcff417afba642f4f71e0498267a21435c524) +- 🔀 **Artifact navigation.** Artifact navigation via arrow buttons now works correctly; the selected artifact is no longer reset when content updates. [#22239](https://github.com/open-webui/open-webui/pull/22239) +- 🖼️ **Artifact thinking block fix.** Fixed a bug where HTML preview rendered code blocks inside thinking blocks for certain models like Mistral and Z.ai, causing stray code with ">" symbols to appear before the actual artifact. The fix strips thinking blocks before extracting code for artifact rendering. [#22267](https://github.com/open-webui/open-webui/issues/22267), [Commit](https://github.com/open-webui/open-webui/commit/35bc8310772c222fd8a466f7d00113a84e0402d0) +- 💬 **Floating Quick Actions availability.** Fixed an issue where the "Ask" and "Explain" Floating Quick Actions were missing when selecting text in chats that used a model that is no longer available. [#22149](https://github.com/open-webui/open-webui/pull/22149), [#22139](https://github.com/open-webui/open-webui/issues/22139) +- 💬 **Follow-up suggestions.** Fixed follow-up suggestions not appearing by correcting contradictory format instructions in the prompt template, ensuring the LLM returns the correct JSON object format. [#22212](https://github.com/open-webui/open-webui/pull/22212) +- 🔊 **TTS thinking content.** Fixed TTS playback reading think tags instead of skipping them by handling edge cases where code blocks inside thinking content prevented proper tag removal. [#22237](https://github.com/open-webui/open-webui/pull/22237), [#22197](https://github.com/open-webui/open-webui/issues/22197) +- 🎨 **Button spinner alignment.** Button spinners across multiple modals now align correctly and stay on the same line as the button text, fixing layout issues when loading states are displayed. [#22227](https://github.com/open-webui/open-webui/pull/22227) +- 🔌 **Terminal keepalive.** Terminal connections now stay active without being closed by idle timeouts from proxies or load balancers, and spurious disconnection messages no longer appear. [Commit](https://github.com/open-webui/open-webui/commit/ca2aaf0321c219d041e92e2c0c842a4e424732ef) +- 📁 **Chat archive handler.** The archive button in the chat navbar now actually archives the chat and refreshes the chat list, instead of doing nothing. [#22229](https://github.com/open-webui/open-webui/pull/22229) +- 🐍 **BeautifulSoup4 dependency.** Added the missing BeautifulSoup4 package to backend requirements, fixing failures when using features that depend on HTML parsing. [#22231](https://github.com/open-webui/open-webui/pull/22231) +- 👥 **Group users default sort.** Group members in the admin panel now sort by last active time by default instead of creation date, making it easier to find active users. [#22211](https://github.com/open-webui/open-webui/pull/22211) +- 🔧 **Tool access permissions.** Users can now change tool and skill access permissions from private to public without errors. [#22325](https://github.com/open-webui/open-webui/pull/22325), [#22324](https://github.com/open-webui/open-webui/issues/22324) +- 🖥️ **Open Terminal permission fix.** Open Terminal is now visible without requiring "Allow Speech to Text" permission, fixing an issue where users without microphone access couldn't access the terminal feature. [#22374](https://github.com/open-webui/open-webui/issues/22374), [Commit](https://github.com/open-webui/open-webui/commit/70a31a9a57bdd0690ac270f31ebd1b46e8fdfa98) +- 📌 **Stale pinned models cleanup.** Pinned models that are deleted or hidden are now automatically unpinned, keeping your pinned models list up to date. [Commit](https://github.com/open-webui/open-webui/commit/af4500e5040c8343d339cd88dd1d2fb6138c7a72) +- 🔧 **OpenTelemetry metric descriptions.** Fixed conflicting metric instrument descriptions that caused warnings in the OpenTelemetry collector, resulting in cleaner telemetry logs for administrators. [#22293](https://github.com/open-webui/open-webui/pull/22293) +- 📊 **Non-streaming token tracking.** Token usage from non-streaming chat responses is now correctly saved to the database, fixing missing token counts in the Admin Panel analytics. Previously, non-streaming responses saved NULL usage data, causing messages to be excluded from token aggregation queries. [#22166](https://github.com/open-webui/open-webui/pull/22166) +- 🔧 **Citation parser error handling.** Fixed crashes when tools return error strings instead of expected data structures by adding type guards to the citation parser. The system now returns an empty source list instead of crashing with AttributeError. [#22118](https://github.com/open-webui/open-webui/pull/22118) +- 🔗 **Tool server URL trailing slash.** Fixed tool server connection failures when URLs have trailing slashes by stripping them before path concatenation. Previously, URLs like "http://host:8080/v1/" + "/openapi.json" produced double-slash URLs that some servers rejected. [#22116](https://github.com/open-webui/open-webui/pull/22116), [#21917](https://github.com/open-webui/open-webui/issues/21917) +- 📝 **Inline code typing.** Fixed a bug where typing inline code with backticks incorrectly deleted the character immediately before the opening backtick, so text formatted as inline code now correctly produces the full word instead of missing the last character. [#20417](https://github.com/open-webui/open-webui/issues/20417), [Commit](https://github.com/open-webui/open-webui/commit/e303c3da3b174da9e92a79b174f85ba574ca06ef) +- 📝 **Variable input newlines.** Fixed a bug where variables containing newlines were not displayed correctly in chat messages, and input values from Windows systems are now properly normalized to use standard line endings. [#21447](https://github.com/open-webui/open-webui/issues/21447), [Commit](https://github.com/open-webui/open-webui/commit/7b2f597b30c77ef300d1966e1c6a3edfdb0c465d) +- 📷 **Android photo capture.** Fixed an issue where the first photo taken in chat appeared completely black on some Android devices by using an alternative canvas export method. [#22317](https://github.com/open-webui/open-webui/pull/22317) +- 🖥️ **Open Terminal Windows path fix.** Fixed a bug where navigating back to parent directories on Windows added an incorrect leading slash, causing directory loads to fail. Paths are now properly normalized for Windows drive letters. [#22352](https://github.com/open-webui/open-webui/issues/22352), [Commit](https://github.com/open-webui/open-webui/commit/044fd1bd15cae06a5c56a321ca79d8362942f66a) +- 🖼️ **Chat overview profile image sizing.** Fixed a bug where profile images in the chat overview could shrink incorrectly in tight spaces. The images now maintain their proper size with the flex-shrink-0 property. [#22261](https://github.com/open-webui/open-webui/pull/22261) +- 💬 **Queued messages display.** Fixed an issue where queued messages could be cut off or hidden. The queued messages area now scrolls properly when content exceeds the visible area, showing up to 25% of the viewport height. [#22176](https://github.com/open-webui/open-webui/pull/22176) +- 🎨 **Image generation in temporary chats.** Generated images now display correctly in temporary chat mode when using builtin image generation tools. Previously, images were not shown because the code was overwriting the image list with a null database response. [#22330](https://github.com/open-webui/open-webui/pull/22330), [#22309](https://github.com/open-webui/open-webui/issues/22309) +- 🤖 **Ollama model unload fix.** Fixed a bug where unloading a model from Ollama via the Open WebUI proxy failed with a "Field required" error for the prompt field. The proxy now correctly allows omitting the prompt when using keep_alive: 0 to unload models. [#22260](https://github.com/open-webui/open-webui/issues/22260), [Commit](https://github.com/open-webui/open-webui/commit/95b65ff751f91131b633cb128ff2decdd87c4a85) +- 📢 **Banner type dropdown fix.** Fixed a bug where selecting a banner type required two clicks to register, as the first selection was being swallowed due to DOM structure changes. The dropdown now works correctly on the first click. [#22378](https://github.com/open-webui/open-webui/pull/22378) +- 📊 **Analytics URL encoding fix.** Fixed a bug where the Analytics page failed to load data for models with slashes in their ID, such as "anthropic/claude-opus-4.6". The frontend now properly URL-encodes forward slashes, allowing model analytics to load correctly. [#22380](https://github.com/open-webui/open-webui/issues/22380), [#22382](https://github.com/open-webui/open-webui/pull/22382) +- 📊 **Analytics chat list duplicate fix.** Fixed a bug where the Analytics page chat list threw an "each_key_duplicate" Svelte error when chat IDs were duplicated during pagination. The fix adds deterministic ordering to prevent duplicate entries. [#22383](https://github.com/open-webui/open-webui/pull/22383) +- 📁 **Folder knowledge base native tool call fix.** Fixed a bug where folders with attached knowledge bases were querying the knowledge base twice when using native tool call mode. The fix now correctly separates knowledge files from regular attachments, letting the builtin query_knowledge_files tool handle knowledge searches instead of duplicating RAG queries. [#22236](https://github.com/open-webui/open-webui/issues/22236), [Commit](https://github.com/open-webui/open-webui/commit/967b1137dcb7a52615f17d086ee89095bb9b60f3), [Commit](https://github.com/open-webui/open-webui/commit/80b5896b70d07ea868e2010b187430d43c9808f0) + ## [0.8.8] - 2026-03-02 ### Added From 223c14f48bfa647e05bc84e7362390e5617bbedd Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 8 Mar 2026 03:16:50 +0100 Subject: [PATCH 0820/1854] fix: add deterministic tiebreaker to all paginated chat queries (#22387) Add Chat.id as a secondary sort key to all paginated chat queries that use offset/limit pagination. When multiple chats share the same updated_at timestamp, the database does not guarantee a stable order across page boundaries, causing chats to appear on multiple pages. This produces duplicate keys in the Svelte sidebar each-block (each_key_duplicate error). Adding Chat.id as a tiebreaker ensures fully deterministic ordering. Extends the fix from #22383 (which addressed get_chat_ids_by_model_id) to all remaining paginated chat queries. --- backend/open_webui/models/chats.py | 32 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/backend/open_webui/models/chats.py b/backend/open_webui/models/chats.py index 8c6eb830b5..9b8261b8d4 100644 --- a/backend/open_webui/models/chats.py +++ b/backend/open_webui/models/chats.py @@ -734,13 +734,13 @@ class ChatTable: raise ValueError("Invalid order_by field") if direction.lower() == "asc": - query = query.order_by(getattr(Chat, order_by).asc()) + query = query.order_by(getattr(Chat, order_by).asc(), Chat.id) elif direction.lower() == "desc": - query = query.order_by(getattr(Chat, order_by).desc()) + query = query.order_by(getattr(Chat, order_by).desc(), Chat.id) else: raise ValueError("Invalid direction for ordering") else: - query = query.order_by(Chat.updated_at.desc()) + query = query.order_by(Chat.updated_at.desc(), Chat.id) query = query.with_entities( Chat.id, Chat.title, Chat.updated_at, Chat.created_at @@ -793,13 +793,13 @@ class ChatTable: raise ValueError("Invalid order_by field") if direction.lower() == "asc": - query = query.order_by(getattr(Chat, order_by).asc()) + query = query.order_by(getattr(Chat, order_by).asc(), Chat.id) elif direction.lower() == "desc": - query = query.order_by(getattr(Chat, order_by).desc()) + query = query.order_by(getattr(Chat, order_by).desc(), Chat.id) else: raise ValueError("Invalid direction for ordering") else: - query = query.order_by(Chat.updated_at.desc()) + query = query.order_by(Chat.updated_at.desc(), Chat.id) # Select only the columns needed for SharedChatResponse # to avoid loading the heavy chat JSON blob @@ -854,13 +854,13 @@ class ChatTable: if order_by and direction and getattr(Chat, order_by): if direction.lower() == "asc": - query = query.order_by(getattr(Chat, order_by).asc()) + query = query.order_by(getattr(Chat, order_by).asc(), Chat.id) elif direction.lower() == "desc": - query = query.order_by(getattr(Chat, order_by).desc()) + query = query.order_by(getattr(Chat, order_by).desc(), Chat.id) else: raise ValueError("Invalid direction for ordering") else: - query = query.order_by(Chat.updated_at.desc()) + query = query.order_by(Chat.updated_at.desc(), Chat.id) if skip: query = query.offset(skip) @@ -892,7 +892,7 @@ class ChatTable: if not include_archived: query = query.filter_by(archived=False) - query = query.order_by(Chat.updated_at.desc()).with_entities( + query = query.order_by(Chat.updated_at.desc(), Chat.id).with_entities( Chat.id, Chat.title, Chat.updated_at, Chat.created_at ) @@ -1039,14 +1039,14 @@ class ChatTable: if order_by and direction: if hasattr(Chat, order_by): if direction.lower() == "asc": - query = query.order_by(getattr(Chat, order_by).asc()) + query = query.order_by(getattr(Chat, order_by).asc(), Chat.id) elif direction.lower() == "desc": - query = query.order_by(getattr(Chat, order_by).desc()) + query = query.order_by(getattr(Chat, order_by).desc(), Chat.id) else: - query = query.order_by(Chat.updated_at.desc()) + query = query.order_by(Chat.updated_at.desc(), Chat.id) else: - query = query.order_by(Chat.updated_at.desc()) + query = query.order_by(Chat.updated_at.desc(), Chat.id) total = query.count() @@ -1188,7 +1188,7 @@ class ChatTable: if folder_ids: query = query.filter(Chat.folder_id.in_(folder_ids)) - query = query.order_by(Chat.updated_at.desc()) + query = query.order_by(Chat.updated_at.desc(), Chat.id) # Check if the database dialect is either 'sqlite' or 'postgresql' dialect_name = db.bind.dialect.name @@ -1309,7 +1309,7 @@ class ChatTable: query = query.filter(or_(Chat.pinned == False, Chat.pinned == None)) query = query.filter_by(archived=False) - query = query.order_by(Chat.updated_at.desc()) + query = query.order_by(Chat.updated_at.desc(), Chat.id) if skip: query = query.offset(skip) From bd456ed10b04ae1b614f69b7f929c78fee1a12a2 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 20:17:51 -0600 Subject: [PATCH 0821/1854] doc: changelog --- CHANGELOG.md | 49 +++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e945a6769..8fe8064414 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,11 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.8.9] - 2026-03-09 +## [0.8.9] - 2026-03-07 ### Added -- 📁 **Pyodide file system support.** Users can now upload files for Python code execution in the code interpreter. Uploaded files are available in the `/mnt/uploads/` directory, and code can write output files there for download. The file system persists across code executions within the same session. The code interpreter now also informs models that pip install is not available in the Pyodide environment, guiding them to use alternative approaches with available modules. [#3583](https://github.com/open-webui/open-webui/issues/3583), [Commit](https://github.com/open-webui/open-webui/commit/ce0ca894fea8a2904bc6f832ff186d5fe53dd0b9), [Commit](https://github.com/open-webui/open-webui/commit/989938856fdb4b4afa584ae2d18c88d5be614ae2) - ▶️ **Open Terminal notebook cell execution.** Users can now run Jupyter Notebook code cells directly in the Open Terminal file navigator, execute entire notebooks with a single click, edit and modify cells before running, and control the kernel - bringing full interactive notebook execution to the browser. [Commit](https://github.com/open-webui/open-webui/commit/4b3ed3e802d6f2ec8ee7caf358af810b7d09f789) - 🗃️ **Open Terminal SQLite browser.** Users can now browse SQLite database files directly in the Open Terminal file navigator, viewing tables and running queries without downloading them first. [Commit](https://github.com/open-webui/open-webui/commit/a181b4a731a9ec7856be08d0b045a454d1341cf4) - 📊 **Open Terminal Mermaid diagram rendering.** Markdown files with Mermaid code blocks are now rendered as diagrams directly in the Open Terminal file navigator, making it easier to visualize flowcharts and other diagrams. [Commit](https://github.com/open-webui/open-webui/commit/aaa49bdd6d6e5c10e8be554039d3cac673008fc2) @@ -21,24 +20,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 🔌 **Open Terminal port viewing.** Users can now view listening ports in the Open Terminal file navigator and open proxy connections to them directly from the UI. [Commit](https://github.com/open-webui/open-webui/commit/e08341dab3bb10e26a64eb44cbebd2d507087b03) - 🎬 **Open Terminal video previews.** Users can now preview video and audio files directly in the Open Terminal file navigator, making it easier to view media without downloading them first. [Commit](https://github.com/open-webui/open-webui/commit/c40f26946f2eaeb1587a1f8b0c643b4a5121fc06) - ✏️ **Open Terminal HTML editing.** Users can now edit HTML source files in Open Terminal with CodeMirror editor, and the save button is properly hidden in preview mode. [Commit](https://github.com/open-webui/open-webui/commit/7806cd5aef9fb0505b2c642ef70599a403cf14ba) +- 📁 **Pyodide file system support.** Users can now upload files for Python code execution in the code interpreter. Uploaded files are available in the `/mnt/uploads/` directory, and code can write output files there for download. The file system persists across code executions within the same session. The code interpreter now also informs models that pip install is not available in the Pyodide environment, guiding them to use alternative approaches with available modules. [#3583](https://github.com/open-webui/open-webui/issues/3583), [Commit](https://github.com/open-webui/open-webui/commit/ce0ca894fea8a2904bc6f832ff186d5fe53dd0b9), [Commit](https://github.com/open-webui/open-webui/commit/989938856fdb4b4afa584ae2d18c88d5be614ae2) - 🧰 **Tool files access.** Tools can now access the files from the current chat context via the files property in their metadata, enabling more powerful tool integrations. [Commit](https://github.com/open-webui/open-webui/commit/35bc8310772c222fd8a466f7d00113a84e0402d0) - ⚡ **Chat performance.** Chat messages now load and display significantly faster thanks to optimized markdown rendering, eliminating delays when viewing messages with mathematical expressions. [#22196](https://github.com/open-webui/open-webui/pull/22196), [#20878](https://github.com/open-webui/open-webui/discussions/20878) -- ⚡ **Message list performance.** Improved message list rendering performance by optimizing array operations, reducing complexity from O(n²) to O(n). [#22280](https://github.com/open-webui/open-webui/pull/22280) -- ⚡ **Streaming markdown performance.** Improved chat responsiveness during streaming by skipping unnecessary markdown re-parsing when the content hasn't changed, eliminating wasted processing during model pauses. [#22183](https://github.com/open-webui/open-webui/pull/22183) -- ⚡ **Chat streaming performance.** Chat streaming is now faster for users not using the voice call feature by skipping unnecessary text parsing that was running on every token. [#22195](https://github.com/open-webui/open-webui/pull/22195) -- ⚡ **Source list performance.** Source lists in chat now render faster thanks to optimized computation that avoids unnecessary recalculations. [#22279](https://github.com/open-webui/open-webui/pull/22279), [Commit](https://github.com/open-webui/open-webui/commit/88af78c) -- ⚡ **Source list performance.** Optimized source list rendering by moving sourceIds computation to a reactive variable, reducing unnecessary recomputations. [Commit](https://github.com/open-webui/open-webui/commit/339ed1d72e100c89d8eb26de761dfefe842ef90c) +- 📋 **Message list performance.** Improved message list rendering performance by optimizing array operations, reducing complexity from O(n²) to O(n). [#22280](https://github.com/open-webui/open-webui/pull/22280) +- 🧵 **Streaming markdown performance.** Improved chat responsiveness during streaming by skipping unnecessary markdown re-parsing when the content hasn't changed, eliminating wasted processing during model pauses. [#22183](https://github.com/open-webui/open-webui/pull/22183) +- 🏃 **Chat streaming performance.** Chat streaming is now faster for users not using the voice call feature by skipping unnecessary text parsing that was running on every token. [#22195](https://github.com/open-webui/open-webui/pull/22195) +- 📑 **Source list performance.** Source lists in chat now render faster thanks to optimized computation that avoids unnecessary recalculations, including moving sourceIds computation to a reactive variable. [#22279](https://github.com/open-webui/open-webui/pull/22279), [Commit](https://github.com/open-webui/open-webui/commit/88af78c), [Commit](https://github.com/open-webui/open-webui/commit/339ed1d72e100c89d8eb26de761dfefe842ef90c) - 💨 **Chat message tree operations.** Chat message tree operations are now significantly faster, improving overall chat responsiveness. [#22194](https://github.com/open-webui/open-webui/pull/22194) - 🚀 **Initial page load speed.** Page load is now significantly faster thanks to deferred loading of the syntax highlighting library, reducing the initial JavaScript bundle by several megabytes. [#22304](https://github.com/open-webui/open-webui/pull/22304) -- ⚡ **Action priority query optimization.** Improved performance of action priority resolution by fixing an N+1 query pattern, reducing database round-trips when loading model actions. [#22301](https://github.com/open-webui/open-webui/pull/22301) -- ⚡ **API key middleware optimization.** The API key restriction middleware was converted to a pure ASGI middleware for improved streaming performance, removing per-chunk call overhead. [#22188](https://github.com/open-webui/open-webui/pull/22188) +- 🗂️ **Action priority query optimization.** Improved performance of action priority resolution by fixing an N+1 query pattern, reducing database round-trips when loading model actions. [#22301](https://github.com/open-webui/open-webui/pull/22301) +- 🔑 **API key middleware optimization.** The API key restriction middleware was converted to a pure ASGI middleware for improved streaming performance, removing per-chunk call overhead. [#22188](https://github.com/open-webui/open-webui/pull/22188) - 🏎️ **Model list loading performance.** Model lists now load significantly faster thanks to optimized custom model matching that uses dictionary lookups instead of nested loops. [#22299](https://github.com/open-webui/open-webui/pull/22299), [Commit](https://github.com/open-webui/open-webui/commit/29160741a3defa8768a43100cb6e63c56400279c), [Commit](https://github.com/open-webui/open-webui/commit/03c6caac1fc8625f85cf1164f5a977be8005c1bc) - ⏱️ **Event call timeout configuration.** Administrators can now configure the WebSocket event call timeout via the WEBSOCKET_EVENT_CALLER_TIMEOUT environment variable, giving users more time to respond to event_call forms instead of timing out after 60 seconds. [#22222](https://github.com/open-webui/open-webui/pull/22222), [#22220](https://github.com/open-webui/open-webui/issues/22220) - 📑 **Office file previews.** Users can now preview DOCX, XLSX, and PPTX files directly in the chat file navigator, making it easier to view documents without downloading them first. [Commit](https://github.com/open-webui/open-webui/commit/890949abe6b01d201355a86c50317e20da07dd34) -- 📁 **File refresh button visibility.** The refresh button in the chat file navigator now appears when viewing files as well as directories, allowing users to refresh the file view at any time. [Commit](https://github.com/open-webui/open-webui/commit/49a2e5bf573415dae6d4c7e5bd635e499c8de77a) +- 🔄 **File refresh button visibility.** The refresh button in the chat file navigator now appears when viewing files as well as directories, allowing users to refresh the file view at any time. [Commit](https://github.com/open-webui/open-webui/commit/49a2e5bf573415dae6d4c7e5bd635e499c8de77a) - 📂 **Nested folders support.** Users can now create subfolders within parent folders, improving organization of chats. A new "Create Subfolder" option is available in the folder context menu. [#22073](https://github.com/open-webui/open-webui/pull/22073), [Commit](https://github.com/open-webui/open-webui/commit/8913f37c3d8fde7dea6d54a550357f1d495b3941) - 📢 **Banner loading on navigation.** Admin-configured banners now load when navigating to the homepage, not just on page refresh, ensuring users see new banners immediately. [#22340](https://github.com/open-webui/open-webui/pull/22340), [#22180](https://github.com/open-webui/open-webui/issues/22180) -- 📊 **System metrics via OpenTelemetry.** Administrators can now monitor Python runtime and system metrics including CPU, memory, garbage collection, and thread counts through the existing OpenTelemetry pipeline. [#22265](https://github.com/open-webui/open-webui/pull/22265) +- 📡 **System metrics via OpenTelemetry.** Administrators can now monitor Python runtime and system metrics including CPU, memory, garbage collection, and thread counts through the existing OpenTelemetry pipeline. [#22265](https://github.com/open-webui/open-webui/pull/22265) - 🔄 **General improvements.** Various improvements were implemented across the application to enhance performance, stability, and security. - 🌐 Translations for French, Finnish, Turkish, German, Simplified Chinese, and Traditional Chinese were enhanced and expanded. - 🔍 **Web search tool guidance.** The web search tool description was updated to encourage direct usage without first checking knowledge bases, making it clearer for users who want to search the web immediately. [#22264](https://github.com/open-webui/open-webui/pull/22264) @@ -49,41 +48,39 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 🔒 **SQLCipher connection stability.** Fixed a crash that occurred when using database encryption with SQLCipher by changing the default connection pool behavior, ensuring stable operation during multi-threaded operations like user signup. [#22273](https://github.com/open-webui/open-webui/pull/22273), [#22258](https://github.com/open-webui/open-webui/issues/22258) - 🛑 **Stop sequence error.** Fixed a bug where setting stop sequences on a model caused the chat to fail with a split error, preventing any responses from being returned. The fix handles both string and array formats for stop tokens. [#22251](https://github.com/open-webui/open-webui/issues/22251), [Commit](https://github.com/open-webui/open-webui/commit/c7d1d1e390a79c6c86d4bfe439fd7de6f5fb060f) - 🔐 **Microsoft OAuth refresh token fix.** Fixed a bug where Microsoft OAuth refresh token requests failed with error AADSTS90009 by adding support for the required scope parameter. Users can now stay logged in reliably with Microsoft OAuth. [#22359](https://github.com/open-webui/open-webui/pull/22359) -- 🔧 **Parameterless tool calls.** Fixed parameterless tool calls failing during streaming by correcting the default arguments initialization, eliminating unnecessary model retries. [#22189](https://github.com/open-webui/open-webui/pull/22189) +- 🛠️ **Parameterless tool calls.** Fixed parameterless tool calls failing during streaming by correcting the default arguments initialization, eliminating unnecessary model retries. [#22189](https://github.com/open-webui/open-webui/pull/22189) - 🔧 **Tool call streaming fixes.** Fixed two bugs where streaming tool calls failed silently for models like GPT-5: function names were incorrectly duplicated when sent in multiple delta chunks, and arguments containing multiple JSON objects were not properly split. Tools now execute correctly instead of failing without explanation. [#22177](https://github.com/open-webui/open-webui/issues/22177), [Commit](https://github.com/open-webui/open-webui/commit/d7efdcce2b1cdbe1637a469294bf9d52dbacab53), [Commit](https://github.com/open-webui/open-webui/commit/459a60a24240eab33441ed50f4f68cc27e65a037) - 🔗 **Tool server URL trailing slash.** Fixed tool server connection failures when URLs have trailing slashes by stripping them before path concatenation. Previously, URLs like "http://host:8080/v1/" + "/openapi.json" produced double-slash URLs that some servers rejected. [#22116](https://github.com/open-webui/open-webui/pull/22116), [#21917](https://github.com/open-webui/open-webui/issues/21917) -- 🔧 **Citation parser error handling.** Fixed crashes when tools return error strings instead of expected data structures by adding type guards to the citation parser. The system now returns an empty source list instead of crashing with AttributeError. [#22118](https://github.com/open-webui/open-webui/pull/22118) +- 🛡️ **Citation parser error handling.** Fixed crashes when tools return error strings instead of expected data structures by adding type guards to the citation parser. The system now returns an empty source list instead of crashing with AttributeError. [#22118](https://github.com/open-webui/open-webui/pull/22118) - 🧠 **Artifacts memory leak.** Fixed a memory leak where Svelte store subscriptions in the Artifacts component were not properly cleaned up when the component unmounted, causing memory to accumulate over time. [#22303](https://github.com/open-webui/open-webui/pull/22303) - ♾️ **Artifacts reactive loop fix.** Fixed an infinite reactive loop in chat when artifacts are present by moving the animation frame logic outside the reactive block, preventing continuous re-rendering and CPU usage. [#22238](https://github.com/open-webui/open-webui/pull/22238), [Commit](https://github.com/open-webui/open-webui/commit/626fcff417afba642f4f71e0498267a21435c524) - 🔀 **Artifact navigation.** Artifact navigation via arrow buttons now works correctly; the selected artifact is no longer reset when content updates. [#22239](https://github.com/open-webui/open-webui/pull/22239) -- 🖼️ **Artifact thinking block fix.** Fixed a bug where HTML preview rendered code blocks inside thinking blocks for certain models like Mistral and Z.ai, causing stray code with ">" symbols to appear before the actual artifact. The fix strips thinking blocks before extracting code for artifact rendering. [#22267](https://github.com/open-webui/open-webui/issues/22267), [Commit](https://github.com/open-webui/open-webui/commit/35bc8310772c222fd8a466f7d00113a84e0402d0) +- 🧩 **Artifact thinking block fix.** Fixed a bug where HTML preview rendered code blocks inside thinking blocks for certain models like Mistral and Z.ai, causing stray code with ">" symbols to appear before the actual artifact. The fix strips thinking blocks before extracting code for artifact rendering. [#22267](https://github.com/open-webui/open-webui/issues/22267), [Commit](https://github.com/open-webui/open-webui/commit/35bc8310772c222fd8a466f7d00113a84e0402d0) - 💬 **Floating Quick Actions availability.** Fixed an issue where the "Ask" and "Explain" Floating Quick Actions were missing when selecting text in chats that used a model that is no longer available. [#22149](https://github.com/open-webui/open-webui/pull/22149), [#22139](https://github.com/open-webui/open-webui/issues/22139) -- 💬 **Follow-up suggestions.** Fixed follow-up suggestions not appearing by correcting contradictory format instructions in the prompt template, ensuring the LLM returns the correct JSON object format. [#22212](https://github.com/open-webui/open-webui/pull/22212) +- 💡 **Follow-up suggestions.** Fixed follow-up suggestions not appearing by correcting contradictory format instructions in the prompt template, ensuring the LLM returns the correct JSON object format. [#22212](https://github.com/open-webui/open-webui/pull/22212) - 🔊 **TTS thinking content.** Fixed TTS playback reading think tags instead of skipping them by handling edge cases where code blocks inside thinking content prevented proper tag removal. [#22237](https://github.com/open-webui/open-webui/pull/22237), [#22197](https://github.com/open-webui/open-webui/issues/22197) - 🎨 **Button spinner alignment.** Button spinners across multiple modals now align correctly and stay on the same line as the button text, fixing layout issues when loading states are displayed. [#22227](https://github.com/open-webui/open-webui/pull/22227) - 🔌 **Terminal keepalive.** Terminal connections now stay active without being closed by idle timeouts from proxies or load balancers, and spurious disconnection messages no longer appear. [Commit](https://github.com/open-webui/open-webui/commit/ca2aaf0321c219d041e92e2c0c842a4e424732ef) -- 📁 **Chat archive handler.** The archive button in the chat navbar now actually archives the chat and refreshes the chat list, instead of doing nothing. [#22229](https://github.com/open-webui/open-webui/pull/22229) +- 🗃️ **Chat archive handler.** The archive button in the chat navbar now actually archives the chat and refreshes the chat list, instead of doing nothing. [#22229](https://github.com/open-webui/open-webui/pull/22229) - 🐍 **BeautifulSoup4 dependency.** Added the missing BeautifulSoup4 package to backend requirements, fixing failures when using features that depend on HTML parsing. [#22231](https://github.com/open-webui/open-webui/pull/22231) - 👥 **Group users default sort.** Group members in the admin panel now sort by last active time by default instead of creation date, making it easier to find active users. [#22211](https://github.com/open-webui/open-webui/pull/22211) -- 🔧 **Tool access permissions.** Users can now change tool and skill access permissions from private to public without errors. [#22325](https://github.com/open-webui/open-webui/pull/22325), [#22324](https://github.com/open-webui/open-webui/issues/22324) +- 🔓 **Tool access permissions.** Users can now change tool and skill access permissions from private to public without errors. [#22325](https://github.com/open-webui/open-webui/pull/22325), [#22324](https://github.com/open-webui/open-webui/issues/22324) - 🖥️ **Open Terminal permission fix.** Open Terminal is now visible without requiring "Allow Speech to Text" permission, fixing an issue where users without microphone access couldn't access the terminal feature. [#22374](https://github.com/open-webui/open-webui/issues/22374), [Commit](https://github.com/open-webui/open-webui/commit/70a31a9a57bdd0690ac270f31ebd1b46e8fdfa98) - 📌 **Stale pinned models cleanup.** Pinned models that are deleted or hidden are now automatically unpinned, keeping your pinned models list up to date. [Commit](https://github.com/open-webui/open-webui/commit/af4500e5040c8343d339cd88dd1d2fb6138c7a72) -- 🔧 **OpenTelemetry metric descriptions.** Fixed conflicting metric instrument descriptions that caused warnings in the OpenTelemetry collector, resulting in cleaner telemetry logs for administrators. [#22293](https://github.com/open-webui/open-webui/pull/22293) -- 📊 **Non-streaming token tracking.** Token usage from non-streaming chat responses is now correctly saved to the database, fixing missing token counts in the Admin Panel analytics. Previously, non-streaming responses saved NULL usage data, causing messages to be excluded from token aggregation queries. [#22166](https://github.com/open-webui/open-webui/pull/22166) -- 🔧 **Citation parser error handling.** Fixed crashes when tools return error strings instead of expected data structures by adding type guards to the citation parser. The system now returns an empty source list instead of crashing with AttributeError. [#22118](https://github.com/open-webui/open-webui/pull/22118) -- 🔗 **Tool server URL trailing slash.** Fixed tool server connection failures when URLs have trailing slashes by stripping them before path concatenation. Previously, URLs like "http://host:8080/v1/" + "/openapi.json" produced double-slash URLs that some servers rejected. [#22116](https://github.com/open-webui/open-webui/pull/22116), [#21917](https://github.com/open-webui/open-webui/issues/21917) -- 📝 **Inline code typing.** Fixed a bug where typing inline code with backticks incorrectly deleted the character immediately before the opening backtick, so text formatted as inline code now correctly produces the full word instead of missing the last character. [#20417](https://github.com/open-webui/open-webui/issues/20417), [Commit](https://github.com/open-webui/open-webui/commit/e303c3da3b174da9e92a79b174f85ba574ca06ef) +- 📏 **OpenTelemetry metric descriptions.** Fixed conflicting metric instrument descriptions that caused warnings in the OpenTelemetry collector, resulting in cleaner telemetry logs for administrators. [#22293](https://github.com/open-webui/open-webui/pull/22293) +- 🔢 **Non-streaming token tracking.** Token usage from non-streaming chat responses is now correctly saved to the database, fixing missing token counts in the Admin Panel analytics. Previously, non-streaming responses saved NULL usage data, causing messages to be excluded from token aggregation queries. [#22166](https://github.com/open-webui/open-webui/pull/22166) +- ⌨️ **Inline code typing.** Fixed a bug where typing inline code with backticks incorrectly deleted the character immediately before the opening backtick, so text formatted as inline code now correctly produces the full word instead of missing the last character. [#20417](https://github.com/open-webui/open-webui/issues/20417), [Commit](https://github.com/open-webui/open-webui/commit/e303c3da3b174da9e92a79b174f85ba574ca06ef) - 📝 **Variable input newlines.** Fixed a bug where variables containing newlines were not displayed correctly in chat messages, and input values from Windows systems are now properly normalized to use standard line endings. [#21447](https://github.com/open-webui/open-webui/issues/21447), [Commit](https://github.com/open-webui/open-webui/commit/7b2f597b30c77ef300d1966e1c6a3edfdb0c465d) - 📷 **Android photo capture.** Fixed an issue where the first photo taken in chat appeared completely black on some Android devices by using an alternative canvas export method. [#22317](https://github.com/open-webui/open-webui/pull/22317) -- 🖥️ **Open Terminal Windows path fix.** Fixed a bug where navigating back to parent directories on Windows added an incorrect leading slash, causing directory loads to fail. Paths are now properly normalized for Windows drive letters. [#22352](https://github.com/open-webui/open-webui/issues/22352), [Commit](https://github.com/open-webui/open-webui/commit/044fd1bd15cae06a5c56a321ca79d8362942f66a) +- 🪟 **Open Terminal Windows path fix.** Fixed a bug where navigating back to parent directories on Windows added an incorrect leading slash, causing directory loads to fail. Paths are now properly normalized for Windows drive letters. [#22352](https://github.com/open-webui/open-webui/issues/22352), [Commit](https://github.com/open-webui/open-webui/commit/044fd1bd15cae06a5c56a321ca79d8362942f66a) - 🖼️ **Chat overview profile image sizing.** Fixed a bug where profile images in the chat overview could shrink incorrectly in tight spaces. The images now maintain their proper size with the flex-shrink-0 property. [#22261](https://github.com/open-webui/open-webui/pull/22261) -- 💬 **Queued messages display.** Fixed an issue where queued messages could be cut off or hidden. The queued messages area now scrolls properly when content exceeds the visible area, showing up to 25% of the viewport height. [#22176](https://github.com/open-webui/open-webui/pull/22176) +- 📨 **Queued messages display.** Fixed an issue where queued messages could be cut off or hidden. The queued messages area now scrolls properly when content exceeds the visible area, showing up to 25% of the viewport height. [#22176](https://github.com/open-webui/open-webui/pull/22176) - 🎨 **Image generation in temporary chats.** Generated images now display correctly in temporary chat mode when using builtin image generation tools. Previously, images were not shown because the code was overwriting the image list with a null database response. [#22330](https://github.com/open-webui/open-webui/pull/22330), [#22309](https://github.com/open-webui/open-webui/issues/22309) - 🤖 **Ollama model unload fix.** Fixed a bug where unloading a model from Ollama via the Open WebUI proxy failed with a "Field required" error for the prompt field. The proxy now correctly allows omitting the prompt when using keep_alive: 0 to unload models. [#22260](https://github.com/open-webui/open-webui/issues/22260), [Commit](https://github.com/open-webui/open-webui/commit/95b65ff751f91131b633cb128ff2decdd87c4a85) - 📢 **Banner type dropdown fix.** Fixed a bug where selecting a banner type required two clicks to register, as the first selection was being swallowed due to DOM structure changes. The dropdown now works correctly on the first click. [#22378](https://github.com/open-webui/open-webui/pull/22378) -- 📊 **Analytics URL encoding fix.** Fixed a bug where the Analytics page failed to load data for models with slashes in their ID, such as "anthropic/claude-opus-4.6". The frontend now properly URL-encodes forward slashes, allowing model analytics to load correctly. [#22380](https://github.com/open-webui/open-webui/issues/22380), [#22382](https://github.com/open-webui/open-webui/pull/22382) +- 📈 **Analytics URL encoding fix.** Fixed a bug where the Analytics page failed to load data for models with slashes in their ID, such as "anthropic/claude-opus-4.6". The frontend now properly URL-encodes forward slashes, allowing model analytics to load correctly. [#22380](https://github.com/open-webui/open-webui/issues/22380), [#22382](https://github.com/open-webui/open-webui/pull/22382) - 📊 **Analytics chat list duplicate fix.** Fixed a bug where the Analytics page chat list threw an "each_key_duplicate" Svelte error when chat IDs were duplicated during pagination. The fix adds deterministic ordering to prevent duplicate entries. [#22383](https://github.com/open-webui/open-webui/pull/22383) -- 📁 **Folder knowledge base native tool call fix.** Fixed a bug where folders with attached knowledge bases were querying the knowledge base twice when using native tool call mode. The fix now correctly separates knowledge files from regular attachments, letting the builtin query_knowledge_files tool handle knowledge searches instead of duplicating RAG queries. [#22236](https://github.com/open-webui/open-webui/issues/22236), [Commit](https://github.com/open-webui/open-webui/commit/967b1137dcb7a52615f17d086ee89095bb9b60f3), [Commit](https://github.com/open-webui/open-webui/commit/80b5896b70d07ea868e2010b187430d43c9808f0) +- 📂 **Folder knowledge base native tool call fix.** Fixed a bug where folders with attached knowledge bases were querying the knowledge base twice when using native tool call mode. The fix now correctly separates knowledge files from regular attachments, letting the builtin query_knowledge_files tool handle knowledge searches instead of duplicating RAG queries. [#22236](https://github.com/open-webui/open-webui/issues/22236), [Commit](https://github.com/open-webui/open-webui/commit/967b1137dcb7a52615f17d086ee89095bb9b60f3), [Commit](https://github.com/open-webui/open-webui/commit/80b5896b70d07ea868e2010b187430d43c9808f0) ## [0.8.8] - 2026-03-02 From 0948235c3b09427830b9e3eb06dd5f1eb497a17f Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 20:21:06 -0600 Subject: [PATCH 0822/1854] refac --- CHANGELOG.md | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fe8064414..259f2f61ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,32 +11,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - ▶️ **Open Terminal notebook cell execution.** Users can now run Jupyter Notebook code cells directly in the Open Terminal file navigator, execute entire notebooks with a single click, edit and modify cells before running, and control the kernel - bringing full interactive notebook execution to the browser. [Commit](https://github.com/open-webui/open-webui/commit/4b3ed3e802d6f2ec8ee7caf358af810b7d09f789) - 🗃️ **Open Terminal SQLite browser.** Users can now browse SQLite database files directly in the Open Terminal file navigator, viewing tables and running queries without downloading them first. [Commit](https://github.com/open-webui/open-webui/commit/a181b4a731a9ec7856be08d0b045a454d1341cf4) -- 📊 **Open Terminal Mermaid diagram rendering.** Markdown files with Mermaid code blocks are now rendered as diagrams directly in the Open Terminal file navigator, making it easier to visualize flowcharts and other diagrams. [Commit](https://github.com/open-webui/open-webui/commit/aaa49bdd6d6e5c10e8be554039d3cac673008fc2) +- 📉 **Open Terminal Mermaid diagram rendering.** Markdown files with Mermaid code blocks are now rendered as diagrams directly in the Open Terminal file navigator, making it easier to visualize flowcharts and other diagrams. [Commit](https://github.com/open-webui/open-webui/commit/aaa49bdd6d6e5c10e8be554039d3cac673008fc2) - 📓 **Open Terminal Jupyter Notebook previews.** Users can now preview Jupyter Notebook files directly in the Open Terminal file navigator, making it easier to view notebook content without downloading them first. [Commit](https://github.com/open-webui/open-webui/commit/b081e33c0a37585a1ee60b6e0e1ea03457f1e5f4) - 🔃 **Open Terminal auto-refresh.** The Open Terminal file navigator now automatically refreshes when the model writes or modifies files, keeping the view in sync without manual refresh. [Commit](https://github.com/open-webui/open-webui/commit/828656b35f04bf486609183799cf8aa2e9850a76) -- 📋 **Open Terminal file copy button.** Users can now copy file contents directly to clipboard in the Open Terminal file navigator with a single click, making it easier to quickly grab file content without downloading. [Commit](https://github.com/open-webui/open-webui/commit/f5ea1ce250cb02fbc583c6cb3f52a923912d0178) +- 📎 **Open Terminal file copy button.** Users can now copy file contents directly to clipboard in the Open Terminal file navigator with a single click, making it easier to quickly grab file content without downloading. [Commit](https://github.com/open-webui/open-webui/commit/f5ea1ce250cb02fbc583c6cb3f52a923912d0178) - 💻 **Code syntax highlighting and XLSX improvements in Open Terminal.** Code files now display with syntax highlighting in the Open Terminal file navigator, and XLSX spreadsheets now show column headers and row numbers for easier navigation. [Commit](https://github.com/open-webui/open-webui/commit/f962bae98306ea9264967b78b803397f4821f9b0) - 🌳 **Open Terminal JSON tree view.** JSON, JSONC, JSONL, and JSON5 files now display as interactive collapsible tree views in the Open Terminal file navigator, and SVG files render as preview images with syntax highlighting support. [Commit](https://github.com/open-webui/open-webui/commit/f4c38e6001dd9d4853ed923e0bc5e790c4fd9941) -- 🔌 **Open Terminal port viewing.** Users can now view listening ports in the Open Terminal file navigator and open proxy connections to them directly from the UI. [Commit](https://github.com/open-webui/open-webui/commit/e08341dab3bb10e26a64eb44cbebd2d507087b03) +- 🛜 **Open Terminal port viewing.** Users can now view listening ports in the Open Terminal file navigator and open proxy connections to them directly from the UI. [Commit](https://github.com/open-webui/open-webui/commit/e08341dab3bb10e26a64eb44cbebd2d507087b03) - 🎬 **Open Terminal video previews.** Users can now preview video and audio files directly in the Open Terminal file navigator, making it easier to view media without downloading them first. [Commit](https://github.com/open-webui/open-webui/commit/c40f26946f2eaeb1587a1f8b0c643b4a5121fc06) - ✏️ **Open Terminal HTML editing.** Users can now edit HTML source files in Open Terminal with CodeMirror editor, and the save button is properly hidden in preview mode. [Commit](https://github.com/open-webui/open-webui/commit/7806cd5aef9fb0505b2c642ef70599a403cf14ba) +- 📄 **Open Terminal DOCX preview.** Word documents generated or modified by the AI can now be viewed directly in the file navigator with formatted text, tables, and images rendered inline — no need to download and open in a separate application. [Commit](https://github.com/open-webui/open-webui/commit/890949abe6b01d201355a86c50317e20da07dd34) +- 📊 **Open Terminal XLSX preview.** Excel spreadsheets in the file navigator now render as interactive tables with column headers and row numbers, making it easy to verify data the AI has generated or processed. [Commit](https://github.com/open-webui/open-webui/commit/890949abe6b01d201355a86c50317e20da07dd34) +- 📽️ **Open Terminal PPTX preview.** PowerPoint presentations created by the AI can now be viewed slide-by-slide directly in the file navigator, enabling quick review and iteration without leaving the browser. [Commit](https://github.com/open-webui/open-webui/commit/890949abe6b01d201355a86c50317e20da07dd34) - 📁 **Pyodide file system support.** Users can now upload files for Python code execution in the code interpreter. Uploaded files are available in the `/mnt/uploads/` directory, and code can write output files there for download. The file system persists across code executions within the same session. The code interpreter now also informs models that pip install is not available in the Pyodide environment, guiding them to use alternative approaches with available modules. [#3583](https://github.com/open-webui/open-webui/issues/3583), [Commit](https://github.com/open-webui/open-webui/commit/ce0ca894fea8a2904bc6f832ff186d5fe53dd0b9), [Commit](https://github.com/open-webui/open-webui/commit/989938856fdb4b4afa584ae2d18c88d5be614ae2) - 🧰 **Tool files access.** Tools can now access the files from the current chat context via the files property in their metadata, enabling more powerful tool integrations. [Commit](https://github.com/open-webui/open-webui/commit/35bc8310772c222fd8a466f7d00113a84e0402d0) - ⚡ **Chat performance.** Chat messages now load and display significantly faster thanks to optimized markdown rendering, eliminating delays when viewing messages with mathematical expressions. [#22196](https://github.com/open-webui/open-webui/pull/22196), [#20878](https://github.com/open-webui/open-webui/discussions/20878) -- 📋 **Message list performance.** Improved message list rendering performance by optimizing array operations, reducing complexity from O(n²) to O(n). [#22280](https://github.com/open-webui/open-webui/pull/22280) +- 📜 **Message list performance.** Improved message list rendering performance by optimizing array operations, reducing complexity from O(n²) to O(n). [#22280](https://github.com/open-webui/open-webui/pull/22280) - 🧵 **Streaming markdown performance.** Improved chat responsiveness during streaming by skipping unnecessary markdown re-parsing when the content hasn't changed, eliminating wasted processing during model pauses. [#22183](https://github.com/open-webui/open-webui/pull/22183) - 🏃 **Chat streaming performance.** Chat streaming is now faster for users not using the voice call feature by skipping unnecessary text parsing that was running on every token. [#22195](https://github.com/open-webui/open-webui/pull/22195) -- 📑 **Source list performance.** Source lists in chat now render faster thanks to optimized computation that avoids unnecessary recalculations, including moving sourceIds computation to a reactive variable. [#22279](https://github.com/open-webui/open-webui/pull/22279), [Commit](https://github.com/open-webui/open-webui/commit/88af78c), [Commit](https://github.com/open-webui/open-webui/commit/339ed1d72e100c89d8eb26de761dfefe842ef90c) +- 🔖 **Source list performance.** Source lists in chat now render faster thanks to optimized computation that avoids unnecessary recalculations, including moving sourceIds computation to a reactive variable. [#22279](https://github.com/open-webui/open-webui/pull/22279), [Commit](https://github.com/open-webui/open-webui/commit/88af78c), [Commit](https://github.com/open-webui/open-webui/commit/339ed1d72e100c89d8eb26de761dfefe842ef90c) - 💨 **Chat message tree operations.** Chat message tree operations are now significantly faster, improving overall chat responsiveness. [#22194](https://github.com/open-webui/open-webui/pull/22194) - 🚀 **Initial page load speed.** Page load is now significantly faster thanks to deferred loading of the syntax highlighting library, reducing the initial JavaScript bundle by several megabytes. [#22304](https://github.com/open-webui/open-webui/pull/22304) -- 🗂️ **Action priority query optimization.** Improved performance of action priority resolution by fixing an N+1 query pattern, reducing database round-trips when loading model actions. [#22301](https://github.com/open-webui/open-webui/pull/22301) +- 🗓️ **Action priority query optimization.** Improved performance of action priority resolution by fixing an N+1 query pattern, reducing database round-trips when loading model actions. [#22301](https://github.com/open-webui/open-webui/pull/22301) - 🔑 **API key middleware optimization.** The API key restriction middleware was converted to a pure ASGI middleware for improved streaming performance, removing per-chunk call overhead. [#22188](https://github.com/open-webui/open-webui/pull/22188) - 🏎️ **Model list loading performance.** Model lists now load significantly faster thanks to optimized custom model matching that uses dictionary lookups instead of nested loops. [#22299](https://github.com/open-webui/open-webui/pull/22299), [Commit](https://github.com/open-webui/open-webui/commit/29160741a3defa8768a43100cb6e63c56400279c), [Commit](https://github.com/open-webui/open-webui/commit/03c6caac1fc8625f85cf1164f5a977be8005c1bc) - ⏱️ **Event call timeout configuration.** Administrators can now configure the WebSocket event call timeout via the WEBSOCKET_EVENT_CALLER_TIMEOUT environment variable, giving users more time to respond to event_call forms instead of timing out after 60 seconds. [#22222](https://github.com/open-webui/open-webui/pull/22222), [#22220](https://github.com/open-webui/open-webui/issues/22220) -- 📑 **Office file previews.** Users can now preview DOCX, XLSX, and PPTX files directly in the chat file navigator, making it easier to view documents without downloading them first. [Commit](https://github.com/open-webui/open-webui/commit/890949abe6b01d201355a86c50317e20da07dd34) -- 🔄 **File refresh button visibility.** The refresh button in the chat file navigator now appears when viewing files as well as directories, allowing users to refresh the file view at any time. [Commit](https://github.com/open-webui/open-webui/commit/49a2e5bf573415dae6d4c7e5bd635e499c8de77a) +- 🔁 **File refresh button visibility.** The refresh button in the chat file navigator now appears when viewing files as well as directories, allowing users to refresh the file view at any time. [Commit](https://github.com/open-webui/open-webui/commit/49a2e5bf573415dae6d4c7e5bd635e499c8de77a) - 📂 **Nested folders support.** Users can now create subfolders within parent folders, improving organization of chats. A new "Create Subfolder" option is available in the folder context menu. [#22073](https://github.com/open-webui/open-webui/pull/22073), [Commit](https://github.com/open-webui/open-webui/commit/8913f37c3d8fde7dea6d54a550357f1d495b3941) -- 📢 **Banner loading on navigation.** Admin-configured banners now load when navigating to the homepage, not just on page refresh, ensuring users see new banners immediately. [#22340](https://github.com/open-webui/open-webui/pull/22340), [#22180](https://github.com/open-webui/open-webui/issues/22180) +- 🔔 **Banner loading on navigation.** Admin-configured banners now load when navigating to the homepage, not just on page refresh, ensuring users see new banners immediately. [#22340](https://github.com/open-webui/open-webui/pull/22340), [#22180](https://github.com/open-webui/open-webui/issues/22180) - 📡 **System metrics via OpenTelemetry.** Administrators can now monitor Python runtime and system metrics including CPU, memory, garbage collection, and thread counts through the existing OpenTelemetry pipeline. [#22265](https://github.com/open-webui/open-webui/pull/22265) - 🔄 **General improvements.** Various improvements were implemented across the application to enhance performance, stability, and security. - 🌐 Translations for French, Finnish, Turkish, German, Simplified Chinese, and Traditional Chinese were enhanced and expanded. @@ -60,8 +62,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 💡 **Follow-up suggestions.** Fixed follow-up suggestions not appearing by correcting contradictory format instructions in the prompt template, ensuring the LLM returns the correct JSON object format. [#22212](https://github.com/open-webui/open-webui/pull/22212) - 🔊 **TTS thinking content.** Fixed TTS playback reading think tags instead of skipping them by handling edge cases where code blocks inside thinking content prevented proper tag removal. [#22237](https://github.com/open-webui/open-webui/pull/22237), [#22197](https://github.com/open-webui/open-webui/issues/22197) - 🎨 **Button spinner alignment.** Button spinners across multiple modals now align correctly and stay on the same line as the button text, fixing layout issues when loading states are displayed. [#22227](https://github.com/open-webui/open-webui/pull/22227) -- 🔌 **Terminal keepalive.** Terminal connections now stay active without being closed by idle timeouts from proxies or load balancers, and spurious disconnection messages no longer appear. [Commit](https://github.com/open-webui/open-webui/commit/ca2aaf0321c219d041e92e2c0c842a4e424732ef) -- 🗃️ **Chat archive handler.** The archive button in the chat navbar now actually archives the chat and refreshes the chat list, instead of doing nothing. [#22229](https://github.com/open-webui/open-webui/pull/22229) +- 📶 **Terminal keepalive.** Terminal connections now stay active without being closed by idle timeouts from proxies or load balancers, and spurious disconnection messages no longer appear. [Commit](https://github.com/open-webui/open-webui/commit/ca2aaf0321c219d041e92e2c0c842a4e424732ef) +- 📥 **Chat archive handler.** The archive button in the chat navbar now actually archives the chat and refreshes the chat list, instead of doing nothing. [#22229](https://github.com/open-webui/open-webui/pull/22229) - 🐍 **BeautifulSoup4 dependency.** Added the missing BeautifulSoup4 package to backend requirements, fixing failures when using features that depend on HTML parsing. [#22231](https://github.com/open-webui/open-webui/pull/22231) - 👥 **Group users default sort.** Group members in the admin panel now sort by last active time by default instead of creation date, making it easier to find active users. [#22211](https://github.com/open-webui/open-webui/pull/22211) - 🔓 **Tool access permissions.** Users can now change tool and skill access permissions from private to public without errors. [#22325](https://github.com/open-webui/open-webui/pull/22325), [#22324](https://github.com/open-webui/open-webui/issues/22324) @@ -75,11 +77,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 🪟 **Open Terminal Windows path fix.** Fixed a bug where navigating back to parent directories on Windows added an incorrect leading slash, causing directory loads to fail. Paths are now properly normalized for Windows drive letters. [#22352](https://github.com/open-webui/open-webui/issues/22352), [Commit](https://github.com/open-webui/open-webui/commit/044fd1bd15cae06a5c56a321ca79d8362942f66a) - 🖼️ **Chat overview profile image sizing.** Fixed a bug where profile images in the chat overview could shrink incorrectly in tight spaces. The images now maintain their proper size with the flex-shrink-0 property. [#22261](https://github.com/open-webui/open-webui/pull/22261) - 📨 **Queued messages display.** Fixed an issue where queued messages could be cut off or hidden. The queued messages area now scrolls properly when content exceeds the visible area, showing up to 25% of the viewport height. [#22176](https://github.com/open-webui/open-webui/pull/22176) -- 🎨 **Image generation in temporary chats.** Generated images now display correctly in temporary chat mode when using builtin image generation tools. Previously, images were not shown because the code was overwriting the image list with a null database response. [#22330](https://github.com/open-webui/open-webui/pull/22330), [#22309](https://github.com/open-webui/open-webui/issues/22309) +- 🖌️ **Image generation in temporary chats.** Generated images now display correctly in temporary chat mode when using builtin image generation tools. Previously, images were not shown because the code was overwriting the image list with a null database response. [#22330](https://github.com/open-webui/open-webui/pull/22330), [#22309](https://github.com/open-webui/open-webui/issues/22309) - 🤖 **Ollama model unload fix.** Fixed a bug where unloading a model from Ollama via the Open WebUI proxy failed with a "Field required" error for the prompt field. The proxy now correctly allows omitting the prompt when using keep_alive: 0 to unload models. [#22260](https://github.com/open-webui/open-webui/issues/22260), [Commit](https://github.com/open-webui/open-webui/commit/95b65ff751f91131b633cb128ff2decdd87c4a85) -- 📢 **Banner type dropdown fix.** Fixed a bug where selecting a banner type required two clicks to register, as the first selection was being swallowed due to DOM structure changes. The dropdown now works correctly on the first click. [#22378](https://github.com/open-webui/open-webui/pull/22378) +- 🏷️ **Banner type dropdown fix.** Fixed a bug where selecting a banner type required two clicks to register, as the first selection was being swallowed due to DOM structure changes. The dropdown now works correctly on the first click. [#22378](https://github.com/open-webui/open-webui/pull/22378) - 📈 **Analytics URL encoding fix.** Fixed a bug where the Analytics page failed to load data for models with slashes in their ID, such as "anthropic/claude-opus-4.6". The frontend now properly URL-encodes forward slashes, allowing model analytics to load correctly. [#22380](https://github.com/open-webui/open-webui/issues/22380), [#22382](https://github.com/open-webui/open-webui/pull/22382) -- 📊 **Analytics chat list duplicate fix.** Fixed a bug where the Analytics page chat list threw an "each_key_duplicate" Svelte error when chat IDs were duplicated during pagination. The fix adds deterministic ordering to prevent duplicate entries. [#22383](https://github.com/open-webui/open-webui/pull/22383) +- 📋 **Analytics chat list duplicate fix.** Fixed a bug where the Analytics page chat list threw an "each_key_duplicate" Svelte error when chat IDs were duplicated during pagination. The fix adds deterministic ordering to prevent duplicate entries. [#22383](https://github.com/open-webui/open-webui/pull/22383) - 📂 **Folder knowledge base native tool call fix.** Fixed a bug where folders with attached knowledge bases were querying the knowledge base twice when using native tool call mode. The fix now correctly separates knowledge files from regular attachments, letting the builtin query_knowledge_files tool handle knowledge searches instead of duplicating RAG queries. [#22236](https://github.com/open-webui/open-webui/issues/22236), [Commit](https://github.com/open-webui/open-webui/commit/967b1137dcb7a52615f17d086ee89095bb9b60f3), [Commit](https://github.com/open-webui/open-webui/commit/80b5896b70d07ea868e2010b187430d43c9808f0) ## [0.8.8] - 2026-03-02 From 9bb226dc52b13a38922328a3dd58a22137c2cd47 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 20:21:33 -0600 Subject: [PATCH 0823/1854] refac --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index e19c790a5b..d50d38d848 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -92,7 +92,7 @@ Deleting it will trigger the CLA-Bot to INVALIDATE your PR. Your PR will NOT be reviewed or merged until you check the box below confirming that you have read and agree to the terms of the CLA. --> -- [ ] By submitting this pull request, I confirm that I have read and fully agree to the [Contributor License Agreement (CLA)](./CLA.md), and I am providing my contributions under its terms. +- [ ] By submitting this pull request, I confirm that I have read and fully agree to the [Contributor License Agreement (CLA)](https://github.com/open-webui/open-webui/blob/main/CONTRIBUTOR_LICENSE_AGREEMENT), and I am providing my contributions under its terms. > [!NOTE] > Deleting the CLA section will lead to immediate closure of your PR and it will not be merged in. From b1048fc9bcc55ced07a431fa4a14e8b1f7e4a170 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 20:22:01 -0600 Subject: [PATCH 0824/1854] refac --- backend/open_webui/models/chats.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/models/chats.py b/backend/open_webui/models/chats.py index 9b8261b8d4..78aa4d3ded 100644 --- a/backend/open_webui/models/chats.py +++ b/backend/open_webui/models/chats.py @@ -1039,9 +1039,13 @@ class ChatTable: if order_by and direction: if hasattr(Chat, order_by): if direction.lower() == "asc": - query = query.order_by(getattr(Chat, order_by).asc(), Chat.id) + query = query.order_by( + getattr(Chat, order_by).asc(), Chat.id + ) elif direction.lower() == "desc": - query = query.order_by(getattr(Chat, order_by).desc(), Chat.id) + query = query.order_by( + getattr(Chat, order_by).desc(), Chat.id + ) else: query = query.order_by(Chat.updated_at.desc(), Chat.id) From 368912ca6261788123c5bc847ff8973a38db48c3 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 20:28:17 -0600 Subject: [PATCH 0825/1854] refac --- backend/open_webui/utils/middleware.py | 29 +++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 40b8dc78a3..db9321f5e1 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -4493,14 +4493,29 @@ async def streaming_chat_response_handler(response, ctx): form_data["messages"], ) - # Combine file and tool sources into one RAG - # template application. - form_data["messages"] = apply_source_context_to_messages( - request, - form_data["messages"], - metadata.get("sources", []) + all_tool_call_sources, - user_message, + # Build context: file sources with content, + # tool sources as citation markers only. + ctx = get_source_context(metadata.get("sources", [])) + ctx += get_source_context( + all_tool_call_sources, include_content=False ) + ctx = ctx.strip() + if ctx: + rag = rag_template( + request.app.state.config.RAG_TEMPLATE, + ctx, + user_message, + ) + if RAG_SYSTEM_CONTEXT: + form_data["messages"] = ( + add_or_update_system_message( + rag, form_data["messages"], append=True + ) + ) + else: + form_data["messages"] = add_or_update_user_message( + rag, form_data["messages"], append=False + ) tool_call_sources.clear() await event_emitter( From f047b6b3aec1b6872c94873d5581c0d0d742e4e6 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 20:30:42 -0600 Subject: [PATCH 0826/1854] refac --- backend/open_webui/utils/middleware.py | 35 +++++++++++++------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index db9321f5e1..2afd5f87bf 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -929,25 +929,21 @@ def apply_source_context_to_messages( if not sources or not user_message: return messages - context_string = get_source_context(sources, include_content) + context = get_source_context(sources, include_content) - context_string = context_string.strip() - if not context_string: + context = context.strip() + if not context: return messages if RAG_SYSTEM_CONTEXT: return add_or_update_system_message( - rag_template( - request.app.state.config.RAG_TEMPLATE, context_string, user_message - ), + rag_template(request.app.state.config.RAG_TEMPLATE, context, user_message), messages, append=True, ) else: return add_or_update_user_message( - rag_template( - request.app.state.config.RAG_TEMPLATE, context_string, user_message - ), + rag_template(request.app.state.config.RAG_TEMPLATE, context, user_message), messages, append=False, ) @@ -4495,26 +4491,31 @@ async def streaming_chat_response_handler(response, ctx): # Build context: file sources with content, # tool sources as citation markers only. - ctx = get_source_context(metadata.get("sources", [])) - ctx += get_source_context( + source_context = get_source_context( + metadata.get("sources", []) + ) + get_source_context( all_tool_call_sources, include_content=False ) - ctx = ctx.strip() - if ctx: - rag = rag_template( + source_context = source_context.strip() + if source_context: + rag_content = rag_template( request.app.state.config.RAG_TEMPLATE, - ctx, + source_context, user_message, ) if RAG_SYSTEM_CONTEXT: form_data["messages"] = ( add_or_update_system_message( - rag, form_data["messages"], append=True + rag_content, + form_data["messages"], + append=True, ) ) else: form_data["messages"] = add_or_update_user_message( - rag, form_data["messages"], append=False + rag_content, + form_data["messages"], + append=False, ) tool_call_sources.clear() From e24299e66d838126faad739474b2a49a714f7755 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 20:36:54 -0600 Subject: [PATCH 0827/1854] refac --- .github/workflows/deploy-to-hf-spaces.yml | 64 ----------------------- 1 file changed, 64 deletions(-) delete mode 100644 .github/workflows/deploy-to-hf-spaces.yml diff --git a/.github/workflows/deploy-to-hf-spaces.yml b/.github/workflows/deploy-to-hf-spaces.yml deleted file mode 100644 index cda9f1eb4b..0000000000 --- a/.github/workflows/deploy-to-hf-spaces.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: Deploy to HuggingFace Spaces - -on: - push: - branches: - - dev - - main - workflow_dispatch: - -jobs: - check-secret: - runs-on: ubuntu-latest - outputs: - token-set: ${{ steps.check-key.outputs.defined }} - steps: - - id: check-key - env: - HF_TOKEN: ${{ secrets.HF_TOKEN }} - if: "${{ env.HF_TOKEN != '' }}" - run: echo "defined=true" >> $GITHUB_OUTPUT - - deploy: - runs-on: ubuntu-latest - needs: [check-secret] - if: needs.check-secret.outputs.token-set == 'true' - env: - HF_TOKEN: ${{ secrets.HF_TOKEN }} - steps: - - name: Checkout repository - uses: actions/checkout@v5 - with: - lfs: true - - - name: Remove git history - run: rm -rf .git - - - name: Prepend YAML front matter to README.md - run: | - echo "---" > temp_readme.md - echo "title: Open WebUI" >> temp_readme.md - echo "emoji: 🐳" >> temp_readme.md - echo "colorFrom: purple" >> temp_readme.md - echo "colorTo: gray" >> temp_readme.md - echo "sdk: docker" >> temp_readme.md - echo "app_port: 8080" >> temp_readme.md - echo "---" >> temp_readme.md - cat README.md >> temp_readme.md - mv temp_readme.md README.md - - - name: Configure git - run: | - git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config --global user.name "github-actions[bot]" - - name: Set up Git and push to Space - run: | - git init --initial-branch=main - git lfs install - git lfs track "*.ttf" - git lfs track "*.jpg" - rm demo.png - rm banner.png - git add . - git commit -m "GitHub deploy: ${{ github.sha }}" - git push --force https://open-webui:${HF_TOKEN}@huggingface.co/spaces/open-webui/open-webui main From 2bff50f736afd2fe41d4f0efbea4a4a7bfab835d Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 20:42:21 -0600 Subject: [PATCH 0828/1854] refac --- backend/open_webui/utils/middleware.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 2afd5f87bf..1bc581233c 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -890,21 +890,24 @@ def handle_responses_streaming_event( return current_output, None -def get_source_context(sources: list, include_content: bool = True) -> str: +def get_source_context( + sources: list, source_id_map: dict = None, include_content: bool = True +) -> str: """ Build tag context string from citation sources. """ context_string = "" - citation_idx = {} + if source_id_map is None: + source_id_map = {} for source in sources: for doc, meta in zip(source.get("document", []), source.get("metadata", [])): src_id = meta.get("source") or source.get("source", {}).get("id") or "N/A" - if src_id not in citation_idx: - citation_idx[src_id] = len(citation_idx) + 1 + if src_id not in source_id_map: + source_id_map[src_id] = len(source_id_map) + 1 src_name = source.get("source", {}).get("name") body = doc if include_content else "" context_string += ( - f'{body}\n" ) @@ -929,7 +932,7 @@ def apply_source_context_to_messages( if not sources or not user_message: return messages - context = get_source_context(sources, include_content) + context = get_source_context(sources, include_content=include_content) context = context.strip() if not context: @@ -4491,10 +4494,13 @@ async def streaming_chat_response_handler(response, ctx): # Build context: file sources with content, # tool sources as citation markers only. + source_id_map = {} source_context = get_source_context( - metadata.get("sources", []) + metadata.get("sources", []), source_id_map ) + get_source_context( - all_tool_call_sources, include_content=False + all_tool_call_sources, + source_id_map, + include_content=False, ) source_context = source_context.strip() if source_context: From 710b5270a111cfbef8af27ac2b7231a6365af983 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 20:43:45 -0600 Subject: [PATCH 0829/1854] refac --- backend/open_webui/utils/middleware.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 1bc581233c..8bfed7d391 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -891,23 +891,25 @@ def handle_responses_streaming_event( def get_source_context( - sources: list, source_id_map: dict = None, include_content: bool = True + sources: list, source_ids: dict = None, include_content: bool = True ) -> str: """ Build tag context string from citation sources. """ context_string = "" - if source_id_map is None: - source_id_map = {} + if source_ids is None: + source_ids = {} for source in sources: for doc, meta in zip(source.get("document", []), source.get("metadata", [])): - src_id = meta.get("source") or source.get("source", {}).get("id") or "N/A" - if src_id not in source_id_map: - source_id_map[src_id] = len(source_id_map) + 1 + source_id = ( + meta.get("source") or source.get("source", {}).get("id") or "N/A" + ) + if source_id not in source_ids: + source_ids[source_id] = len(source_ids) + 1 src_name = source.get("source", {}).get("name") body = doc if include_content else "" context_string += ( - f'{body}\n" ) @@ -4494,12 +4496,12 @@ async def streaming_chat_response_handler(response, ctx): # Build context: file sources with content, # tool sources as citation markers only. - source_id_map = {} + source_ids = {} source_context = get_source_context( - metadata.get("sources", []), source_id_map + metadata.get("sources", []), source_ids ) + get_source_context( all_tool_call_sources, - source_id_map, + source_ids, include_content=False, ) source_context = source_context.strip() From 124ad948fe1d8120a21f449cf46c5fa2900a3a6f Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 7 Mar 2026 20:56:05 -0600 Subject: [PATCH 0830/1854] refac --- .github/workflows/build-release.yml | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 019fbb6bae..2ecb013e0b 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -27,28 +27,17 @@ jobs: echo "::set-output name=version::$VERSION" - name: Extract latest CHANGELOG entry - id: changelog run: | - CHANGELOG_CONTENT=$(awk 'BEGIN {print_section=0;} /^## \[/ {if (print_section == 0) {print_section=1;} else {exit;}} print_section {print;}' CHANGELOG.md) - CHANGELOG_ESCAPED=$(echo "$CHANGELOG_CONTENT" | sed ':a;N;$!ba;s/\n/%0A/g') - echo "Extracted latest release notes from CHANGELOG.md:" - echo -e "$CHANGELOG_CONTENT" - echo "::set-output name=content::$CHANGELOG_ESCAPED" + VERSION="${{ steps.get_version.outputs.version }}" + awk "/^## \[${VERSION}\]/{found=1; next} /^## \[/{if(found) exit} found{print}" CHANGELOG.md > /tmp/release-notes.md - name: Create GitHub release - uses: actions/github-script@v8 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const changelog = `${{ steps.changelog.outputs.content }}`; - const release = await github.rest.repos.createRelease({ - owner: context.repo.owner, - repo: context.repo.repo, - tag_name: `v${{ steps.get_version.outputs.version }}`, - name: `v${{ steps.get_version.outputs.version }}`, - body: changelog, - }) - console.log(`Created release ${release.data.html_url}`) + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release create "v${{ steps.get_version.outputs.version }}" \ + --title "v${{ steps.get_version.outputs.version }}" \ + --notes-file /tmp/release-notes.md - name: Upload package to GitHub release uses: actions/upload-artifact@v4 From 61bbb99d9e99c69177f1f0230f730fc512b5b293 Mon Sep 17 00:00:00 2001 From: "Ethan T." Date: Mon, 9 Mar 2026 05:36:53 +0800 Subject: [PATCH 0831/1854] fix: replace bare except with Exception in oauth.py (#22420) * fix: replace bare except with except Exception in main.py * fix: replace bare except with Exception in oauth.py In Python 3, bare 'except:' is discouraged as it catches all SystemExit and KeyboardInterrupt exceptions. Changed to 'except Exception:' to only catch actual exceptions. --- backend/open_webui/main.py | 4 ++-- backend/open_webui/utils/oauth.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index 4c27e811cb..202bd32c1d 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -1864,7 +1864,7 @@ async def chat_completion( "model": model_id, }, ) - except: + except Exception: pass ctx = build_chat_response_context( @@ -1911,7 +1911,7 @@ async def chat_completion( {"type": "chat:tasks:cancel"}, ) - except: + except Exception: pass finally: try: diff --git a/backend/open_webui/utils/oauth.py b/backend/open_webui/utils/oauth.py index 392ae74f96..249cc62d74 100644 --- a/backend/open_webui/utils/oauth.py +++ b/backend/open_webui/utils/oauth.py @@ -620,7 +620,7 @@ class OAuthClientManager: payload = json.loads(response_text) error = payload.get("error") error_description = payload.get("error_description", "") - except: + except Exception: pass else: error_description = response_text From f419830a524051ac46a0518ccd9eedee8394df99 Mon Sep 17 00:00:00 2001 From: joaoback <156559121+joaoback@users.noreply.github.com> Date: Sun, 8 Mar 2026 18:37:33 -0300 Subject: [PATCH 0832/1854] # i18n: (pt-BR) add translations for newly added UI items + consistency pass (#22391) New **pt-BR** translations for items introduced in the latest releases, plus a consistency/quality pass across existing strings (grammar, tone, capitalization, pluralization). Placeholders and hotkeys preserved. No logic changes. --- src/lib/i18n/locales/pt-BR/translation.json | 48 ++++++++++----------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/lib/i18n/locales/pt-BR/translation.json b/src/lib/i18n/locales/pt-BR/translation.json index 2d69ed5a3a..2333523217 100644 --- a/src/lib/i18n/locales/pt-BR/translation.json +++ b/src/lib/i18n/locales/pt-BR/translation.json @@ -19,11 +19,11 @@ "{{COUNT}} Rows": "{{COUNT}} Linhas", "{{COUNT}} Sources": "{{COUNT}} Origens", "{{COUNT}} words": "{{COUNT}} palavras", - "{{COUNT}}d_time_ago": "", - "{{COUNT}}h_time_ago": "", - "{{COUNT}}m_time_ago": "", - "{{COUNT}}w_time_ago": "", - "{{COUNT}}y_time_ago": "", + "{{COUNT}}d_time_ago": "{{COUNT}}d atrás", + "{{COUNT}}h_time_ago": "{{COUNT}}h atrás", + "{{COUNT}}m_time_ago": "{{COUNT}}m atrás", + "{{COUNT}}w_time_ago": "{{COUNT}}sem atrás", + "{{COUNT}}y_time_ago": "{{COUNT}}a atrás", "{{LOCALIZED_DATE}} at {{LOCALIZED_TIME}}": "{{LOCALIZED_DATE}} às {{LOCALIZED_TIME}}", "{{model}} download has been canceled": "O download do {{model}} foi cancelado", "{{modelName}} profile image": "Imagem de perfil de {{modelName}}", @@ -183,7 +183,7 @@ "Are you sure you want to delete this channel?": "Tem certeza de que deseja excluir este canal?", "Are you sure you want to delete this message?": "Tem certeza de que deseja excluir esta mensagem?", "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "Tem certeza de que deseja excluir esta versão? As versões filhas serão vinculadas novamente à versão pai.", - "Are you sure you want to delete this?": "", + "Are you sure you want to delete this?": "Tem certeza de que deseja excluir isto?", "Are you sure you want to unarchive all archived chats?": "Você tem certeza que deseja desarquivar todos os chats arquivados?", "Arena Models": "Arena de Modelos", "Artifacts": "Artefatos", @@ -283,7 +283,7 @@ "Character limit for autocomplete generation input": "Limite de caracteres para entrada de geração de preenchimento automático", "Chart new frontiers": "Trace novas fronteiras", "Chat": "Chat", - "Chat archived.": "", + "Chat archived.": "Chat arquivado.", "Chat Background Image": "Imagem de Fundo do Chat", "Chat Bubble UI": "Interface de Bolha de Chat", "Chat Completions": "Gerar Resposta", @@ -487,7 +487,7 @@ "Default User Role": "Padrão para novos usuários", "Defaults": "Padrões", "Delete": "Excluir", - "Delete {{name}}": "", + "Delete {{name}}": "Excluir {{name}}", "Delete a model": "Excluir um modelo", "Delete All": "Excluir tudo", "Delete All Chats": "Excluir Todos os Chats", @@ -580,7 +580,7 @@ "Downloading stats...": "Baixando estatísticas...", "Draw": "Empate", "Drop any files here to upload": "Solte qualquer arquivo aqui para fazer upload", - "Drop files here": "", + "Drop files here": "Solte os arquivos aqui", "Drop files here to upload": "Solte os arquivos aqui para fazer upload", "DuckDuckGo": "DuckDuckGo", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "por exemplo, '30s', '10m'. Unidades de tempo válidas são 's', 'm', 'h'.", @@ -826,7 +826,7 @@ "Fade Effect for Streaming Text": "Efeito de Fade para texto em streaming", "Failed to add file.": "Falha ao adicionar arquivo.", "Failed to add members": "Falha ao adicionar membros", - "Failed to archive chat.": "", + "Failed to archive chat.": "Falha ao arquivar o chat.", "Failed to attach file": "Falha ao anexar arquivo", "Failed to clear status": "Falha ao limpar o status", "Failed to connect to {{URL}} OpenAPI tool server": "Falha ao conectar ao servidor da ferramenta OpenAPI {{URL}}", @@ -841,11 +841,11 @@ "Failed to generate title": "Falha ao gerar título", "Failed to import models": "Falha ao importar modelos", "Failed to load chat preview": "Falha ao carregar a pré-visualização do chat", - "Failed to load DOCX file. Please try downloading it instead.": "", + "Failed to load DOCX file. Please try downloading it instead.": "Não foi possível carregar o arquivo DOCX. Tente baixá-lo em vez disso.", "Failed to load Excel/CSV file. Please try downloading it instead.": "Não foi possível carregar o arquivo Excel/CSV. Tente baixá-lo em vez disso.", "Failed to load file content.": "Falha ao carregar o conteúdo do arquivo.", "Failed to load Interface settings": "Falha ao carregar configurações da Interface", - "Failed to load PPTX file. Please try downloading it instead.": "", + "Failed to load PPTX file. Please try downloading it instead.": "Não foi possível carregar o arquivo PPTX. Tente baixá-lo em vez disso.", "Failed to move chat": "Falha ao mover o chat", "Failed to process URL: {{url}}": "Falha ao processar URL: {{url}}", "Failed to read clipboard contents": "Falha ao ler o conteúdo da área de transferência", @@ -900,7 +900,7 @@ "Focus Chat Input": "Foco na janela do Chat", "Folder": "Pasta", "Folder Background Image": "Imagem de fundo da pasta", - "Folder created successfully": "", + "Folder created successfully": "Pasta criada com sucesso", "Folder deleted successfully": "Pasta excluída com sucesso", "Folder Max File Count": "Contagem máxima de arquivos por pasta", "Folder name": "Nome da pasta", @@ -1265,7 +1265,7 @@ "More options": "Mais opções", "More Options": "Mais opções", "Move": "Mover", - "Moved {{name}}": "", + "Moved {{name}}": "{{name}} movido", "My Terminal": "Meu Terminal", "Name": "Nome", "Name and ID are required, please fill them out": "Nome e ID são obrigatórios, por favor preencha-os", @@ -1308,13 +1308,13 @@ "No file selected": "Nenhum arquivo selecionado", "No files found": "Nenhum arquivo encontrado", "No files in this knowledge base.": "Não existem arquivos nesta base de conhecimento.", - "No files yet. Upload files or run Python code to create them.": "", + "No files yet. Upload files or run Python code to create them.": "Nenhum arquivo ainda. Envie arquivos ou execute código Python para criá-los.", "No functions found": "Nenhuma função encontrada", "No groups found": "Nenhum grupo encontrado", "No history available": "Não há histórico disponível.", "No HTML, CSS, or JavaScript content found.": "Nenhum conteúdo HTML, CSS ou JavaScript encontrado.", "No inference engine with management support found": "Nenhum mecanismo de inferência com suporte de gerenciamento encontrado", - "No kernel": "", + "No kernel": "Sem kernel", "No knowledge bases found.": "Nenhuma base de conhecimento encontrada.", "No knowledge found": "Nenhum conhecimento encontrado", "No memories to clear": "Nenhuma memória para limpar", @@ -1330,7 +1330,7 @@ "No results": "Nenhum resultado encontrado", "No results found": "Nenhum resultado encontrado", "No search query generated": "Nenhuma consulta de pesquisa gerada", - "No servers detected": "", + "No servers detected": "Nenhum servidor detectado", "No skills found": "Nenhuma skill encontrada", "No source available": "Nenhuma fonte disponível", "No sources found": "Nenhuma fonte encontrada", @@ -1486,7 +1486,7 @@ "Please select at least one user for Direct Message channel.": "Por favor, selecione pelo menos um usuário para o canal de Mensagens Diretas.", "Please wait until all files are uploaded.": "Aguarde até que todos os arquivos sejam enviados.", "Port": "Porta", - "Ports": "", + "Ports": "Portas", "Positive attitude": "Atitude positiva", "Prefer not to say": "Prefiro não dizer", "Prefix ID": "Prefixo ID", @@ -1516,7 +1516,7 @@ "Pull \"{{searchValue}}\" from Ollama.com": "Obter \"{{searchValue}}\" de Ollama.com", "Pull a model from Ollama.com": "Obter um modelo de Ollama.com", "Pull Model": "Obter Modelo", - "Pyodide file browser": "", + "Pyodide file browser": "Navegador de arquivos Pyodide", "Query Generation Prompt": "Prompt de Geração de Consulta", "Querying": "Consultando", "Quick Actions": "Ações rápidas", @@ -1584,7 +1584,7 @@ "Response splitting": "Divisão da Resposta", "Response Watermark": "Marca d'água de resposta", "Responses": "Respostas", - "Restart": "", + "Restart": "Reiniciar", "Result": "Resultado", "RESULT": "Resultado", "Retrieval": "Recuperação", @@ -1598,7 +1598,7 @@ "Role": "Função", "RTL": "Direita para Esquerda", "Run": "Executar", - "Run All": "", + "Run All": "Executar Tudo", "Running": "Executando", "Running...": "Executando...", "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "Executa tarefas de incorporação simultaneamente para acelerar o processamento. Desative se os limites de taxa se tornarem um problema.", @@ -1789,7 +1789,7 @@ "Start a new conversation": "Iniciar uma nova conversa", "Start of the channel": "Início do canal", "Start Tag": "Tag inicial", - "Starting kernel...": "", + "Starting kernel...": "Iniciando kernel...", "Status": "Status", "Status cleared successfully": "Status liberado com sucesso", "Status updated successfully": "Status atualizado com sucesso", @@ -2134,8 +2134,8 @@ "You're now logged in.": "Você agora está logado.", "Your Account": "Sua conta", "Your account status is currently pending activation.": "O status da sua conta está atualmente aguardando ativação.", - "Your browser does not support the audio tag.": "", - "Your browser does not support the video tag.": "", + "Your browser does not support the audio tag.": "Seu navegador não suporta a tag de áudio.", + "Your browser does not support the video tag.": "Seu navegador não suporta a tag de vídeo.", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Toda a sua contribuição irá diretamente para o desenvolvedor do plugin; o Open WebUI não retém nenhuma porcentagem. No entanto, a plataforma de financiamento escolhida pode ter suas próprias taxas.", "Your message text or inputs": "Seu texto de mensagem ou entradas", "Your usage stats have been successfully synced.": "Suas estatísticas de uso foram sincronizadas com sucesso.", From e1d04be89782ac6c9183499c484b730c850adaed Mon Sep 17 00:00:00 2001 From: joaoback <156559121+joaoback@users.noreply.github.com> Date: Sun, 8 Mar 2026 18:38:24 -0300 Subject: [PATCH 0833/1854] i18n: (pt-BR) add translations for newly added UI items + consistency pass (#22452) New **pt-BR** translations for items introduced in the latest releases, plus a consistency/quality pass across existing strings (grammar, tone, capitalization, pluralization). Placeholders and hotkeys preserved. No logic changes. From abe865f4f38f9c6daf8e2bd44780a7494aa84fe5 Mon Sep 17 00:00:00 2001 From: amirsubhi Date: Mon, 9 Mar 2026 05:38:35 +0800 Subject: [PATCH 0834/1854] i18n : Updated ms-MY Malay (Bahasa Malaysia) Language (#22450) Update ms-MY Malay (Bahasa Malaysia) Language --- src/lib/i18n/locales/ms-MY/translation.json | 3198 +++++++++---------- 1 file changed, 1599 insertions(+), 1599 deletions(-) diff --git a/src/lib/i18n/locales/ms-MY/translation.json b/src/lib/i18n/locales/ms-MY/translation.json index 4f05a58d67..91340356df 100644 --- a/src/lib/i18n/locales/ms-MY/translation.json +++ b/src/lib/i18n/locales/ms-MY/translation.json @@ -1,570 +1,570 @@ { - "-1 for no limit, or a positive integer for a specific limit": "", + "-1 for no limit, or a positive integer for a specific limit": "-1 untuk tanpa had, atau integer positif untuk had tertentu", "'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "'s', 'm', 'h', 'd', 'w' or '-1' untuk tiada tempoh luput.", "(e.g. `sh webui.sh --api --api-auth username_password`)": "(contoh `sh webui.sh --api --api-auth username_password`)", "(e.g. `sh webui.sh --api`)": "(contoh `sh webui.sh --api`)", "(latest)": "(terkini)", - "(leave blank for to use commercial endpoint)": "", - "[Last] dddd [at] h:mm A": "", - "[Today at] h:mm A": "", - "[Yesterday at] h:mm A": "", + "(leave blank for to use commercial endpoint)": "(biarkan kosong untuk menggunakan titik akhir komersial)", + "[Last] dddd [at] h:mm A": "[Terakhir] dddd [pada] h:mm A", + "[Today at] h:mm A": "[Hari ini pada] h:mm A", + "[Yesterday at] h:mm A": "[Semalam pada] h:mm A", "{{ models }}": "{{ models }}", - "{{COUNT}} Available Tools": "", - "{{COUNT}} characters": "", - "{{COUNT}} extracted lines": "", - "{{COUNT}} files": "", - "{{COUNT}} hidden lines": "", - "{{COUNT}} members": "", - "{{COUNT}} Replies": "", - "{{COUNT}} Rows": "", - "{{COUNT}} Sources": "", - "{{COUNT}} words": "", - "{{COUNT}}d_time_ago": "", - "{{COUNT}}h_time_ago": "", - "{{COUNT}}m_time_ago": "", - "{{COUNT}}w_time_ago": "", - "{{COUNT}}y_time_ago": "", - "{{LOCALIZED_DATE}} at {{LOCALIZED_TIME}}": "", - "{{model}} download has been canceled": "", - "{{modelName}} profile image": "", - "{{NAMES}} reacted with {{REACTION}}": "", + "{{COUNT}} Available Tools": "{{COUNT}} Alat Tersedia", + "{{COUNT}} characters": "{{COUNT}} aksara", + "{{COUNT}} extracted lines": "{{COUNT}} baris yang diekstrak", + "{{COUNT}} files": "{{COUNT}} fail", + "{{COUNT}} hidden lines": "{{COUNT}} baris tersembunyi", + "{{COUNT}} members": "{{COUNT}} ahli", + "{{COUNT}} Replies": "{{COUNT}} Balasan", + "{{COUNT}} Rows": "{{COUNT}} Baris", + "{{COUNT}} Sources": "{{COUNT}} Sumber", + "{{COUNT}} words": "{{COUNT}} perkataan", + "{{COUNT}}d_time_ago": "{{COUNT}}h yang lalu", + "{{COUNT}}h_time_ago": "{{COUNT}}j yang lalu", + "{{COUNT}}m_time_ago": "{{COUNT}}m yang lalu", + "{{COUNT}}w_time_ago": "{{COUNT}}m yang lalu", + "{{COUNT}}y_time_ago": "{{COUNT}}t yang lalu", + "{{LOCALIZED_DATE}} at {{LOCALIZED_TIME}}": "{{LOCALIZED_DATE}} pada {{LOCALIZED_TIME}}", + "{{model}} download has been canceled": "Muat turun {{model}} telah dibatalkan", + "{{modelName}} profile image": "Imej profil {{modelName}}", + "{{NAMES}} reacted with {{REACTION}}": "{{NAMES}} bertindak balas dengan {{REACTION}}", "{{user}}'s Chats": "Perbualan {{user}}", "{{webUIName}} Backend Required": "{{webUIName}} Backend diperlukan", - "*Prompt node ID(s) are required for image generation": "", - "1 Source": "", - "1m_time_ago": "", - "A collaboration channel where people join as members": "", - "A discussion channel where access is controlled by groups and permissions": "", - "A new version (v{{LATEST_VERSION}}) is now available.": "", - "A private conversation between you and selected users": "", + "*Prompt node ID(s) are required for image generation": "*ID nod Prompt diperlukan untuk penjanaan imej", + "1 Source": "1 Sumber", + "1m_time_ago": "1m_masa_lalu", + "A collaboration channel where people join as members": "Saluran kolaborasi di mana orang ramai menyertai sebagai ahli", + "A discussion channel where access is controlled by groups and permissions": "Saluran perbincangan di mana akses dikawal oleh kumpulan dan kebenaran", + "A new version (v{{LATEST_VERSION}}) is now available.": "Versi baru (v{{LATEST_VERSION}}) kini tersedia.", + "A private conversation between you and selected users": "Perbualan peribadi antara anda dan pengguna terpilih", "A task model is used when performing tasks such as generating titles for chats and web search queries": "Model tugas digunakan semasa melaksanakan tugas seperti menjana tajuk untuk perbualan dan pertanyaan carian web.", "a user": "seorang pengguna", "About": "Mengenai", - "Accept Autocomplete Generation\nJump to Prompt Variable": "", - "Access": "", - "Access Control": "", - "Access Grants": "", - "Access List": "", - "Accessible to all users": "", + "Accept Autocomplete Generation\nJump to Prompt Variable": "Terima Penjanaan Autolengkap", + "Access": "Akses", + "Access Control": "Kawalan Akses", + "Access Grants": "Pemberian Akses", + "Access List": "Senarai Akses", + "Accessible to all users": "Boleh diakses oleh semua pengguna", "Account": "Akaun", "Account Activation Pending": "Pengaktifan Akaun belum selesai", "Accurate information": "Informasi tepat", - "Action": "", - "Action not found": "", + "Action": "Tindakan", + "Action not found": "Tindakan tidak ditemui", "Action Required for Chat Log Storage": "Tindakan diperlukan untuk menyimpan log sembang", "Actions": "Tindakan", - "Activate": "", - "Activate this command by typing \"/{{COMMAND}}\" to chat input.": "", + "Activate": "Aktifkan", + "Activate this command by typing \"/{{COMMAND}}\" to chat input.": "Aktifkan perintah ini dengan menaip \"/{{COMMAND}}\" ke input sembang.", "Active": "Aktif", "Active Users": "Pengguna Aktif", - "Activity": "", + "Activity": "Aktiviti", "Add": "Tambah", - "Add a model ID": "", + "Add a model ID": "Tambah ID model", "Add a short description about what this model does": "Tambah penerangan ringkas tentang apa yang model ini boleh lakukan", "Add a tag": "Tambah tag", - "Add a tag...": "", - "Add Access": "", - "Add Arena Model": "", - "Add Connection": "", - "Add Content": "", - "Add content here": "", - "Add Custom Parameter": "", - "Add Custom Prompt": "", - "Add Details": "", + "Add a tag...": "Tambah tag...", + "Add Access": "Tambah Akses", + "Add Arena Model": "Tambah Model Arena", + "Add Connection": "Tambah Sambungan", + "Add Content": "Tambah Kandungan", + "Add content here": "Tambah kandungan di sini", + "Add Custom Parameter": "Tambah Parameter Tersuai", + "Add Custom Prompt": "Tambah Prompt Tersuai", + "Add Details": "Tambah Butiran", "Add Files": "Tambah Fail", - "Add Image": "", - "Add Member": "", - "Add Members": "", + "Add Image": "Tambah Imej", + "Add Member": "Tambah Ahli", + "Add Members": "Tambah Ahli", "Add Memory": "Tambah Memori", "Add Model": "Tambah Model", - "Add Reaction": "", - "Add tag": "", + "Add Reaction": "Tambah Reaksi", + "Add tag": "Tambah tag", "Add Tag": "Tambah Tag", - "Add Terminal": "", - "Add Terminal Connection": "", - "Add text content": "", - "Add to favorites": "", + "Add Terminal": "Tambah Terminal", + "Add Terminal Connection": "Tambah Sambungan Terminal", + "Add text content": "Tambah kandungan teks", + "Add to favorites": "Tambah ke kegemaran", "Add User": "Tambah Pengguna", - "Add User Group": "", - "Add webpage": "", - "Add your Open Terminal URL and API key in Settings → Integrations.": "", - "Additional Config": "", - "Additional configuration options for marker. This should be a JSON string with key-value pairs. For example, '{\"key\": \"value\"}'. Supported keys include: disable_links, keep_pageheader_in_output, keep_pagefooter_in_output, filter_blank_pages, drop_repeated_text, layout_coverage_threshold, merge_threshold, height_tolerance, gap_threshold, image_threshold, min_line_length, level_count, default_level": "", - "Additional feedback comments": "", - "Additional Parameters": "", - "Adds filenames, titles, sections, and snippets into the BM25 text to improve lexical recall.": "", + "Add User Group": "Tambah Kumpulan Pengguna", + "Add webpage": "Tambah halaman web", + "Add your Open Terminal URL and API key in Settings → Integrations.": "Tambah URL Open Terminal dan kunci API anda dalam Tetapan → Integrasi.", + "Additional Config": "Konfigurasi Tambahan", + "Additional configuration options for marker. This should be a JSON string with key-value pairs. For example, '{\"key\": \"value\"}'. Supported keys include: disable_links, keep_pageheader_in_output, keep_pagefooter_in_output, filter_blank_pages, drop_repeated_text, layout_coverage_threshold, merge_threshold, height_tolerance, gap_threshold, image_threshold, min_line_length, level_count, default_level": "Pilihan konfigurasi tambahan untuk penanda. Ini mestilah rentetan JSON dengan pasangan kunci-nilai. Contohnya, '{\"key\": \"value\"}'. Kunci yang disokong termasuk: disable_links, keep_pageheader_in_output, keep_pagefooter_in_output, filter_blank_pages, drop_repeated_text, layout_coverage_threshold, merge_threshold, height_tolerance, gap_threshold, image_threshold, min_line_length, level_count, default_level", + "Additional feedback comments": "Ulasan maklum balas tambahan", + "Additional Parameters": "Parameter Tambahan", + "Adds filenames, titles, sections, and snippets into the BM25 text to improve lexical recall.": "Menambah nama fail, tajuk, bahagian, dan petikan ke dalam teks BM25 untuk meningkatkan penarikan kembali leksikal.", "Adjusting these settings will apply changes universally to all users.": "Melaraskan tetapan ini akan menggunakan perubahan secara universal kepada semua pengguna.", "admin": "pentadbir", "Admin": "Pentadbir", - "Admin Contact Email": "", + "Admin Contact Email": "E-mel Pentadbir", "Admin Panel": "Panel Pentadbir", "Admin Settings": "Tetapan Pentadbir", "Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "Pentadbir mempunyai akses kepada semua alat pada setiap masa; pengguna memerlukan alat yang ditetapkan mengikut model dalam ruang kerja.", - "Advanced": "", + "Advanced": "Lanjutan", "Advanced Parameters": "Parameter Lanjutan", - "Advanced parameters for MinerU parsing (enable_ocr, enable_formula, enable_table, language, model_version, page_ranges)": "", + "Advanced parameters for MinerU parsing (enable_ocr, enable_formula, enable_table, language, model_version, page_ranges)": "Parameter lanjutan untuk penghuraian MinerU (enable_ocr, enable_formula, enable_table, language, model_version, page_ranges)", "Advanced Params": "Parameter Lanjutan", - "After updating or changing the embedding model, you must reindex the knowledge base for the changes to take effect. You can do this using the \"Reindex\" button below.": "", - "AI": "", - "All": "", - "All chats have been unarchived.": "", - "All models are now hidden": "", - "All models are now visible": "", - "All models deleted successfully": "", - "All time": "", - "All Users": "", - "Allow Call": "", - "Allow Chat Controls": "", - "Allow Chat Delete": "", - "Allow Chat Edit": "", - "Allow Chat Export": "", - "Allow Chat Params": "", - "Allow Chat Share": "", - "Allow Chat System Prompt": "", - "Allow Chat Valves": "", - "Allow Continue Response": "", - "Allow Delete Messages": "", - "Allow File Upload": "", - "Allow Multiple Models in Chat": "", + "After updating or changing the embedding model, you must reindex the knowledge base for the changes to take effect. You can do this using the \"Reindex\" button below.": "Selepas mengemas kini atau mengubah model embedding, anda mesti mengindeks semula pangkalan pengetahuan untuk perubahan berkuat kuasa. Anda boleh melakukan ini menggunakan butang \"Indeks Semula\" di bawah.", + "AI": "AI", + "All": "Semua", + "All chats have been unarchived.": "Semua sembang telah nyaharkib.", + "All models are now hidden": "Semua model kini tersembunyi", + "All models are now visible": "Semua model kini kelihatan", + "All models deleted successfully": "Semua model telah dipadamkan dengan berjaya", + "All time": "Sepanjang masa", + "All Users": "Semua Pengguna", + "Allow Call": "Benarkan Panggilan", + "Allow Chat Controls": "Benarkan Kawalan Sembang", + "Allow Chat Delete": "Benarkan Padam Sembang", + "Allow Chat Edit": "Benarkan Sunting Sembang", + "Allow Chat Export": "Benarkan Eksport Sembang", + "Allow Chat Params": "Benarkan Parameter Sembang", + "Allow Chat Share": "Benarkan Kongsi Sembang", + "Allow Chat System Prompt": "Benarkan arahan Sistem Sembang", + "Allow Chat Valves": "Benarkan Injap Sembang", + "Allow Continue Response": "Benarkan Sambungan Respons", + "Allow Delete Messages": "Benarkan Padam Mesej", + "Allow File Upload": "Benarkan Muat Naik Fail", + "Allow Multiple Models in Chat": "Benarkan Berbilang Model dalam Sembang", "Allow non-local voices": "Benarkan suara bukan tempatan ", - "Allow Rate Response": "", - "Allow Regenerate Response": "", - "Allow Sharing With Users": "", - "Allow Speech to Text": "", - "Allow Temporary Chat": "", - "Allow Text to Speech": "", + "Allow Rate Response": "Benarkan Penilaian Respons", + "Allow Regenerate Response": "Benarkan Jana Semula Respons", + "Allow Sharing With Users": "Benarkan Perkongsian dengan Pengguna", + "Allow Speech to Text": "Benarkan Pertuturan ke Teks", + "Allow Temporary Chat": "Benarkan Sembang Sementara", + "Allow Text to Speech": "Benarkan Teks ke Pertuturan", "Allow User Location": "Benarkan Lokasi Pengguna", "Allow Voice Interruption in Call": "Benarkan gangguan suara dalam panggilan", - "Allow Web Upload": "", - "Allowed Endpoints": "", - "Allowed File Extensions": "", - "Allowed file extensions for upload. Separate multiple extensions with commas. Leave empty for all file types.": "", - "Already have an account?": "Telah mempunyai akaun?", - "Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out.": "", - "Always": "", - "Always Collapse Code Blocks": "", - "Always Expand Details": "", - "Always Play Notification Sound": "", - "Amazing": "", + "Allow Web Upload": "Benarkan Muat Naik Web", + "Allowed Endpoints": "Titik Akhir yang Dibenarkan", + "Allowed File Extensions": "Sambungan Fail yang Dibenarkan", + "Allowed file extensions for upload. Separate multiple extensions with commas. Leave empty for all file types.": "Sambungan fail yang dibenarkan untuk muat naik. Pisahkan bilangan-bilangan sambungan dengan koma. Biarkan kosong untuk semua jenis fail.", + "Already have an account?": "Telah mempunyai aka?", + "Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out.": "Alternatif kepada top_p, dan bertujuan untuk memastikan keseimbangan antara kualiti dan kepelbagaian. Parameter p mewakili kebarangkalian minimum untuk token dipertimbangkan, relatif kepada kebarangkalian token yang paling berkemungkinan. Sebagai contoh, dengan p=0.05 dan token yang paling berkemungkinan mempunyai kebarangkalian 0.9, logit dengan nilai kurang daripada 0.045 ditapis keluar.", + "Always": "Sentiasa", + "Always Collapse Code Blocks": "Sentiasa Lipat Blok Kod", + "Always Expand Details": "Sentiasa Kembangkan Butiran", + "Always Play Notification Sound": "Sentiasa Mainkan Bunyi Pemberitahuan", + "Amazing": "Hebat", "an assistant": "seorang pembantu", - "An error occurred while fetching the explanation": "", - "Analytics": "", - "Analyzed": "", - "Analyzing...": "", - "and {{COUNT}} more": "", - "and create a new shared link.": "dan cipta pautan kongsi baharu", - "Android": "", - "Anyone": "", + "An error occurred while fetching the explanation": "Ralat berlaku semasa mengambil penjelasan", + "Analytics": "Analitik", + "Analyzed": "Sudah dianalisis", + "Analyzing...": "Menganalisis...", + "and {{COUNT}} more": "dan {{COUNT}} lagi", + "and create a new shared link.": "dan cipta patina kongsi baharu", + "Android": "Android", + "Anyone": "Sesiapa", "API Base URL": "URL Asas API", - "API Base URL for Datalab Marker service. Defaults to: https://www.datalab.to/api/v1/marker": "", + "API Base URL for Datalab Marker service. Defaults to: https://www.datalab.to/api/v1/marker": "URL Asas API untuk perkhidmatan Datalab Marker. Lalai kepada: https://www.datalab.to/api/v1/marker", "API Key": "Kunci API", "API Key created.": "Kunci API dicipta", - "API Key Endpoint Restrictions": "", + "API Key Endpoint Restrictions": "Sekatan Titik Akhir Kunci API", "API keys": "Kekunci API", - "API Keys": "", - "API Mode": "", - "API Timeout": "", - "API Type": "", - "API Version": "", - "API Version is required": "", - "Application DN": "", - "Application DN Password": "", - "applies to all users with the \"user\" role": "", + "API Keys": "Kunci API", + "API Mode": "Mod API", + "API Timeout": "Masa Tamat API", + "API Type": "Jenis API", + "API Version": "Versi API", + "API Version is required": "Versi API diperlukan", + "Application DN": "Aplikasi DN", + "Application DN Password": "Kata Laluan Aplikasi DN", + "applies to all users with the \"user\" role": "trepan kepada semua pengguna dengan peranan \"user\"", "April": "April", "Archive": "Arkib", - "Archive All": "", + "Archive All": "Arkibkan Semua", "Archive All Chats": "Arkibkan Semua Perbualan", "Archived Chats": "Perbualan yang diarkibkan", - "archived-chat-export": "", - "Are you sure you want to archive all chats? This action cannot be undone.": "", - "Are you sure you want to clear all memories? This action cannot be undone.": "", - "Are you sure you want to delete \"{{NAME}}\"?": "", - "Are you sure you want to delete all chats? This action cannot be undone.": "", - "Are you sure you want to delete this channel?": "", - "Are you sure you want to delete this message?": "", - "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "", - "Are you sure you want to delete this?": "", - "Are you sure you want to unarchive all archived chats?": "", - "Arena Models": "", - "Artifacts": "", - "Asc": "", - "Ask": "", - "Ask a question": "", - "Assistant": "", - "Async Embedding Processing": "", - "Attach File From Knowledge": "", - "Attach Knowledge": "", - "Attach Notes": "", - "Attach Webpage": "", + "archived-chat-export": "archived-chat-export", + "Are you sure you want to archive all chats? This action cannot be undone.": "Adakah anda pasti ingin mengarkibkan semua obrolan? Tindakan ini tidak boleh dibatalkan.", + "Are you sure you want to clear all memories? This action cannot be undone.": "Adakah anda pasti ingin menghapus semua ingatan? Tindakan ini tidak boleh dibatalkan.", + "Are you sure you want to delete \"{{NAME}}\"?": "Adakah anda pasti ingin menghapus \"{{NAME}}\"?", + "Are you sure you want to delete all chats? This action cannot be undone.": "Adakah anda pasti ingin menghapus semua obrolan? Tindakan ini tidak boleh dibatalkan.", + "Are you sure you want to delete this channel?": "Adakah anda pasti ingin menghapus saluran ini?", + "Are you sure you want to delete this message?": "Adakah anda pasti ingin menghapus mesej ini?", + "Are you sure you want to delete this version? Child versions will be relinked to this version's parent.": "Adakah anda pasti ingin menghapus versi ini? Versi anak akan dipautkan semula ke induk versi ini.", + "Are you sure you want to delete this?": "Adakah anda pasti ingin menghapus ini?", + "Are you sure you want to unarchive all archived chats?": "Adakah anda pasti ingin membuka arkib semua obrolan yang diarkibkan?", + "Arena Models": "Model Arena", + "Artifacts": "Artifak", + "Asc": "Naik", + "Ask": "Tanya", + "Ask a question": "Tanya soalan", + "Assistant": "Pembantu", + "Async Embedding Processing": "Pemprosesan Embedding Tak Segerak", + "Attach File From Knowledge": "Lampirkan Fail Daripada Pengetahuan", + "Attach Knowledge": "Lampirkan Pengetahuan", + "Attach Notes": "Lampirkan Nota", + "Attach Webpage": "Lampirkan Halaman Web", "Attention to detail": "Perincian", - "Attribute for Mail": "", - "Attribute for Username": "", + "Attribute for Mail": "Atribut untuk E-mel", + "Attribute for Username": "Atribut untuk Nama Pengguna", "Audio": "Audio", "August": "Ogos", - "Auth": "", - "Authenticate": "", - "Authentication": "", - "Auto": "", - "Auto (Random)": "", + "Auth": "Pengesahan", + "Authenticate": "Sahkan", + "Authentication": "Pengesahan", + "Auto": "Automatik", + "Auto (Random)": "Automatik (Rawak)", "Auto-Copy Response to Clipboard": "Salin Response secara Automatik ke Papan Klip", "Auto-playback response": "Main semula respons secara automatik", - "Autocomplete Generation": "", - "Autocomplete Generation Input Max Length": "", - "Automatic1111": "", + "Autocomplete Generation": "Penjanaan Autolengkap", + "Autocomplete Generation Input Max Length": "Panjang Maksimum Input Penjanaan Autolengkap", + "Automatic1111": "Automatic1111", "AUTOMATIC1111 Api Auth String": "AUTOMATIC1111 Api Auth String", "AUTOMATIC1111 Base URL": "URL Asas AUTOMATIC1111", "AUTOMATIC1111 Base URL is required.": "URL Asas AUTOMATIC1111 diperlukan.", - "Automatically inject system tools in native function calling mode (e.g., timestamps, memory, chat history, notes, etc.)": "", - "Available list": "", - "Available models": "", - "Available Tools": "", + "Automatically inject system tools in native function calling mode (e.g., timestamps, memory, chat history, notes, etc.)": "Secara automatik suntikkan alat sistem dalam mod panggilan fungsi asli (cth., setem masa, memori, sejarah sembang, nota, dll)", + "Available list": "Senarai tersedia", + "Available models": "Model tersedia", + "Available Tools": "Alat Tersedia", "available users": "pengguna tersedia", "available!": "tersedia!", "Away": "Tiada di tempat", - "Awful": "", - "Azure AI Speech": "", + "Awful": "Teruk", + "Azure AI Speech": "Azure AI Speech", "Azure OpenAI": "Azure OpenAI", - "Azure Region": "", + "Azure Region": "Kawasan Azure", "Back": "Kembali", "Bad Response": "Maklumbalas Salah", "Banners": "Sepanduk", "Base Model (From)": "Model Asas (Dari)", - "Base Model List Cache speeds up access by fetching base models only at startup or on settings save—faster, but may not show recent base model changes.": "", - "Bearer": "", + "Base Model List Cache speeds up access by fetching base models only at startup or on settings save—faster, but may not show recent base model changes.": "Cache Sonar Model Asas mempercepatkan akses dengan mengambil model asas hanya pada permulaan atau penyimpanan tetapan—lebih pantas, tetapi mungkin tidak menunjukkan perubahan model asas terbaru.", + "Bearer": "Bearer", "before": "sebelum,", "Being lazy": "Menjadi Malas", - "Beta": "", - "Bing": "", - "Bing Search V7 Endpoint": "", - "Bing Search V7 Subscription Key": "", - "Bio": "", - "Birth Date": "", - "BM25 Weight": "", - "Bocha Search API Key": "", - "Bold": "", - "Boosting or penalizing specific tokens for constrained responses. Bias values will be clamped between -100 and 100 (inclusive). (Default: none)": "", - "Brave": "", + "Beta": "Beta", + "Bing": "Bing", + "Bing Search V7 Endpoint": "Titik Akhir Bing Search V7", + "Bing Search V7 Subscription Key": "Kunci Langganan Bing Search V7", + "Bio": "Biografi", + "Birth Date": "Tarikh Lahir", + "BM25 Weight": "Berat BM25", + "Bocha Search API Key": "Kunci API Mocha Search", + "Bold": "Tebal", + "Boosting or penalizing specific tokens for constrained responses. Bias values will be clamped between -100 and 100 (inclusive). (Default: none)": "Meningkatkan atau mengurangkan token tertentu untuk respons terbatas. Nilai bias akan dihadkan antara -100 dan 100 (termasuk). (Lalai: tiada)", + "Brave": "Brave", "Brave Search API Key": "Kunci API Carian Brave", - "Browse and query knowledge bases": "", - "Builtin Tools": "", - "Bullet List": "", - "Button ID": "", - "Button Label": "", - "Button Prompt": "", - "by {{name}}": "", - "By {{name}}": "", - "Bypass Embedding and Retrieval": "", - "Bypass Web Loader": "", - "Cache Base Model List": "", - "Calendar": "", + "Browse and query knowledge bases": "Semak imbas dan pertanyaan pangkalan pengetahuan", + "Builtin Tools": "Alat Terbina", + "Bullet List": "Senarai Tanda Pleura", + "Button ID": "ID Butang", + "Button Label": "Label Butang", + "Button Prompt": "Prompt Butang", + "by {{name}}": "oleh {{name}}", + "By {{name}}": "Oleh {{name}}", + "Bypass Embedding and Retrieval": "Langkau Pembenaman dan Pencarian Semula", + "Bypass Web Loader": "Langkau Pemuat Web", + "Cache Base Model List": "Senarai Model Asas Cache", + "Calendar": "Kalendar", "Call": "Hubungi", "Call feature is not supported when using Web STT engine": "Ciri panggilan tidak disokong apabila menggunakan enjin Web STT", "Camera": "Kamera", "Cancel": "Batal", - "Cancel download of {{model}}": "", - "Cannot create an empty note.": "", - "Cannot delete the production version": "", + "Cancel download of {{model}}": "Batal muat turun {{model}}", + "Cannot create an empty note.": "Tidak dapat membuat nota kosong.", + "Cannot delete the production version": "Tidak dapat menghapus versi pengeluaran", "Capabilities": "Keupayaan", - "Capture": "", - "Capture Audio": "", - "Certificate Path": "", - "Change folder icon": "", + "Capture": "Tangkap", + "Capture Audio": "Tangkap Audio", + "Certificate Path": "Laluan Sijil", + "Change folder icon": "Tukar ikon folder", "Change Password": "Tukar Kata Laluan", - "Change User Role": "", - "Channel": "", - "Channel deleted successfully": "", - "Channel Name": "", - "Channel name cannot be empty.": "", - "Channel name must be less than 128 characters": "", - "Channel Type": "", - "Channel updated successfully": "", - "Channels": "", - "Character": "", - "Character limit for autocomplete generation input": "", - "Chart new frontiers": "", + "Change User Role": "Tukar Peranan Pengguna", + "Channel": "Saluran", + "Channel deleted successfully": "Saluran berjaya dipadam", + "Channel Name": "Nama Saluran", + "Channel name cannot be empty.": "Nama saluran tidak boleh kosong.", + "Channel name must be less than 128 characters": "Nama saluran mesti kurang daripada 128 aksara", + "Channel Type": "Jenis Saluran", + "Channel updated successfully": "Saluran berjaya dikemas kini", + "Channels": "Saluran-saluran", + "Character": "Aksara", + "Character limit for autocomplete generation input": "Had aksara untuk input penjanaan autolengkap", + "Chart new frontiers": "Jelajahi sempadan baru", "Chat": "Perbualan", - "Chat archived.": "", + "Chat archived.": "Sembang telah diarkibkan.", "Chat Background Image": "Imej Latar Belakang Perbualan", "Chat Bubble UI": "Antaramuka Buih Perbualan", - "Chat Completions": "", - "Chat Conversation": "", + "Chat Completions": "Pelengkapan Sembang", + "Chat Conversation": "Perbualan Sembang", "Chat direction": "Arah Perbualan", - "Chat exported successfully": "", - "Chat History": "", - "Chat ID": "", - "Chat moved successfully": "", - "Chat Permissions": "", - "Chat Tags Auto-Generation": "", - "Chat unshared successfully.": "", - "chats": "", + "Chat exported successfully": "Sembang telah dieksport dengan berjaya", + "Chat History": "Sejarah Sembang", + "Chat ID": "ID Sembang", + "Chat moved successfully": "Sembang telah dipindahkan dengan berjaya", + "Chat Permissions": "Kebenaran Untuk Sembang", + "Chat Tags Auto-Generation": "Penjanaan Auto Tag Sembang", + "Chat unshared successfully.": "Obrolan tidak dikongsi dengan berjaya.", + "chats": "obrolan", "Chats": "Perbualan", "Check Again": "Semak Kembali", "Check for updates": "Semak kemas kini", "Checking for updates...": "Kemas kini sedang disemak", "Choose a model before saving...": "Pilih model sebelum menyimpan", - "Chunk Min Size Target": "", + "Chunk Min Size Target": "Sasaran Saiz Minimum Chunk", "Chunk Overlap": "Tindihan 'Çhunk'", "Chunk Size": "Saiz 'Chunk'", - "Chunks smaller than this threshold will be merged with neighboring chunks when possible. Set to 0 to disable merging.": "", - "Ciphers": "", + "Chunks smaller than this threshold will be merged with neighboring chunks when possible. Set to 0 to disable merging.": "Chunk yang lebih kecil daripada ambang ini akan digabungkan dengan chunk yang berdampingan apabila mungkin. Tetapkan kepada 0 untuk melumpuhkan penggabungan.", + "Ciphers": "Cipher", "Citation": "Petikan", - "Citations": "", + "Citations": "Petikan", "Clear memory": "Kosongkan memori", - "Clear Memory": "", - "Clear search": "", - "Clear status": "", - "click here": "", - "Click here for filter guides.": "", + "Clear Memory": "Padam Memori", + "Clear search": "Padam carian", + "Clear status": "Padam status", + "click here": "klik di sini", + "Click here for filter guides.": "Klik di sini untuk panduan penapis.", "Click here for help.": "Klik disini untuk mendapatkan bantuan", "Click here to": "Klik disini untuk", "Click here to download user import template file.": "Klik disini untuk memuat turun fail templat import pengguna", - "Click here to learn more about faster-whisper and see the available models.": "", - "Click here to see available models.": "", + "Click here to learn more about faster-whisper and see the available models.": "Klik di sini untuk mengetahui lebih lanjut tentang faster-whisper dan lihat model yang tersedia.", + "Click here to see available models.": "Klik di sini untuk melihat model yang tersedia.", "Click here to select": "Klik disini untuk memilih", "Click here to select a csv file.": "Klik disini untuk memilih fail csv", "Click here to select a py file.": "Klik disini untuk memilih fail py", - "Click here to upload a workflow.json file.": "", + "Click here to upload a workflow.json file.": "Klik di sini untuk memuat naik fail workflow.json.", "click here.": "klik disini.", "Click on the user role button to change a user's role.": "Klik pada butang peranan pengguna untuk menukar peranan pengguna", - "Click to copy ID": "", + "Click to copy ID": "Klik untuk menyalin ID", "Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Kebenaran untuk menulis di papan klip ditolak. Sila semak tetapan pelayan web anda untuk memberikan akses yang diperlukan", "Clone": "Klon", - "Clone Chat": "", - "Clone of {{TITLE}}": "", + "Clone Chat": "Klon Sembang", + "Clone of {{TITLE}}": "Klon {{TITLE}}", "Close": "Tutup", - "Close Banner": "", - "Close chat controls": "", - "Close citation modal": "", - "Close Configure Connection Modal": "", - "Close feedback": "", - "Close modal": "", - "Close Modal": "", - "Close settings modal": "", - "Close Sidebar": "", - "cloud": "", - "CMU ARCTIC speaker embedding name": "", - "Code Block": "", - "Code Editor": "", - "Code execution": "", - "Code Execution": "", - "Code Execution Engine": "", - "Code Execution Timeout": "", + "Close Banner": "Tutup Sepanduk", + "Close chat controls": "Tutup kawalan sembang", + "Close citation modal": "Tutup modal petikan", + "Close Configure Connection Modal": "Tutup Konfigurasi Sambungan Modal", + "Close feedback": "Tutup maklum balas", + "Close modal": "Tutup modal", + "Close Modal": "Tutup Modal", + "Close settings modal": "Tutup modal tetapan", + "Close Sidebar": "Tutup Bar Sisi", + "cloud": "awan", + "CMU ARCTIC speaker embedding name": "Nama pembenaman pembicara CMU ARCTIC", + "Code Block": "Blok Kod", + "Code Editor": "Editor Kod", + "Code execution": "Pelaksanaan kod", + "Code Execution": "Pelaksanaan Kod", + "Code Execution Engine": "Enjin Pelaksanaan Kod", + "Code Execution Timeout": "Tamat Masa Pelaksanaan Kod", "Code formatted successfully": "Kod berjaya diformatkan", - "Code Interpreter": "", - "Code Interpreter Engine": "", - "Code Interpreter Prompt Template": "", - "Collaboration channel where people join as members": "", - "Collapse": "", + "Code Interpreter": "Penterjemah Kod", + "Code Interpreter Engine": "Enjin Penterjemah Kod", + "Code Interpreter Prompt Template": "Templat Prompt Penterjemah Kod", + "Collaboration channel where people join as members": "Saluran kolaborasi di mana orang bergabung sebagai ahli", + "Collapse": "Runtuhkan", "Collection": "Koleksi", - "Collections": "", - "Color": "", + "Collections": "Koleksi", + "Color": "Warna", "ComfyUI": "ComfyUI", - "ComfyUI API Key": "", + "ComfyUI API Key": "Kunci API ComfyUI", "ComfyUI Base URL": "URL asas ComfyUI", "ComfyUI Base URL is required.": "URL asas ComfyUI diperlukan", - "ComfyUI Workflow": "", - "ComfyUI Workflow Nodes": "", - "Comma separated Node Ids (e.g. 1 or 1,2)": "", - "command": "", + "ComfyUI Workflow": "Aliran Kerja ComfyUI", + "ComfyUI Workflow Nodes": "Nod Aliran Kerja ComfyUI", + "Comma separated Node Ids (e.g. 1 or 1,2)": "ID Nod yang dipisahkan dengan koma (cth. 1 atau 1,2)", + "command": "perintah", "Command": "Arahan", - "Comment": "", - "Commit Message": "", - "Community Reviews": "", - "Completions": "", - "Compress Images in Channels": "", + "Comment": "Komen", + "Commit Message": "Mesej Komit", + "Community Reviews": "Ulasan Komuniti", + "Completions": "Penyelesaian", + "Compress Images in Channels": "Mampat Imej dalam Saluran", "Concurrent Requests": "Permintaan Serentak", - "Config": "", - "Config imported successfully": "", - "Configure": "", + "Config": "Konfigurasi", + "Config imported successfully": "Konfigurasi diimport dengan berjaya", + "Configure": "Konfigurasikan", "Confirm": "Sahkan", "Confirm Password": "Sahkan kata laluan", "Confirm your action": "Sahkan tindakan anda", - "Confirm your new password": "", - "Confirm Your Password": "", - "Connect to an AI provider to start chatting": "", - "Connect to Open Terminal instances to browse files and use them as always-on tools. Only one can be active at a time.": "", - "Connect to Open Terminal instances. All users will have access to file browsing and terminal tools through these servers.": "", - "Connect to your own OpenAI compatible API endpoints.": "", - "Connect to your own OpenAPI compatible external tool servers.": "", - "Connection failed": "", - "Connection successful": "", - "Connection Type": "", + "Confirm your new password": "Sahkan kata laluan baru anda", + "Confirm Your Password": "Sahkan Kata Laluan Anda", + "Connect to an AI provider to start chatting": "Sambung ke penyedia AI untuk mulai berbual", + "Connect to Open Terminal instances to browse files and use them as always-on tools. Only one can be active at a time.": "Sambung ke instans Terminal Terbuka untuk layar fail dan gunakannya sebagai alat sentiasa aktif. Hanya satu boleh aktif pada satu masa.", + "Connect to Open Terminal instances. All users will have access to file browsing and terminal tools through these servers.": "Sambung ke instans Terminal Terbuka. Semua pengguna akan mempunyai akses kepada penyemakan fail dan alat terminal melalui pelayan ini.", + "Connect to your own OpenAI compatible API endpoints.": "Sambung ke titik akhir API yang serasi dengan OpenAI anda sendiri.", + "Connect to your own OpenAPI compatible external tool servers.": "Sambung ke pelayan alat luaran yang serasi dengan OpenAPI anda sendiri.", + "Connection failed": "Sambungan gagal", + "Connection successful": "Sambungan berjaya", + "Connection Type": "Jenis Sambungan", "Connections": "Sambungan", - "Connections saved successfully": "", - "Connections settings updated": "", - "Constrains effort on reasoning for reasoning models. Only applicable to reasoning models from specific providers that support reasoning effort.": "", + "Connections saved successfully": "Sambungan disimpan dengan berjaya", + "Connections settings updated": "Tetapan sambungan dikemas kini", + "Constrains effort on reasoning for reasoning models. Only applicable to reasoning models from specific providers that support reasoning effort.": "Mengehadkan usaha pada penaakulan untuk model penaakulan. Hanya terpakai pada model penaakulan daripada pembekal tertentu yang menyokong usaha penaakulan.", "Contact Admin for WebUI Access": "Hubungi admin untuk akses WebUI", "Content": "Kandungan", - "Content Extraction Engine": "", - "Content lengths (character counts only)": "", + "Content Extraction Engine": "Enjin Pengekstrakan Kandungan", + "Content lengths (character counts only)": "Panjang kandungan (kiraan aksara sahaja)", "Continue Response": "Teruskan Respons", "Continue with {{provider}}": "Teruskan dengan {{provider}}", - "Continue with Email": "", - "Continue with LDAP": "", - "Control how message text is split for TTS requests. 'Punctuation' splits into sentences, 'paragraphs' splits into paragraphs, and 'none' keeps the message as a single string.": "", - "Control the repetition of token sequences in the generated text. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 1.1) will be more lenient. At 1, it is disabled.": "", + "Continue with Email": "Teruskan dengan Email", + "Continue with LDAP": "Teruskan dengan LDAP", + "Control how message text is split for TTS requests. 'Punctuation' splits into sentences, 'paragraphs' splits into paragraphs, and 'none' keeps the message as a single string.": "Kawal cara teks mesej dibahagi untuk permintaan TTS. 'Punctuation' membahagi kepada ayat, 'paragraphs' membahagi kepada perenggan, dan 'none' mengekalkan mesej sebagai satu rentetan.", + "Control the repetition of token sequences in the generated text. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 1.1) will be more lenient. At 1, it is disabled.": "Kawal pengulangan jujukan token dalam teks yang dijana. Nilai yang lebih tinggi (cth. 1.5) akan menghukum pengulangan dengan lebih kuat, manakala nilai yang lebih rendah (cth. 1.1) akan lebih lembut. Pada 1, ia dilumpuhkan.", "Controls": "Kawalan", - "Controls the balance between coherence and diversity of the output. A lower value will result in more focused and coherent text.": "", - "Conversation saved successfully": "", + "Controls the balance between coherence and diversity of the output. A lower value will result in more focused and coherent text.": "Mengawal keseimbangan antara koheren dan kepelbagaian output. Nilai yang lebih rendah akan menghasilkan teks yang lebih fokus dan koheren.", + "Conversation saved successfully": "Perbualan disimpan dengan berjaya", "Copied": "Disalin", - "Copied link to clipboard": "", + "Copied link to clipboard": "Pautan disalin ke papan klip", "Copied shared chat URL to clipboard!": "Menyalin URL sembang kongsi ke papan klip", - "Copied to clipboard": "", + "Copied to clipboard": "Disalin ke papan klip", "Copy": "Salin", - "Copy API Key": "", - "Copy content": "", - "Copy Formatted Text": "", - "Copy Last Code Block": "", - "Copy Last Response": "", - "Copy link": "", + "Copy API Key": "Salin Kunci API", + "Copy content": "Salin kandungan", + "Copy Formatted Text": "Salin Teks Terformat", + "Copy Last Code Block": "Salin Blok Kod Terakhir", + "Copy Last Response": "Salin Respons Terakhir", + "Copy link": "Salin Pautan", "Copy Link": "Salin Pautan", - "Copy Prompt": "", - "Copy Share Link": "", - "Copy to clipboard": "", - "Copy Token": "", - "Copy URL": "", + "Copy Prompt": "Salin Prompt", + "Copy Share Link": "Salin Pautan Kongsian", + "Copy to clipboard": "Salin ke Papan Klip", + "Copy Token": "Salin Token", + "Copy URL": "Salin URL", "Copying to clipboard was successful!": "Menyalin ke papan klip berjaya!", - "CORS must be properly configured by the provider to allow requests from Open WebUI.": "", - "Could not read file.": "", - "Create": "", - "Create a knowledge base": "", + "CORS must be properly configured by the provider to allow requests from Open WebUI.": "CORS mesti dikonfigurasi dengan betul oleh pembekal untuk membenarkan permintaan daripada Open WebUI.", + "Could not read file.": "Tidak dapat membaca fail.", + "Create": "Buat", + "Create a knowledge base": "Buat pangkalan pengetahuan", "Create a model": "Cipta model", - "Create a new note": "", + "Create a new note": "Buat nota baru", "Create Account": "Cipta Akaun", - "Create Admin Account": "", - "Create Channel": "", - "Create Folder": "", - "Create Image": "", - "Create Knowledge": "", - "Create Model": "", + "Create Admin Account": "Buat Akaun Admin", + "Create Channel": "Buat Saluran", + "Create Folder": "Buat Folder", + "Create Image": "Buat Imej", + "Create Knowledge": "Buat Pengetahuan", + "Create Model": "Buat Model", "Create new key": "Cipta kekunci baharu", "Create new secret key": "Cipta kekunci rahsia baharu", - "Create note": "", - "Create Note": "", - "Create your first note by clicking on the plus button below.": "", + "Create note": "Buat nota", + "Create Note": "Buat Nota", + "Create your first note by clicking on the plus button below.": "Buat nota pertama anda dengan mengklik butang tambah di bawah.", "Created at": "Dicipta di", "Created At": "Dicipta Pada", "Created by": "Dicipta oleh", - "Created by you": "", - "Created on {{date}}": "", + "Created by you": "Dibuat oleh anda", + "Created on {{date}}": "Dibuat pada {{date}}", "CSV Import": "Import CSV", - "Ctrl+Enter to Send": "", + "Ctrl+Enter to Send": "Ctrl+Enter untuk Hantar", "Current Model": "Model Semasa", "Current Password": "Kata laluan semasa", "Custom": "Tersuai", - "Custom description enabled": "", - "Custom Gender": "", - "Custom Parameter Name": "", - "Custom Parameter Value": "", - "Daily Messages": "", - "Danger Zone": "", + "Custom description enabled": "Penerangan tersuai didayakan", + "Custom Gender": "Jantina Tersuai", + "Custom Parameter Name": "Nama Parameter Tersuai", + "Custom Parameter Value": "Nilai Parameter Tersuai", + "Daily Messages": "Mesej Harian", + "Danger Zone": "Zon Bahaya", "Dark": "Gelap", - "Data Controls": "", + "Data Controls": "Kawalan Data", "Database": "Pangkalan Data", - "Datalab Marker API": "", - "DD/MM/YYYY": "", - "DDGS Backend": "", + "Datalab Marker API": "API Penanda Datalab", + "DD/MM/YYYY": "DD/MM/YYYY", + "DDGS Backend": "Bahagian Belakang DDGS", "December": "Disember", - "Decrease UI Scale": "", - "Deepgram": "", + "Decrease UI Scale": "Kurangkan Skala UI", + "Deepgram": "Deepgram", "Default": "Lalai", - "Default (Open AI)": "", + "Default (Open AI)": "Lalai (Open AI)", "Default (SentenceTransformers)": "Lalai (SentenceTransformers)", - "Default action buttons will be used.": "", - "Default description enabled": "", - "Default Features": "", - "Default Filters": "", - "Default Group": "", - "Default mode works with a wider range of models by calling tools once before execution. Native mode leverages the model's built-in tool-calling capabilities, but requires the model to inherently support this feature.": "", + "Default action buttons will be used.": "Butang tindakan lalai akan digunakan.", + "Default description enabled": "Penerangan lalai diaktifkan", + "Default Features": "Fitur Lalai", + "Default Filters": "Penapis Lalai", + "Default Group": "Kumpulan Lalai", + "Default mode works with a wider range of models by calling tools once before execution. Native mode leverages the model's built-in tool-calling capabilities, but requires the model to inherently support this feature.": "Mode lalai berfungsi dengan rangkaian model yang lebih luas dengan memanggil alat sekali sebelum pelaksanaan. Mode asli memanfaatkan keupayaan panggilan alat terbina dalam model, tetapi memerlukan model untuk menyokong ciri ini secara bawaan.", "Default Model": "Model Lalai", "Default model updated": "Model lalai dikemas kini", - "Default permissions": "", - "Default permissions updated successfully": "", - "Default Prompt Suggestions": "Cadangan Gesaan Lalai", - "Default to 389 or 636 if TLS is enabled": "", - "Default to ALL": "", - "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default permissions": "Kebenaran Lalai", + "Default permissions updated successfully": "Kebenaran lalai dikemas kini dengan berjaya", + "Default Prompt Suggestions": "Cadangan arahan Lalai", + "Default to 389 or 636 if TLS is enabled": "Lalai kepada 389 atau 636 jika TLS didayakan", + "Default to ALL": "Lalai kepada SEMUA", + "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Lalai kepada pengambilan tersegmen untuk pengekstrakan kandungan yang berfokus dan relevan, ini disyorkan untuk kebanyakan kes.", "Default User Role": "Peranan Pengguna Lalai", - "Defaults": "", + "Defaults": "Lalai", "Delete": "Padam", - "Delete {{name}}": "", + "Delete {{name}}": "Padam {{name}}", "Delete a model": "Padam Model", - "Delete All": "", + "Delete All": "Padam Semua", "Delete All Chats": "Padam Semua Perbualan", - "Delete all contents inside this folder": "", + "Delete all contents inside this folder": "Padam semua kandungan dalam folder ini", "Delete Chat": "Padam Perbualan", "Delete chat?": "Padam perbualan?", - "Delete File": "", - "Delete folder?": "", + "Delete File": "Padam Fail", + "Delete folder?": "Padam folder?", "Delete function?": "Padam fungsi?", - "Delete Message": "", - "Delete message?": "", - "Delete Model": "", - "Delete note?": "", - "Delete prompt?": "Padam Gesaan?", - "Delete skill?": "", + "Delete Message": "Padam Mesej", + "Delete message?": "Padam mesej?", + "Delete Model": "Padam Model", + "Delete note?": "Padam nota?", + "Delete prompt?": "Padam arahan?", + "Delete skill?": "Padam kemahiran?", "delete this link": "Padam pautan ini?", "Delete tool?": "Padam alat?", "Delete User": "Padam Pengguna", - "Delete Version": "", - "Deleted": "", + "Delete Version": "Padam Versi", + "Deleted": "Sudah Dipadam", "Deleted {{deleteModelTag}}": "{{deleteModelTag}} dipadam", "Deleted {{name}}": "{{name}} dipadam", - "Deleted User": "", - "Deployment names are required for Azure OpenAI": "", - "Desc": "", - "Describe the edit...": "", - "Describe the image...": "", - "Describe what changed...": "", - "Describe your knowledge base and objectives": "", + "Deleted User": "Pengguna yang Dipadam", + "Deployment names are required for Azure OpenAI": "Nama penggunaan diperlukan untuk Azure OpenAI", + "Desc": "Penerangan", + "Describe the edit...": "Terangkan pengeditan...", + "Describe the image...": "Terangkan imej...", + "Describe what changed...": "Terangkan apa yang berubah...", + "Describe your knowledge base and objectives": "Terangkan pangkalan pengetahuan dan objektif anda", "Description": "Penerangan", - "Detect Artifacts Automatically": "", - "Dictate": "", + "Detect Artifacts Automatically": "Kesan Artifak Secara Automatik", + "Dictate": "Dikte", "Didn't fully follow instructions": "Tidak mengikut arahan sepenuhnya", - "Direct": "", - "Direct Connections": "", - "Direct Connections allow users to connect to their own OpenAI compatible API endpoints.": "", - "Direct Message": "", - "Direct Tool Servers": "", - "Directory selection was cancelled": "", - "Disable All": "", - "Disable Code Interpreter": "", - "Disable Image Extraction": "", - "Disable image extraction from the PDF. If Use LLM is enabled, images will be automatically captioned. Defaults to False.": "", + "Direct": "Langsung", + "Direct Connections": "Sambungan Langsung", + "Direct Connections allow users to connect to their own OpenAI compatible API endpoints.": "Sambungan Langsung membenarkan pengguna untuk menyambung ke titik akhir API yang serasi dengan OpenAI mereka sendiri.", + "Direct Message": "Mesej Langsung", + "Direct Tool Servers": "Pelayan Alat Langsung", + "Directory selection was cancelled": "Pemilihan direktori telah dibatalkan", + "Disable All": "Nyahlumpuhkan Semua", + "Disable Code Interpreter": "Nyahlumpuhkan Penterjemah Kod", + "Disable Image Extraction": "Nyahlumpuhkan Pengekstrakan Imej", + "Disable image extraction from the PDF. If Use LLM is enabled, images will be automatically captioned. Defaults to False.": "Melumpuhkan pengekstrakan imej daripada PDF. Jika Gunakan LLM didayakan, imej akan diselia secara automatik. Lalai kepada Palsu.", "Disabled": "Dilumpuhkan", "Discover a function": "Temui fungsi", "Discover a model": "Temui model", - "Discover a prompt": "Temui gesaan", + "Discover a prompt": "Temui arahan", "Discover a tool": "Temui alat", - "Discover how to use Open WebUI and seek support from the community.": "", - "Discover wonders": "", + "Discover how to use Open WebUI and seek support from the community.": "Temui cara menggunakan Open WebUI dan dapatkan sokongan daripada komuniti.", + "Discover wonders": "Temui keajaiban", "Discover, download, and explore custom functions": "Temui, muat turun dan teroka fungsi tersuai", - "Discover, download, and explore custom prompts": "Temui, muat turun dan teroka gesaan tersuai", + "Discover, download, and explore custom prompts": "Temui, muat turun dan teroka arahan tersuai", "Discover, download, and explore custom tools": "Temui, muat turun dan teroka alat tersuai", "Discover, download, and explore model presets": "Temui, muat turun dan teroka model pratetap", - "Discussion channel where access is based on groups and permissions": "", - "Display": "", - "Display chat title in tab": "", + "Discussion channel where access is based on groups and permissions": "Saluran perbincangan di mana akses berdasarkan kumpulan dan kebenaran", + "Display": "Paparan", + "Display chat title in tab": "Paparkan tajuk sembang dalam tab", "Display Emoji in Call": "Paparkan Emoji dalam Panggilan", - "Display Multi-model Responses in Tabs": "", + "Display Multi-model Responses in Tabs": "Paparkan Respons Multi-model dalam Tab", "Display the username instead of You in the Chat": "Paparkan nama pengguna dan bukannya 'Anda' dalam Sembang", - "Displays citations in the response": "", - "Displays status updates (e.g., web search progress) in the response": "", - "Dive into knowledge": "", + "Displays citations in the response": "Memaparkan petikan dalam respons", + "Displays status updates (e.g., web search progress) in the response": "Memaparkan kemas kini status (cth., kemajuan carian web) dalam respons", + "Dive into knowledge": "Menyelami pengetahuan", "Do not install functions from sources you do not fully trust.": "Jangan pasang fungsi daripada sumber yang anda tidak percayai sepenuhnya.", "Do not install tools from sources you do not fully trust.": "Jangan pasang alat daripada sumber yang anda tidak percaya sepenuhnya.", - "Do you want to sync your usage stats with Open WebUI Community?": "", - "Docling": "", - "Docling Parameters": "", - "Docling Server URL required.": "", + "Do you want to sync your usage stats with Open WebUI Community?": "Adakah anda ingin menyegerakkan statistik penggunaan anda dengan Komuniti Open WebUI?", + "Docling": "Docling", + "Docling Parameters": "Parameter Docling", + "Docling Server URL required.": "URL Pelayan Docling diperlukan.", "Document": "Dokumen", - "Document Intelligence": "", - "Document Intelligence endpoint required.": "", - "Document Intelligence Model": "", + "Document Intelligence": "Kecerdasan Dokumen", + "Document Intelligence endpoint required.": "Titik akhir Dokumen Kecerdasan diperlukan.", + "Document Intelligence Model": "Document Model Kecerdasan", "Documentation": "Dokumentasi", - "Documents": "", + "Documents": "Dokumen", "does not make any external connections, and your data stays securely on your locally hosted server.": "tidak membuat sebarang sambungan luaran, dan data anda kekal selamat pada pelayan yang dihoskan ditempat anda", - "Domain Filter List": "", + "Domain Filter List": "Senarai Penapis Domain", "don't fetch random pipelines from sources you don't trust.": "Jangan ambil pipeline rawak daripada sumber yang anda tidak percayai.", "Don't have an account?": "Anda tidak mempunyai akaun?", "don't install random functions from sources you don't trust.": "jangan pasang mana-mana fungsi daripada sumber yang anda tidak percayai.", @@ -573,793 +573,793 @@ "Done": "Selesai", "Download": "Muat Turun", "Download & Delete": "Muat turun & Padam", - "Download as JSON": "", - "Download as SVG": "", + "Download as JSON": "Muat Turun sebagai JSON", + "Download as SVG": "Muat turun sebagai SVG", "Download canceled": "Muat Turun dibatalkan", "Download Database": "Muat turun Pangkalan Data", - "Downloading stats...": "", - "Draw": "", - "Drop any files here to upload": "", - "Drop files here": "", - "Drop files here to upload": "", - "DuckDuckGo": "", + "Downloading stats...": "Memuat turun statistik...", + "Draw": "Lukis", + "Drop any files here to upload": "Lepaskan fail di sini untuk muat naik", + "Drop files here": "Lepaskan fail di sini", + "Drop files here to upload": "Lepaskan fail di sini untuk muat naik", + "DuckDuckGo": "DuckDuckGo", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "cth '30s','10m'. Unit masa yang sah ialah 's', 'm', 'h'.", - "e.g. 'low', 'medium', 'high'": "", - "e.g. \"json\" or a JSON schema": "", - "e.g. 60": "", - "e.g. A filter to remove profanity from text": "", - "e.g. about the Roman Empire": "", - "e.g. alloy, echo, shimmer": "", - "e.g. Code Review Guidelines": "", - "e.g. code-review-guidelines": "", - "e.g. en": "", - "e.g. My Filter": "", - "e.g. My Tools": "", - "e.g. my_filter": "", - "e.g. my_tools": "", - "e.g. pdf, docx, txt": "", - "e.g. Step-by-step instructions for code reviews": "", - "e.g. Tell me a fun fact": "", - "e.g. Tell me a fun fact about the Roman Empire": "", - "e.g. Tools for performing various operations": "", - "e.g., 3, 4, 5 (leave blank for default)": "", - "e.g., audio/wav,audio/mpeg,video/* (leave blank for defaults)": "", - "e.g., en-US,ja-JP (leave blank for auto-detect)": "", - "e.g., westus (leave blank for eastus)": "", + "e.g. 'low', 'medium', 'high'": "cth. 'rendah', 'sederhana', 'tinggi'", + "e.g. \"json\" or a JSON schema": "cth. \"json\" atau skema JSON", + "e.g. 60": "cth. 60", + "e.g. A filter to remove profanity from text": "cth. Penapis untuk membuang kata-kata lucah daripada teks", + "e.g. about the Roman Empire": "cth. tentang Empayar Rom", + "e.g. alloy, echo, shimmer": "cth. aloi, gema, kilauan", + "e.g. Code Review Guidelines": "cth. Garis Panduan Semakan Kod", + "e.g. code-review-guidelines": "cth. garis-panduan-semakan-kod", + "e.g. en": "cth. ms", + "e.g. My Filter": "cth. Penapis Saya", + "e.g. My Tools": "cth. Alatan Saya", + "e.g. my_filter": "cth. penapis_saya", + "e.g. my_tools": "cth. alatan_saya", + "e.g. pdf, docx, txt": "cth. pdf, docx, txt", + "e.g. Step-by-step instructions for code reviews": "cth. Arahan langkah demi langkah untuk semakan kod", + "e.g. Tell me a fun fact": "cth. Beritahu saya fakta menarik", + "e.g. Tell me a fun fact about the Roman Empire": "cth. Beritahu saya fakta menarik tentang Empayar Rom", + "e.g. Tools for performing various operations": "cth. Alat untuk melakukan pelbagai operasi", + "e.g., 3, 4, 5 (leave blank for default)": "cth., 3, 4, 5 (biarkan kosong untuk lalai)", + "e.g., audio/wav,audio/mpeg,video/* (leave blank for defaults)": "cth., audio/wav,audio/mpeg,video/* (biarkan kosong untuk lalai)", + "e.g., en-US,ja-JP (leave blank for auto-detect)": "cth., en-US,ja-JP (biarkan kosong untuk auto-detect)", + "e.g., westus (leave blank for eastus)": "cth., westus (biarkan kosong untuk eastus)", "Edit": "Edit", - "Edit Arena Model": "", - "Edit Channel": "", - "Edit Connection": "", - "Edit Default Permissions": "", - "Edit Folder": "", - "Edit Image": "", - "Edit Last Message": "", + "Edit Arena Model": "Edit Model Arena", + "Edit Channel": "Edit Saluran", + "Edit Connection": "Edit Sambungan", + "Edit Default Permissions": "Edit Kebenaran Lalai", + "Edit Folder": "Edit Folder", + "Edit Image": "Edit Imej", + "Edit Last Message": "Edit Mesej Terakhir", "Edit Memory": "Edit Memori", - "Edit Prompt": "", - "Edit Terminal Connection": "", + "Edit Prompt": "Edit Arahan", + "Edit Terminal Connection": "Edit Sambungan Terminal", "Edit User": "Edit Penggunal", - "Edit User Group": "", - "Edit workflow.json content": "", - "edited": "", - "Edited": "", - "Editing": "", - "Eject": "", - "Eject model": "", + "Edit User Group": "Edit Kumpulan Pengguna", + "Edit workflow.json content": "Edit kandungan workflow.json", + "edited": "disunting", + "Edited": "Disunting", + "Editing": "Menyunting", + "Eject": "Keluarkan", + "Eject model": "Keluarkan model", "ElevenLabs": "ElevenLabs", "Email": "E-mel", - "Embark on adventures": "", - "Embedding": "", + "Embark on adventures": "Mulai petualangan", + "Embedding": "Pembenaman", "Embedding Batch Size": "Membenamkan Saiz Kelompok", - "Embedding Concurrent Requests": "", + "Embedding Concurrent Requests": "Permintaan Serentak Pembenaman", "Embedding Model": "Model Benamkan", "Embedding Model Engine": "Enjin Model Benamkan", - "Enable All": "", - "Enable API Keys": "", - "Enable autocomplete generation for chat messages": "", - "Enable Code Execution": "", - "Enable Code Interpreter": "", + "Enable All": "Dayakan Semua", + "Enable API Keys": "Dayakan Kunci API", + "Enable autocomplete generation for chat messages": "Aktifkan penjanaan auto-lengkap untuk mesej sembang", + "Enable Code Execution": "Aktifkan Pelaksanaan Kod", + "Enable Code Interpreter": "Aktifkan Pentafsir Kod", "Enable Community Sharing": "Benarkan Perkongsian Komuniti", - "Enable Memory Locking (mlock) to prevent model data from being swapped out of RAM. This option locks the model's working set of pages into RAM, ensuring that they will not be swapped out to disk. This can help maintain performance by avoiding page faults and ensuring fast data access.": "", - "Enable Memory Mapping (mmap) to load model data. This option allows the system to use disk storage as an extension of RAM by treating disk files as if they were in RAM. This can improve model performance by allowing for faster data access. However, it may not work correctly with all systems and can consume a significant amount of disk space.": "", - "Enable Message Queue": "", - "Enable Message Rating": "", - "Enable Mirostat sampling for controlling perplexity.": "", + "Enable Memory Locking (mlock) to prevent model data from being swapped out of RAM. This option locks the model's working set of pages into RAM, ensuring that they will not be swapped out to disk. This can help maintain performance by avoiding page faults and ensuring fast data access.": "Aktifkan Penguncian Memori (mlock) untuk mencegah data model daripada ditukar keluar daripada RAM. Pilihan ini mengunci set halaman kerja model ke dalam RAM, memastikan bahawa ia tidak akan ditukar ke cakera. Ini boleh membantu mengekalkan prestasi dengan mengelakkan kesalahan halaman dan memastikan akses data yang cepat.", + "Enable Memory Mapping (mmap) to load model data. This option allows the system to use disk storage as an extension of RAM by treating disk files as if they were in RAM. This can improve model performance by allowing for faster data access. However, it may not work correctly with all systems and can consume a significant amount of disk space.": "Aktifkan Pemetaan Memori (mmap) untuk memuatkan data model. Pilihan ini membenarkan sistem menggunakan storan cakera sebagai lanjutan RAM dengan memperlakukan fail cakera seolah-olah ia berada di dalam RAM. Ini boleh meningkatkan prestasi model dengan membenarkan akses data yang lebih cepat. Walau bagaimanapun, ia mungkin tidak berfungsi dengan betul pada semua sistem dan boleh menggunakan sejumlah besar ruang cakera.", + "Enable Message Queue": "Aktifkan Barisan Mesej", + "Enable Message Rating": "Aktifkan Penilaian Mesej", + "Enable Mirostat sampling for controlling perplexity.": "Aktifkan pensampelan Mirostat untuk mengawal kekeliruan.", "Enable New Sign Ups": "Benarkan Pendaftaran Baharu", - "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", + "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "Aktifkan, nyahaktifkan, atau sesuaikan teg penaakulan yang digunakan oleh model. \"Diaktifkan\" menggunakan teg lalai, \"Dilumpuhkan\" mematikan teg penaakulan, dan \"Tersuai\" membenarkan anda menentukan teg permulaan dan akhir anda sendiri.", "Enabled": "Dibenarkan", - "End Tag": "", - "Endpoint URL": "", - "Enforce Temporary Chat": "", - "Enhance": "", - "Enrich Hybrid Search Text": "", + "End Tag": "Teg Akhir", + "Endpoint URL": "URL Titik Akhir", + "Enforce Temporary Chat": "Kuatkuasakan Sembang Sementara", + "Enhance": "Tingkatkan", + "Enrich Hybrid Search Text": "Perkaya Teks Carian Hibrid", "Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "astikan fail CSV anda mengandungi 4 lajur dalam susunan ini: Nama, E-mel, Kata Laluan, Peranan.", "Enter {{role}} message here": "Masukkan mesej {{role}} di sini", "Enter a detail about yourself for your LLMs to recall": "Masukkan butiran tentang diri anda untuk diingati oleh LLM anda", - "Enter a title for the pending user info overlay. Leave empty for default.": "", - "Enter a watermark for the response. Leave empty for none.": "", - "Enter additional headers in JSON format": "", - "Enter additional headers in JSON format (e.g. {\"X-Custom-Header\": \"value\"}": "", - "Enter additional parameters in JSON format": "", + "Enter a title for the pending user info overlay. Leave empty for default.": "Masukkan tajuk untuk overlay maklumat pengguna yang tertunda. Biarkan kosong untuk lalai.", + "Enter a watermark for the response. Leave empty for none.": "Masukkan tera air untuk respons. Biarkan kosong untuk tiada.", + "Enter additional headers in JSON format": "Masukkan pengepala tambahan dalam format JSON", + "Enter additional headers in JSON format (e.g. {\"X-Custom-Header\": \"value\"}": "Masukkan pengepala tambahan dalam format JSON (cth. {\"X-Custom-Header\": \"value\"}", + "Enter additional parameters in JSON format": "Masukkan parameter tambahan dalam format JSON", "Enter api auth string (e.g. username:password)": "Masukkan kekunci auth api ( cth nama pengguna:kata laluan )", - "Enter Application DN": "", - "Enter Application DN Password": "", - "Enter Bing Search V7 Endpoint": "", - "Enter Bing Search V7 Subscription Key": "", - "Enter Bocha Search API Key": "", + "Enter Application DN": "Masukkan DN Aplikasi", + "Enter Application DN Password": "Masukkan Kata Laluan DN Aplikasi", + "Enter Bing Search V7 Endpoint": "Masukkan Titik Akhir Bing Search V7", + "Enter Bing Search V7 Subscription Key": "Masukkan Kunci Langganan Bing Search V7", + "Enter Bocha Search API Key": "Masukkan Kunci API Pencarian Bocha", "Enter Brave Search API Key": "Masukkan Kekunci API carian Brave", - "Enter certificate path": "", - "Enter Chunk Min Size Target": "", + "Enter certificate path": "Masukkan laluan sertifikat", + "Enter Chunk Min Size Target": "Masukkan Saiz Minimum Chunk Target", "Enter Chunk Overlap": "Masukkan Tindihan 'Chunk'", "Enter Chunk Size": "Masukkan Saiz 'Chunk'", - "Enter comma-separated \"token:bias_value\" pairs (example: 5432:100, 413:-100)": "", - "Enter content for the pending user info overlay. Leave empty for default.": "", - "Enter coordinates (e.g. 51.505, -0.09)": "", - "Enter Datalab Marker API Base URL": "", - "Enter Datalab Marker API Key": "", - "Enter description": "", - "Enter Docling API Key": "", - "Enter Docling Server URL": "", - "Enter Document Intelligence Endpoint": "", - "Enter Document Intelligence Key": "", - "Enter Document Intelligence Model": "", - "Enter domains separated by commas (e.g., example.com,site.org,!excludedsite.com)": "", - "Enter Exa API Key": "", - "Enter External Document Loader API Key": "", - "Enter External Document Loader URL": "", - "Enter External Web Loader API Key": "", - "Enter External Web Loader URL": "", - "Enter External Web Search API Key": "", - "Enter External Web Search URL": "", - "Enter Firecrawl API Base URL": "", - "Enter Firecrawl API Key": "", - "Enter Firecrawl Timeout": "", - "Enter folder name": "", - "Enter function name filter list (e.g. func1, !func2)": "", + "Enter comma-separated \"token:bias_value\" pairs (example: 5432:100, 413:-100)": "Masukkan pasangan \"token:bias_value\" yang dipisahkan dengan koma (contoh: 5432:100, 413:-100)", + "Enter content for the pending user info overlay. Leave empty for default.": "Masukkan kandungan untuk lapisan maklumat pengguna tertangguh. Biarkan kosong untuk lalai.", + "Enter coordinates (e.g. 51.505, -0.09)": "Masukkan koordinat (cth. 51.505, -0.09)", + "Enter Datalab Marker API Base URL": "Masukkan URL Asas API Penanda Datalab", + "Enter Datalab Marker API Key": "Masukkan Kunci API Datalab Marker", + "Enter description": "Masukkan penerangan", + "Enter Docling API Key": "Masukkan Kunci API Docling", + "Enter Docling Server URL": "Masukkan URL Pelayan Docling", + "Enter Document Intelligence Endpoint": "Masukkan Titik Akhir Document Intelligence", + "Enter Document Intelligence Key": "Masukkan Kunci Document Intelligence", + "Enter Document Intelligence Model": "Masukkan Model Document Intelligence", + "Enter domains separated by commas (e.g., example.com,site.org,!excludedsite.com)": "Masukkan domain yang dipisahkan dengan koma (cth. example.com,site.org,!excludedsite.com)", + "Enter Exa API Key": "Masukkan Kunci API Exa", + "Enter External Document Loader API Key": "Masukkan Kunci API Pemuat Dokumen Luaran", + "Enter External Document Loader URL": "Masukkan URL Pemuat Dokumen Luaran", + "Enter External Web Loader API Key": "Masukkan Kunci API Pemuat Web Luaran", + "Enter External Web Loader URL": "Masukkan URL Pemuat Web Luaran", + "Enter External Web Search API Key": "Masukkan Kunci API Carian Web Luaran", + "Enter External Web Search URL": "Masukkan URL Carian Web Luaran", + "Enter Firecrawl API Base URL": "Masukkan URL Asas API Firecrawl", + "Enter Firecrawl API Key": "Masukkan Kunci API Firecrawl", + "Enter Firecrawl Timeout": "Masukkan Masa Tamat Firecrawl", + "Enter folder name": "Masukkan nama folder", + "Enter function name filter list (e.g. func1, !func2)": "Masukkan senarai penapis nama fungsi (cth. func1, !func2)", "Enter Github Raw URL": "Masukkan URL 'Github Raw'", "Enter Google PSE API Key": "Masukkan kunci API Google PSE", "Enter Google PSE Engine Id": "Masukkan Id Enjin Google PSE", - "Enter hex color (e.g. #FF0000)": "", + "Enter hex color (e.g. #FF0000)": "Masukkan warna heks (cth. #FF0000)", "Enter Image Size (e.g. 512x512)": "Masukkan Saiz Imej (cth 512x512)", - "Enter Jina API Base URL": "", - "Enter Jina API Key": "", - "Enter JSON config (e.g., {\"disable_links\": true})": "", - "Enter Jupyter Password": "", - "Enter Jupyter Token": "", - "Enter Jupyter URL": "", - "Enter Kagi Search API Key": "", - "Enter Key Behavior": "", + "Enter Jina API Base URL": "Masukkan URL Asas API Jina", + "Enter Jina API Key": "Masukkan Kunci API Jina", + "Enter JSON config (e.g., {\"disable_links\": true})": "Masukkan konfigurasi JSON (cth., {\"disable_links\": true})", + "Enter Jupyter Password": "Masukkan Kata Laluan Jupyter", + "Enter Jupyter Token": "Masukkan Token Jupyter", + "Enter Jupyter URL": "Masukkan URL Jupyter", + "Enter Kagi Search API Key": "Masukkan Kunci API Pencarian Kagi", + "Enter Key Behavior": "Masukkan Perilaku Kunci", "Enter language codes": "Masukkan kod bahasa", - "Enter MinerU API Key": "", - "Enter Mistral API Base URL": "", - "Enter Mistral API Key": "", - "Enter Model ID": "", + "Enter MinerU API Key": "Masukkan Kunci API MinerU", + "Enter Mistral API Base URL": "Masukkan URL Asas API Mistral", + "Enter Mistral API Key": "Masukkan Kunci API Mistral", + "Enter Model ID": "Masukkan ID Model", "Enter model tag (e.g. {{modelTag}})": "Masukkan tag model (cth {{ modelTag }})", - "Enter Mojeek Search API Key": "", - "Enter name": "", - "Enter New Password": "", + "Enter Mojeek Search API Key": "Masukkan Kunci API Pencarian Mojeek", + "Enter name": "Masukkan nama", + "Enter New Password": "Masukkan Kata Laluan Baharu", "Enter Number of Steps (e.g. 50)": "Masukkan Bilangan Langkah (cth 50)", - "Enter Ollama Cloud API Key": "", - "Enter Perplexity API Key": "", - "Enter Perplexity Search API URL": "", - "Enter Playwright Timeout": "", - "Enter Playwright WebSocket URL": "", - "Enter proxy URL (e.g. https://user:password@host:port)": "", - "Enter reasoning effort": "", + "Enter Ollama Cloud API Key": "Masukkan Kunci API Ollama Cloud", + "Enter Perplexity API Key": "Masukkan Kunci API Perplexity", + "Enter Perplexity Search API URL": "Masukkan URL API Pencarian Perplexity", + "Enter Playwright Timeout": "Masukkan Masa Tamat Playwright", + "Enter Playwright WebSocket URL": "Masukkan URL WebSocket Playwright", + "Enter proxy URL (e.g. https://user:password@host:port)": "Masukkan URL proksi (contoh: https://user:password@host:port)", + "Enter reasoning effort": "Masukkan usaha penaakulan", "Enter Score": "Masukkan Skor", - "Enter SearchApi API Key": "", - "Enter SearchApi Engine": "", + "Enter SearchApi API Key": "Masukkan Kunci API SearchApi", + "Enter SearchApi Engine": "Masukkan Enjin SearchApi", "Enter Searxng Query URL": "Masukkan URL 'Searxng Query'", - "Enter Searxng search language": "", - "Enter Seed": "", - "Enter SerpApi API Key": "", - "Enter SerpApi Engine": "", + "Enter Searxng search language": "Masukkan bahasa carian Searxng", + "Enter Seed": "Masukkan Benih", + "Enter SerpApi API Key": "Masukkan Kunci API SerpApi", + "Enter SerpApi Engine": "Masukkan Enjin SerpApi", "Enter Serper API Key": "Masukkan Kunci API Serper", "Enter Serply API Key": "Masukkan Kunci API Serply", "Enter Serpstack API Key": "Masukkan Kunci API Serpstack", - "Enter server host": "", - "Enter server label": "", - "Enter server port": "", - "Enter skill instructions in markdown...": "", - "Enter Sougou Search API sID": "", - "Enter Sougou Search API SK": "", + "Enter server host": "Masukkan hos pelayan", + "Enter server label": "Masukkan label pelayan", + "Enter server port": "Masukkan port pelayan", + "Enter skill instructions in markdown...": "Masukkan arahan kemahiran dalam markdown...", + "Enter Sougou Search API sID": "Masukkan sID API Pencarian Sougou", + "Enter Sougou Search API SK": "Masukkan SK API Pencarian Sougou", "Enter stop sequence": "Masukkan urutan hentian", - "Enter system prompt": "Masukkan gesaan sistem", - "Enter system prompt here": "", + "Enter system prompt": "Masukkan arahan sistem", + "Enter system prompt here": "Masukkan gesaran sistem di sini", "Enter Tavily API Key": "Masukkan Kunci API Tavily", - "Enter Tavily Extract Depth": "", - "Enter the public URL of your WebUI. This URL will be used to generate links in the notifications.": "", - "Enter the URL of the function to import": "", - "Enter the URL to import": "", + "Enter Tavily Extract Depth": "Masukkan Kedalaman Ekstrak Tavily", + "Enter the public URL of your WebUI. This URL will be used to generate links in the notifications.": "Masukkan URL awam WebUI anda. URL ini akan digunakan untuk menjana pautan dalam pemberitahuan.", + "Enter the URL of the function to import": "Masukkan URL fungsi untuk diimport", + "Enter the URL to import": "Masukkan URL untuk diimport", "Enter Tika Server URL": "Masukkan URL Pelayan Tika", - "Enter timeout in seconds": "", - "Enter to Send": "", + "Enter timeout in seconds": "Masukkan had masa dalam saat", + "Enter to Send": "Tekan untuk Hantar", "Enter Top K": "Masukkan 'Top K'", - "Enter Top K Reranker": "", + "Enter Top K Reranker": "Masukkan Top K Penyusun Semula", "Enter URL (e.g. http://127.0.0.1:7860/)": "Masukkan URL (cth http://127.0.0.1:7860/)", "Enter URL (e.g. http://localhost:11434)": "Masukkan URL (cth http://localhost:11434)", - "Enter value": "", - "Enter value (true/false)": "", - "Enter Yacy Password": "", - "Enter Yacy URL (e.g. http://yacy.example.com:8090)": "", - "Enter Yacy Username": "", - "Enter Yandex Web Search API Key": "", - "Enter Yandex Web Search URL": "", - "Enter You.com API Key": "", + "Enter value": "Masukkan nilai", + "Enter value (true/false)": "Masukkan nilai (benar/salah)", + "Enter Yacy Password": "Masukkan Kata Laluan Yacy", + "Enter Yacy URL (e.g. http://yacy.example.com:8090)": "Masukkan URL Yacy (cth. http://yacy.example.com:8090)", + "Enter Yacy Username": "Masukkan Nama Pengguna Yacy", + "Enter Yandex Web Search API Key": "Masukkan Kunci API Pencarian Web Yandex", + "Enter Yandex Web Search URL": "Masukkan URL Pencarian Web Yandex", + "Enter You.com API Key": "Masukkan Kunci API You.com", "Enter your code here...": "Masukkan kod anda di sini...", - "Enter your current password": "", + "Enter your current password": "Masukkan kata laluan semasa anda", "Enter Your Email": "Masukkan E-mel Anda", "Enter Your Full Name": "Masukkan Nama Penuh Anda", - "Enter your gender": "", + "Enter your gender": "Masukkan jantina anda", "Enter your message": "Masukkan mesej anda", - "Enter your name": "", - "Enter Your Name": "", - "Enter your new password": "", + "Enter your name": "Masukkan nama anda", + "Enter Your Name": "Masukkan Nama Anda", + "Enter your new password": "Masukkan kata laluan baru anda", "Enter Your Password": "Masukkan Kata Laluan Anda", "Enter Your Role": "Masukkan Peranan Anda", - "Enter Your Username": "", - "Enter your webhook URL": "", - "Entra ID": "", + "Enter Your Username": "Masukkan Nama Pengguna Anda", + "Enter your webhook URL": "Masukkan URL webhook anda", + "Entra ID": "Entra ID", "Error": "Ralat", - "ERROR": "", - "Error accessing directory": "", - "Error accessing Google Drive: {{error}}": "", - "Error accessing media devices.": "", - "Error starting recording.": "", - "Error unloading model: {{error}}": "", - "Error uploading file: {{error}}": "", - "Error: A model with the ID '{{modelId}}' already exists. Please select a different ID to proceed.": "", - "Error: Model ID cannot be empty. Please enter a valid ID to proceed.": "", - "Evaluations": "", - "Exa API Key": "", - "Example: (&(objectClass=inetOrgPerson)(uid=%s))": "", - "Example: ALL": "", - "Example: mail": "", - "Example: ou=users,dc=foo,dc=example": "", - "Example: sAMAccountName or uid or userPrincipalName": "", - "Exceeded the number of seats in your license. Please contact support to increase the number of seats.": "", - "Exclude": "", - "Execute code": "", - "Execute code for analysis": "", - "Executing **{{NAME}}**...": "", - "Expand": "", + "ERROR": "RALAT", + "Error accessing directory": "Ralat mengakses direktori", + "Error accessing Google Drive: {{error}}": "Ralat mengakses Google Drive: {{error}}", + "Error accessing media devices.": "Ralat mengakses peranti media.", + "Error starting recording.": "Ralat memulai rakaman.", + "Error unloading model: {{error}}": "Ralat memunggah model: {{error}}", + "Error uploading file: {{error}}": "Ralat memuat naik fail: {{error}}", + "Error: A model with the ID '{{modelId}}' already exists. Please select a different ID to proceed.": "Ralat: Model dengan ID '{{modelId}}' sudah wujud. Sila pilih ID yang berbeza untuk meneruskan.", + "Error: Model ID cannot be empty. Please enter a valid ID to proceed.": "Ralat: ID Model tidak boleh kosong. Sila masukkan ID yang sah untuk meneruskan.", + "Evaluations": "Penilaian", + "Exa API Key": "Kunci API Exa", + "Example: (&(objectClass=inetOrgPerson)(uid=%s))": "Example: (&(objectClass=inetOrgPerson)(uid=%s))", + "Example: ALL": "Contoh: SEMUA", + "Example: mail": "Contoh: mail", + "Example: ou=users,dc=foo,dc=example": "Contoh: ou=users,dc=foo,dc=example", + "Example: sAMAccountName or uid or userPrincipalName": "Contoh: sAMAccountName atau uid atau userPrincipalName", + "Exceeded the number of seats in your license. Please contact support to increase the number of seats.": "Telah melampaui bilangan tempat duduk dalam lesen anda. Sila hubungi sokongan untuk meningkatkan bilangan tempat duduk.", + "Exclude": "Kecualikan", + "Execute code": "Laksanakan kod", + "Execute code for analysis": "Laksanakan kod untuk analisis", + "Executing **{{NAME}}**...": "Melaksanakan **{{NAME}}**...", + "Expand": "Kembangkan", "Experimental": "Percubaan", - "Explain": "", - "Explore the cosmos": "", + "Explain": "Jelaskan", + "Explore the cosmos": "Jelajahi alam semesta", "Export": "Eksport", - "Export All Archived Chats": "", + "Export All Archived Chats": "Eksport Semua Sembang Tersimpan", "Export All Chats (All Users)": "Eksport Semua Perbualan (Semua Pengguna)", "Export chat (.json)": "Eksport perbualan (.json)", "Export Chats": "Eksport Perbualan", - "Export Config": "", - "Export Models": "", - "Export Prompts": "", - "Export to CSV": "", - "Export Tools": "", - "Export Users": "", - "External": "", - "External Document Loader URL required.": "", - "External Task Model": "", - "External Web Loader API Key": "", - "External Web Loader URL": "", - "External Web Search API Key": "", - "External Web Search URL": "", - "Fade Effect for Streaming Text": "", - "Failed to add file.": "", - "Failed to add members": "", - "Failed to archive chat.": "", - "Failed to attach file": "", - "Failed to clear status": "", - "Failed to connect to {{URL}} OpenAPI tool server": "", - "Failed to connect to {{URL}} terminal server": "", - "Failed to copy link": "", + "Export Config": "Eksport Konfigurasi", + "Export Models": "Eksport Model", + "Export Prompts": "Eksport Prompt", + "Export to CSV": "Eksport ke CSV", + "Export Tools": "Eksport Alat", + "Export Users": "Eksport Pengguna", + "External": "Luaran", + "External Document Loader URL required.": "URL Pemuat Dokumen Luaran diperlukan.", + "External Task Model": "Model Tugas Luaran", + "External Web Loader API Key": "Kunci API Pemuat Web Luaran", + "External Web Loader URL": "URL Pemuat Web Luaran", + "External Web Search API Key": "Kunci API Carian Web Luaran", + "External Web Search URL": "URL Carian Web Luaran", + "Fade Effect for Streaming Text": "Kesan Pudar untuk Teks Penstriman", + "Failed to add file.": "Gagal menambah fail.", + "Failed to add members": "Gagal menambah ahli", + "Failed to archive chat.": "Gagal mengarkibkan sembang.", + "Failed to attach file": "Gagal melampirkan fail", + "Failed to clear status": "Gagal mengosongkan status", + "Failed to connect to {{URL}} OpenAPI tool server": "Gagal menyambung ke pelayan alat OpenAPI {{URL}}", + "Failed to connect to {{URL}} terminal server": "Gagal menyambung ke pelayan terminal {{URL}}", + "Failed to copy link": "Gagal menyalin pautan", "Failed to create API Key.": "Gagal mencipta kekunci API", - "Failed to delete note": "", - "Failed to download image": "", - "Failed to extract content from the file: {{error}}": "", - "Failed to extract content from the file.": "", - "Failed to fetch models": "", - "Failed to generate title": "", - "Failed to import models": "", - "Failed to load chat preview": "", - "Failed to load DOCX file. Please try downloading it instead.": "", - "Failed to load Excel/CSV file. Please try downloading it instead.": "", - "Failed to load file content.": "", - "Failed to load Interface settings": "", - "Failed to load PPTX file. Please try downloading it instead.": "", - "Failed to move chat": "", - "Failed to process URL: {{url}}": "", + "Failed to delete note": "Gagal memadamkan nota", + "Failed to download image": "Gagal memuat turun imej", + "Failed to extract content from the file: {{error}}": "Gagal mengekstrak kandungan daripada fail: {{error}}", + "Failed to extract content from the file.": "Gagal mengekstrak kandungan daripada fail.", + "Failed to fetch models": "Gagal mengambil model", + "Failed to generate title": "Gagal menjana tajuk", + "Failed to import models": "Gagal mengimport model", + "Failed to load chat preview": "Gagal memuatkan pratonton obrolan", + "Failed to load DOCX file. Please try downloading it instead.": "Gagal memuatkan fail DOCX. Sila cuba muat turun sebaliknya.", + "Failed to load Excel/CSV file. Please try downloading it instead.": "Gagal memuatkan fail Excel/CSV. Sila cuba muat turun sebaliknya.", + "Failed to load file content.": "Gagal memuatkan kandungan fail.", + "Failed to load Interface settings": "Gagal memuatkan tetapan Antara Muka", + "Failed to load PPTX file. Please try downloading it instead.": "Gagal memuatkan fail PPTX. Sila cuba muat turun sebaliknya.", + "Failed to move chat": "Gagal memindahkan obrolan", + "Failed to process URL: {{url}}": "Gagal memproses URL: {{url}}", "Failed to read clipboard contents": "Gagal membaca konten papan klip", - "Failed to remove member": "", - "Failed to render diagram": "", - "Failed to render visualization": "", - "Failed to save connections": "", + "Failed to remove member": "Gagal mengeluarkan ahli", + "Failed to render diagram": "Gagal merender rajah", + "Failed to render visualization": "Gagal merender visualisasi", + "Failed to save connections": "Gagal menyimpan sambungan", "Failed to save conversation": "Gagal menyimpan perbualan", - "Failed to save models configuration": "", - "Failed to save terminal servers": "", - "Failed to unshare chat.": "", + "Failed to save models configuration": "Gagal menyimpan konfigurasi model", + "Failed to save terminal servers": "Gagal menyimpan pelayan terminal", + "Failed to unshare chat.": "Gagal membatalkan perkongsian sembang.", "Failed to update settings": "Gagal mengemaskini tetapan", - "Failed to update status": "", - "Failed to upload file.": "", - "Features": "", - "Features Permissions": "", + "Failed to update status": "Gagal mengemaskini status", + "Failed to upload file.": "Gagal memuat naik fail.", + "Features": "Ciri-ciri", + "Features Permissions": "Kebenaran Ciri-ciri", "February": "Febuari", - "Feedback": "", - "Feedback Activity": "", - "Feedback deleted successfully": "", - "Feedback Details": "", - "Feedback History": "", + "Feedback": "Maklum Balas", + "Feedback Activity": "Aktiviti Maklum Balas", + "Feedback deleted successfully": "Maklum balas telah dipadam dengan berjaya", + "Feedback Details": "Butiran Maklum Balas", + "Feedback History": "Sejarah Maklum Balas", "Feel free to add specific details": "Jangan ragu untuk menambah butiran khusus", - "Female": "", + "Female": "Perempuan", "File": "Fail", - "File added successfully.": "", - "File attached to chat": "", - "File browser": "", - "File content": "", - "File content updated successfully.": "", - "File Context": "", - "File deleted successfully.": "", + "File added successfully.": "Fail telah ditambah dengan berjaya.", + "File attached to chat": "Fail dilampirkan pada sembang", + "File browser": "Pelayar fail", + "File content": "Kandungan fail", + "File content updated successfully.": "Kandungan fail dikemas kini dengan berjaya.", + "File Context": "Konteks Fail", + "File deleted successfully.": "Fail telah dipadamkan dengan berjaya.", "File Mode": "Mod Fail", - "File name": "", + "File name": "Nama fail", "File not found.": "Fail tidak dijumpai", - "File removed successfully.": "", - "File size should not exceed {{maxSize}} MB.": "", - "File Upload": "", - "File uploaded successfully": "", - "File uploaded!": "", - "Filename": "", + "File removed successfully.": "Fail telah dialihkan dengan berjaya.", + "File size should not exceed {{maxSize}} MB.": "Saiz fail tidak boleh melebihi {{maxSize}} MB.", + "File Upload": "Muat Naik Fail", + "File uploaded successfully": "Fail dimuat naik dengan berjaya", + "File uploaded!": "Fail dimuat naik!", + "Filename": "Nama fail", "Files": "Fail-Fail", - "Filter": "", + "Filter": "Penapis", "Filter is now globally disabled": "Tapisan kini dilumpuhkan secara global", "Filter is now globally enabled": "Tapisan kini dibenarkan secara global", "Filters": "Tapisan", "Fingerprint spoofing detected: Unable to use initials as avatar. Defaulting to default profile image.": "Peniruan cap jari dikesan, tidak dapat menggunakan nama pendek sebagai avatar. Lalai kepada imej profail asal", - "Firecrawl API Base URL": "", - "Firecrawl API Key": "", - "Firecrawl Timeout (s)": "", - "Floating Quick Actions": "", - "Focus Chat Input": "", - "Folder": "", - "Folder Background Image": "", - "Folder created successfully": "", - "Folder deleted successfully": "", - "Folder Max File Count": "", - "Folder name": "", - "Folder Name": "", - "Folder name cannot be empty.": "", - "Folder name updated successfully": "", - "Folder options": "", - "Folder updated successfully": "", - "Folders": "", - "Follow up": "", - "Follow Up Generation": "", - "Follow Up Generation Prompt": "", - "Follow up: {{question}}": "", - "Follow-Up Auto-Generation": "", + "Firecrawl API Base URL": "URL Asas API Firecrawl", + "Firecrawl API Key": "Kunci API Firecrawl", + "Firecrawl Timeout (s)": "Masa Tamat Firecrawl (s)", + "Floating Quick Actions": "Tindakan Pantas Terapung", + "Focus Chat Input": "Fokus Input Sembang", + "Folder": "Folder", + "Folder Background Image": "Imej Latar Belakang Folder", + "Folder created successfully": "Folder berjaya dibuat", + "Folder deleted successfully": "Folder berjaya dipadamkan", + "Folder Max File Count": "Bilangan Fail Maksimum Folder", + "Folder name": "Nama folder", + "Folder Name": "Nama Folder", + "Folder name cannot be empty.": "Nama folder tidak boleh kosong.", + "Folder name updated successfully": "Nama folder berjaya dikemas kini", + "Folder options": "Pilihan folder", + "Folder updated successfully": "Folder berjaya dikemas kini", + "Folders": "Folder-folder", + "Follow up": "Susulan", + "Follow Up Generation": "Penjanaan Susulan", + "Follow Up Generation Prompt": "Prompt Penjanaan Susulan", + "Follow up: {{question}}": "Susulan: {{question}}", + "Follow-Up Auto-Generation": "Auto-Penjanaan Susulan", "Followed instructions perfectly": "Mengikut arahan dengan sempurna", - "for placeholders": "", - "Force OCR": "", - "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", - "Forge new paths": "", + "for placeholders": "untuk pemegang tempat", + "Force OCR": "Paksa OCR", + "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "Paksa OCR pada semua halaman PDF. Ini boleh menghasilkan hasil yang lebih teruk jika anda mempunyai teks yang baik dalam PDF anda. Lalai kepada False.", + "Forge new paths": "Membuka jalan baru", "Form": "Borang", - "Format Lines": "", - "Format the lines in the output. Defaults to False. If set to True, the lines will be formatted to detect inline math and styles.": "", - "Formatting may be inconsistent from source.": "", - "Forwards system user OAuth access token to authenticate": "", - "Forwards system user session credentials to authenticate": "", - "Full Context Mode": "", - "Function": "", - "Function Calling": "", + "Format Lines": "Format Baris", + "Format the lines in the output. Defaults to False. If set to True, the lines will be formatted to detect inline math and styles.": "Format baris dalam output. Lalai kepada False. Jika ditetapkan kepada True, baris akan diformat untuk mengesan matematik sebaris dan gaya.", + "Formatting may be inconsistent from source.": "Pemformatan mungkin tidak konsisten dari sumber.", + "Forwards system user OAuth access token to authenticate": "Meneruskan token akses OAuth pengguna sistem untuk pengesahan", + "Forwards system user session credentials to authenticate": "Meneruskan bukti kelayakan sesi pengguna sistem untuk pengesahan", + "Full Context Mode": "Mod Konteks Penuh", + "Function": "Fungsi", + "Function Calling": "Pemanggilan Fungsi", "Function created successfully": "Fungsi berjaya dibuat", "Function deleted successfully": "Fungsi berjaya dipadamkan", - "Function Description": "", - "Function ID": "", - "Function imported successfully": "", + "Function Description": "Penerangan Fungsi", + "Function ID": "ID Fungsi", + "Function imported successfully": "Fungsi diimport dengan berjaya", "Function is now globally disabled": "Fungsi kini dilumpuhkan secara global", "Function is now globally enabled": "Fungsi kini dibenarkan secara global", - "Function Name": "", - "Function Name Filter List": "", + "Function Name": "Nama Fungsi", + "Function Name Filter List": "Senarai Penapis Nama Fungsi", "Function updated successfully": "Fungsi berjaya dikemaskini", "Functions": "Fungsi", "Functions allow arbitrary code execution.": "Fungsi membenarkan pelaksanaan kod sewenang-wenangnya.", "Functions imported successfully": "Fungsi berjaya diimport", - "Gemini": "", - "Gemini API Key": "", - "Gemini API Key is required.": "", - "Gemini Base URL": "", - "Gemini Endpoint Method": "", - "Gender": "", + "Gemini": "Gemini", + "Gemini API Key": "Kunci API Gemini", + "Gemini API Key is required.": "Kunci API Gemini diperlukan.", + "Gemini Base URL": "URL Asas Gemini", + "Gemini Endpoint Method": "Kaedah Titik Akhir Gemini", + "Gender": "Jantina", "General": "Umum", - "Generate": "", - "Generate an image": "", - "Generate and edit images": "", - "Generate Message Pair": "", - "Generated Image": "", - "Generated images will appear here": "", + "Generate": "Janakan", + "Generate an image": "Janakan imej", + "Generate and edit images": "Janakan dan edit imej", + "Generate Message Pair": "Janakan Pasangan Mesej", + "Generated Image": "Imej yang Dijana", + "Generated images will appear here": "Imej yang dijana akan muncul di sini", "Generating search query": "Jana pertanyaan carian", - "Generating...": "", - "Get current time and perform date/time calculations": "", - "Get information on {{name}} in the UI": "", - "Get started": "", - "Get started with {{WEBUI_NAME}}": "", + "Generating...": "Menjana...", + "Get current time and perform date/time calculations": "Dapatkan masa semasa dan lakukan pengiraan tarikh/masa", + "Get information on {{name}} in the UI": "Dapatkan maklumat tentang {{name}} dalam UI", + "Get started": "Mulai", + "Get started with {{WEBUI_NAME}}": "Mulai dengan {{WEBUI_NAME}}", "Global": "Global", "Good Response": "Respons Baik", - "Google": "", - "Google Drive": "", + "Google": "Google", + "Google Drive": "Google Drive", "Google PSE API Key": "Kunci API Google PSE", "Google PSE Engine Id": "ID Enjin Google PSE", - "Gravatar": "", - "Grid": "", - "Grokipedia": "", - "Group Channel": "", - "Group created successfully": "", - "Group deleted successfully": "", - "Group Description": "", - "Group Name": "", - "Group updated successfully": "", - "groups": "", - "Groups": "", - "H1": "", - "H2": "", - "H3": "", - "Haptic Feedback": "", - "Headers": "", - "Headers must be a valid JSON object": "", - "Height": "", + "Gravatar": "Gravatar", + "Grid": "Grid", + "Grokipedia": "Grokipedia", + "Group Channel": "Saluran Kumpulan", + "Group created successfully": "Kumpulan berjaya dibuat", + "Group deleted successfully": "Kumpulan berjaya dipadamkan", + "Group Description": "Penerangan Kumpulan", + "Group Name": "Nama Kumpulan", + "Group updated successfully": "Kumpulan berjaya dikemaskini", + "groups": "kumpulan", + "Groups": "Kumpulan", + "H1": "H1", + "H2": "H2", + "H3": "H3", + "Haptic Feedback": "Maklum Balas Haptic", + "Headers": "Tajuk", + "Headers must be a valid JSON object": "Tajuk mesti menjadi objek JSON yang sah", + "Height": "Ketinggian", "Hello, {{name}}": "Hello, {{name}}", "Help": "Bantuan", - "Help the community discover great models": "", - "Hex Color": "", - "Hex Color - Leave empty for default color": "", - "Hidden": "", + "Help the community discover great models": "Bantu komuniti menemui model-model hebat", + "Hex Color": "Warna Heks", + "Hex Color - Leave empty for default color": "Warna Heks - Biarkan kosong untuk warna lalai", + "Hidden": "Tersembunyi", "Hide": "Sembunyi", - "Hide All": "", - "Hide from Sidebar": "", - "Hide Model": "", - "High": "", - "High Contrast Mode": "", - "History": "", - "Home": "", - "Host": "", - "Hourly Messages": "", + "Hide All": "Sembunyikan Semua", + "Hide from Sidebar": "Sembunyikan daripada Sidebar", + "Hide Model": "Sembunyikan Model", + "High": "Tinggi", + "High Contrast Mode": "Mode Kontras Tinggi", + "History": "Sejarah", + "Home": "Halaman Utama", + "Host": "Hos", + "Hourly Messages": "Mesej Setiap Jam", "How can I help you today?": "Bagaimana saya boleh membantu anda hari ini?", - "How would you rate this response?": "", - "HTML": "", - "http://localhost:8000": "", - "https://mineru.net/api/v4": "", + "How would you rate this response?": "Bagaimana anda menilai respons ini?", + "HTML": "HTML", + "http://localhost:8000": "http://localhost:8000", + "https://mineru.net/api/v4": "https://mineru.net/api/v4", "Hybrid Search": "Carian Hibrid", "I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "Saya mengakui bahawa saya telah membaca dan saya memahami implikasi tindakan saya. Saya sedar tentang risiko yang berkaitan dengan melaksanakan kod sewenang-wenangnya dan saya telah mengesahkan kebolehpercayaan sumber tersebut.", - "ID": "", - "ID cannot contain \":\" or \"|\" characters": "", - "ID copied to clipboard": "", - "iframe Sandbox Allow Forms": "", - "iframe Sandbox Allow Same Origin": "", - "Ignite curiosity": "", - "Image": "", - "Image Compression": "", - "Image Compression Height": "", - "Image Compression Width": "", - "Image Edit": "", - "Image Edit Engine": "", - "Image Generation": "", + "ID": "ID", + "ID cannot contain \":\" or \"|\" characters": "ID tidak boleh mengandungi aksara \":\" atau \"|\"", + "ID copied to clipboard": "ID disalin ke papan kerja", + "iframe Sandbox Allow Forms": "iframe Sandbox Benarkan Borang", + "iframe Sandbox Allow Same Origin": "Benarkan Asal Sama untuk Sandbox iframe", + "Ignite curiosity": "Nyalakan rasa ingin tahu", + "Image": "Imej", + "Image Compression": "Mampatan Imej", + "Image Compression Height": "Tinggi Mampatan Imej", + "Image Compression Width": "Lebar Mampatan Imej", + "Image Edit": "Edit Imej", + "Image Edit Engine": "Enjin Edit Imej", + "Image Generation": "Penjanaan Imej", "Image Generation Engine": "Enjin Penjanaan Imej", - "Image Max Compression Size": "", - "Image Max Compression Size height": "", - "Image Max Compression Size width": "", - "Image Prompt Generation": "", - "Image Prompt Generation Prompt": "", - "Image Size": "", - "Images": "", - "Import": "", + "Image Max Compression Size": "Saiz Mampatan Imej Maksimum", + "Image Max Compression Size height": "Tinggi Saiz Mampatan Imej Maksimum", + "Image Max Compression Size width": "Lebar Saiz Mampatan Imej Maksimum", + "Image Prompt Generation": "Penjanaan Arahan Imej", + "Image Prompt Generation Prompt": "Arahan Penjanaan Imej", + "Image Size": "Saiz Imej", + "Images": "Imej", + "Import": "Import", "Import Chats": "Import Perbualan", - "Import Config": "", - "Import From Link": "", - "Import Models": "", - "Import Prompts": "", - "Import successful": "", - "Import Tools": "", + "Import Config": "Konfigurasi Import", + "Import From Link": "Import Dari Pautan", + "Import Models": "Import Model", + "Import Prompts": "Import Prompts", + "Import successful": "Import Berjaya", + "Import Tools": "Import Alat", "Important Update": "Kemas kini penting", - "Inactive": "", - "Include": "", + "Inactive": "Tidak Aktif", + "Include": "Sertakan", "Include `--api-auth` flag when running stable-diffusion-webui": "Sertakan bendera `-- api -auth` semasa menjalankan stable-diffusion-webui ", "Include `--api` flag when running stable-diffusion-webui": "Sertakan bendera `-- api ` semasa menjalankan stable-diffusion-webui", "Includes SharePoint": "Termasuk SharePoint", - "Increase UI Scale": "", - "Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive.": "", + "Increase UI Scale": "Tingkatkan Skala UI", + "Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive.": "Mempengaruhi seberapa cepat algoritma merespons umpan balik dari teks yang dihasilkan. Kadar pembelajaran yang lebih rendah akan menghasilkan penyesuaian yang lebih lambat, sementara kadar pembelajaran yang lebih tinggi akan membuat algoritma lebih responsif.", "Info": "Maklumat", - "Initials": "", - "Inject file content into conversation context": "", - "Inject the entire content as context for comprehensive processing, this is recommended for complex queries.": "", - "Input": "", - "Input Key (e.g. text, unet_name, steps)": "", - "Input Variables": "", - "Insert": "", - "Insert Follow-Up Prompt to Input": "", - "Insert Prompt as Rich Text": "", - "Insert Suggestion Prompt to Input": "", + "Initials": "Inisial", + "Inject file content into conversation context": "Suntikkan kandungan fail ke dalam konteks perbualan", + "Inject the entire content as context for comprehensive processing, this is recommended for complex queries.": "Suntikkan seluruh kandungan sebagai konteks untuk pemprosesan komprehensif, ini disyorkan untuk pertanyaan yang kompleks.", + "Input": "Input", + "Input Key (e.g. text, unet_name, steps)": "Kunci Input (cth: text, unet_name, steps)", + "Input Variables": "Pembolehubah Input", + "Insert": "Sisipkan", + "Insert Follow-Up Prompt to Input": "Sisipkan Arahan Susulan ke Input", + "Insert Prompt as Rich Text": "Sisipkan Arahan sebagai Teks Kaya", + "Insert Suggestion Prompt to Input": "Sisipkan Arahan Cadangan ke Input", "Install from Github URL": "Pasang daripada URL Github", "Instant Auto-Send After Voice Transcription": "Hantar Secara Automatik Dengan Segera Selepas Transkripsi Suara", - "Integration": "", - "Integrations": "", + "Integration": "Integrasi", + "Integrations": "Integrasi", "Interface": "Antaramuka", - "Interface Settings Access": "", - "Invalid file content": "", - "Invalid file format.": "", - "Invalid JSON file": "", - "Invalid JSON format for ComfyUI Edit Workflow.": "", - "Invalid JSON format for ComfyUI Workflow.": "", - "Invalid JSON format for Parameters": "", - "Invalid JSON format in {{NAME}}": "", - "Invalid JSON format in Additional Config": "", - "Invalid JSON format in MinerU Parameters": "", - "is typing...": "", - "Italic": "", + "Interface Settings Access": "Akses Tetapan Antara Muka", + "Invalid file content": "Kandungan fail tidak sah", + "Invalid file format.": "Format fail tidak sah.", + "Invalid JSON file": "Fail JSON tidak sah", + "Invalid JSON format for ComfyUI Edit Workflow.": "Format JSON tidak sah untuk ComfyUI Edit Workflow.", + "Invalid JSON format for ComfyUI Workflow.": "Format JSON tidak sah untuk ComfyUI Workflow.", + "Invalid JSON format for Parameters": "Format JSON tidak sah untuk Parameters", + "Invalid JSON format in {{NAME}}": "Format JSON tidak sah dalam {{NAME}}", + "Invalid JSON format in Additional Config": "Format JSON tidak sah dalam Additional Config", + "Invalid JSON format in MinerU Parameters": "Format JSON tidak sah dalam MinerU Parameters", + "is typing...": "sedang menaip...", + "Italic": "Miring", "January": "Januari", - "Jina API Base URL": "", - "Jina API Key": "", + "Jina API Base URL": "URL Asas API Jina", + "Jina API Key": "Kunci API Jina", "join our Discord for help.": "sertai Discord kami untuk mendapatkan bantuan.", "JSON": "JSON", "JSON Preview": "Pratonton JSON", - "JSON Spec": "", + "JSON Spec": "Spesifikasi JSON", "July": "Julai", "June": "Jun", - "Jupyter Auth": "", - "Jupyter URL": "", + "Jupyter Auth": "Pengesahan Jupyter", + "Jupyter URL": "URL Jupyter", "JWT Expiration": "Tempoh Tamat JWT", "JWT Token": "Token JWT", - "Kagi Search API Key": "", - "Keep Follow-Up Prompts in Chat": "", - "Keep in Sidebar": "", - "Key": "", - "Key is required": "", + "Kagi Search API Key": "Kunci API Pencarian Kagi", + "Keep Follow-Up Prompts in Chat": "Simpan Gesaran Susulan dalam Sembang", + "Keep in Sidebar": "Simpan dalam Bar Sisi", + "Key": "Kunci", + "Key is required": "Kunci diperlukan", "Keyboard shortcuts": "Pintasan papan kekunci", - "Keyboard Shortcuts": "", + "Keyboard Shortcuts": "Pintasan Papan Kekunci", "Knowledge": "Pengetahuan", - "Knowledge Access": "", - "Knowledge Base": "", - "Knowledge created successfully.": "", - "Knowledge deleted successfully.": "", - "Knowledge Description": "", - "Knowledge exported successfully": "", - "Knowledge Name": "", - "Knowledge Public Sharing": "", - "Knowledge reset successfully.": "", - "Knowledge Sharing": "", - "Knowledge updated successfully": "", - "Kokoro.js (Browser)": "", - "Kokoro.js Dtype": "", - "Label": "", - "Landing Page Mode": "", + "Knowledge Access": "Akses Pengetahuan", + "Knowledge Base": "Pangkalan Pengetahuan", + "Knowledge created successfully.": "Pengetahuan berjaya dibuat.", + "Knowledge deleted successfully.": "Pengetahuan berjaya dipadam.", + "Knowledge Description": "Penerangan Pengetahuan", + "Knowledge exported successfully": "Pengetahuan berjaya dieksport", + "Knowledge Name": "Nama Pengetahuan", + "Knowledge Public Sharing": "Perkongsian Awam Pengetahuan", + "Knowledge reset successfully.": "Pengetahuan telah direset dengan berjaya.", + "Knowledge Sharing": "Perkongsian Pengetahuan", + "Knowledge updated successfully": "Pengetahuan telah dikemas kini dengan berjaya", + "Kokoro.js (Browser)": "Kokoro.js (Penyemak Imbas)", + "Kokoro.js Dtype": "Kokoro.js Dtype", + "Label": "Label", + "Landing Page Mode": "Mod Halaman Pendaratan", "Language": "Bahasa", - "Language Locales": "", - "Last 24 hours": "", - "Last 30 days": "", - "Last 7 days": "", - "Last 90 days": "", + "Language Locales": "Lokalisasi Bahasa", + "Last 24 hours": "24 jam terakhir", + "Last 30 days": "30 hari terakhir", + "Last 7 days": "7 hari lepas", + "Last 90 days": "90 hari lepas", "Last Active": "Dilihat aktif terakhir pada", "Last Modified": "Kemaskini terakhir pada", - "Last reply": "", - "LDAP": "", - "LDAP server updated": "", - "Leaderboard": "", - "Learn more": "", - "Learn More": "", - "Learn more about Open Terminal": "", - "Learn more about OpenAPI tool servers.": "", - "Learn more about Voxtral transcription.": "", - "Leave a public review for {{modelName}}": "", - "Leave empty for no compression": "", - "Leave empty for unlimited": "", - "Leave empty to include all models from \"{{url}}\" endpoint": "", - "Leave empty to include all models from \"{{url}}/api/tags\" endpoint": "", - "Leave empty to include all models from \"{{url}}/models\" endpoint": "", - "Leave empty to include all models or select specific models": "", - "Leave empty to use first admin user": "", - "Leave empty to use the default config, or enter a valid json (see https://yandex.cloud/en/docs/search-api/api-ref/WebSearch/search#yandex.cloud.searchapi.v2.WebSearchRequest)": "", - "Leave empty to use the default model (voxtral-mini-latest).": "", - "Leave empty to use the default prompt, or enter a custom prompt": "", - "Leave model field empty to use the default model.": "", - "Legacy": "", - "lexical": "", - "License": "", - "Lift List": "", + "Last reply": "Balasan terakhir", + "LDAP": "LDAP", + "LDAP server updated": "Pelayan LDAP dikemas kini", + "Leaderboard": "Papan Kedudukan", + "Learn more": "Ketahui lebih lanjut", + "Learn More": "Ketahui Lebih Lanjut", + "Learn more about Open Terminal": "Ketahui lebih lanjut tentang Terminal Terbuka", + "Learn more about OpenAPI tool servers.": "Ketahui lebih lanjut tentang pelayan alat OpenAPI.", + "Learn more about Voxtral transcription.": "Ketahui lebih lanjut tentang transkripsi Voxtral.", + "Leave a public review for {{modelName}}": "Tinggalkan ulasan awam untuk {{modelName}}", + "Leave empty for no compression": "Biarkan kosong untuk tiada pemampatan", + "Leave empty for unlimited": "Biarkan kosong untuk tanpa had", + "Leave empty to include all models from \"{{url}}\" endpoint": "Biarkan kosong untuk memasukkan semua model dari endpoint \"{{url}}\"", + "Leave empty to include all models from \"{{url}}/api/tags\" endpoint": "Biarkan kosong untuk memasukkan semua model dari endpoint \"{{url}}/api/tags\"", + "Leave empty to include all models from \"{{url}}/models\" endpoint": "Biarkan kosong untuk memasukkan semua model dari endpoint \"{{url}}/models\"", + "Leave empty to include all models or select specific models": "Biarkan kosong untuk memasukkan semua model atau pilih model tertentu", + "Leave empty to use first admin user": "Biarkan kosong untuk menggunakan pengguna admin pertama", + "Leave empty to use the default config, or enter a valid json (see https://yandex.cloud/en/docs/search-api/api-ref/WebSearch/search#yandex.cloud.searchapi.v2.WebSearchRequest)": "Biarkan kosong untuk menggunakan konfigurasi lalai, atau masukkan json yang sah (lihat https://yandex.cloud/en/docs/search-api/api-ref/WebSearch/search#yandex.cloud.searchapi.v2.WebSearchRequest)", + "Leave empty to use the default model (voxtral-mini-latest).": "Biarkan kosong untuk menggunakan model lalai (voxtral-mini-latest).", + "Leave empty to use the default prompt, or enter a custom prompt": "Biarkan kosong untuk menggunakan prompt lalai, atau masukkan prompt tersuai", + "Leave model field empty to use the default model.": "Biarkan medan model kosong untuk menggunakan model lalai.", + "Legacy": "Warisan", + "lexical": "leksikal", + "License": "Lesen", + "Lift List": "Senarai Angkat", "Light": "Cerah", - "Limit concurrent search queries. 0 = unlimited (default). Set to 1 for sequential execution (recommended for APIs with strict rate limits like Brave free tier).": "", - "Limits the number of concurrent embedding requests. Set to 0 for unlimited.": "", - "List": "", + "Limit concurrent search queries. 0 = unlimited (default). Set to 1 for sequential execution (recommended for APIs with strict rate limits like Brave free tier).": "Hadkan pertanyaan carian serentak. 0 = tanpa had (lalai). Tetapkan kepada 1 untuk pelaksanaan berurutan (disyorkan untuk API dengan had kadar ketat seperti peringkat percuma Brave).", + "Limits the number of concurrent embedding requests. Set to 0 for unlimited.": "Mengehadkan jumlah permintaan pembenaman serentak. Tetapkan kepada 0 untuk tanpa had.", + "List": "Senarai", "Listening...": "Mendengar...", - "Live": "", - "Llama.cpp": "", + "Live": "Langsung", + "Llama.cpp": "Llama.cpp", "LLMs can make mistakes. Verify important information.": "LLM boleh membuat kesilapan. Sahkan maklumat penting", - "Loader": "", - "Loading Kokoro.js...": "", + "Loader": "Pemuat", + "Loading Kokoro.js...": "Memuatkan Kokoro.js...", "Loading...": "Memuatkan...", - "local": "", - "Local": "", - "Local Task Model": "", - "Location access not allowed": "", - "Lost": "", - "Low": "", + "local": "tempatan", + "Local": "Tempatan", + "Local Task Model": "Model Tugas Tempatan", + "Location access not allowed": "Akses lokasi tidak dibenarkan", + "Lost": "Hilang", + "Low": "Rendah", "LTR": "LTR", "Made by Open WebUI Community": "Dicipta oleh Komuniti OpenWebUI", - "Make password visible in the user interface": "", - "Make sure to export a workflow.json file as API format from ComfyUI.": "", - "Male": "", + "Make password visible in the user interface": "Buat kata laluan kelihatan dalam antara muka pengguna", + "Make sure to export a workflow.json file as API format from ComfyUI.": "Pastikan untuk mengeksport fail workflow.json sebagai format API daripada ComfyUI.", + "Male": "Lelaki", "Manage": "Urus", - "Manage Connections": "", - "Manage Direct Connections": "", - "Manage Files": "", - "Manage Models": "", - "Manage Ollama": "", - "Manage Ollama API Connections": "", - "Manage OpenAI API Connections": "", + "Manage Connections": "Urus Sambungan", + "Manage Direct Connections": "Urus Sambungan Langsung", + "Manage Files": "Urus Fail", + "Manage Models": "Urus Model", + "Manage Ollama": "Urus Ollama", + "Manage Ollama API Connections": "Urus Sambungan API Ollama", + "Manage OpenAI API Connections": "Urus Sambungan API OpenAI", "Manage Pipelines": "Urus 'Pipelines'", - "Manage Tool Servers": "", - "Manage your account information.": "", + "Manage Tool Servers": "Kelola Pelayan Alat", + "Manage your account information.": "Kelola maklumat akaun anda.", "March": "Mac", - "Markdown": "", - "Markdown Header Text Splitter": "", - "Max Speakers": "", - "Max Upload Count": "", - "Max Upload Size": "", - "Maximum number of files allowed per folder.": "", - "Maximum number of files per folder is {{max}}.": "", + "Markdown": "Markdown", + "Markdown Header Text Splitter": "Pemisah Teks Tajuk Markdown", + "Max Speakers": "Pembicara Maksimum", + "Max Upload Count": "Bilangan Muat Naik Maksimum", + "Max Upload Size": "Saiz Muat Naik Maksimum", + "Maximum number of files allowed per folder.": "Bilangan maksimum fail yang dibenarkan setiap folder.", + "Maximum number of files per folder is {{max}}.": "Bilangan maksimum fail setiap folder ialah {{max}}.", "Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maksimum 3 model boleh dimuat turun serentak. Sila cuba sebentar lagi.", "May": "Mei", - "MBR": "", - "MCP": "", - "MCP support is experimental and its specification changes often, which can lead to incompatibilities. OpenAPI specification support is directly maintained by the Open WebUI team, making it the more reliable option for compatibility.": "", - "Medium": "", - "Member removed successfully": "", - "members": "", - "Members": "", - "Members added successfully": "", - "Memories": "", + "MBR": "MBR", + "MCP": "MCP", + "MCP support is experimental and its specification changes often, which can lead to incompatibilities. OpenAPI specification support is directly maintained by the Open WebUI team, making it the more reliable option for compatibility.": "Sokongan MCP adalah eksperimental dan spesifikasinya kerap berubah, yang boleh menyebabkan ketidakserasian. Sokongan spesifikasi OpenAPI dikekalkan secara langsung oleh pasukan Open WebUI, menjadikannya pilihan yang lebih boleh dipercayai untuk keserasian.", + "Medium": "Sederhana", + "Member removed successfully": "Ahli telah dikeluarkan dengan berjaya", + "members": "ahli", + "Members": "Ahli", + "Members added successfully": "Ahli telah ditambah dengan berjaya", + "Memories": "Ingatan", "Memories accessible by LLMs will be shown here.": "Memori yang boleh diakses oleh LLM akan ditunjukkan di sini.", "Memory": "Memori", "Memory added successfully": "Memori berjaya ditambah", "Memory cleared successfully": "Memori berjaya dikosongkan", "Memory deleted successfully": "Memori berjaya dihapuskan", "Memory updated successfully": "Memori berjaya dikemaskini", - "Merge Responses": "", + "Merge Responses": "Gabungkan Respons", "Merged Response": "Respons Digabungkan", - "Message": "", - "Message counts and response timestamps": "", - "Message counts are based on assistant responses.": "", - "Message rating should be enabled to use this feature": "", - "messages": "", - "Messages": "", + "Message": "Mesej", + "Message counts and response timestamps": "Kiraan mesej dan cap masa respons", + "Message counts are based on assistant responses.": "Kiraan mesej adalah berdasarkan respons pembantu.", + "Message rating should be enabled to use this feature": "Penilaian mesej mesti didayakan untuk menggunakan ciri ini", + "messages": "mesej", + "Messages": "Mesej", "Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "Mesej yang anda hantar selepas membuat pautan anda tidak akan dikongsi. Pengguna dengan URL akan dapat melihat perbualan yang dikongsi.", - "Microsoft OneDrive": "", - "Microsoft OneDrive (personal)": "", - "Microsoft OneDrive (work/school)": "", - "MinerU": "", - "MinerU API Key required for Cloud API mode.": "", - "Mistral OCR": "", - "Mistral OCR API Key required.": "", - "MistralAI": "", - "Model": "", + "Microsoft OneDrive": "Microsoft OneDrive", + "Microsoft OneDrive (personal)": "Microsoft OneDrive (peribadi)", + "Microsoft OneDrive (work/school)": "Microsoft OneDrive (kerja/sekolah)", + "MinerU": "MinerU", + "MinerU API Key required for Cloud API mode.": "Kunci API MinerU diperlukan untuk mod Cloud API.", + "Mistral OCR": "Mistral OCR", + "Mistral OCR API Key required.": "Kunci API Mistral OCR diperlukan.", + "MistralAI": "MistralAI", + "Model": "Model", "Model '{{modelName}}' has been successfully downloaded.": "Model '{{ modelName }}' telah berjaya dimuat turun.", "Model '{{modelTag}}' is already in queue for downloading.": "Model '{{ modelTag }}' sudah dalam baris gilir untuk dimuat turun.", "Model {{modelId}} not found": "Model {{ modelId }} tidak dijumpai", "Model {{modelName}} is not vision capable": "Model {{ modelName }} tidak mempunyai keupayaan penglihatan", "Model {{name}} is now {{status}}": "Model {{name}} kini {{status}}", - "Model {{name}} is now hidden": "", - "Model {{name}} is now visible": "", - "Model accepts file inputs": "", - "Model accepts image inputs": "", - "Model can execute code and perform calculations": "", - "Model can generate images based on text prompts": "", - "Model can search the web for information": "", - "Model Capabilities": "", + "Model {{name}} is now hidden": "Model {{name}} kini tersembunyi", + "Model {{name}} is now visible": "Model {{name}} kini dapat dilihat", + "Model accepts file inputs": "Model menerima input fail", + "Model accepts image inputs": "Model menerima input imej", + "Model can execute code and perform calculations": "Model dapat melaksanakan kod dan melakukan pengiraan", + "Model can generate images based on text prompts": "Model dapat menjana imej berdasarkan gesaran teks", + "Model can search the web for information": "Model boleh mencari web untuk maklumat", + "Model Capabilities": "Keupayaan Model", "Model created successfully!": "Model berjaya dibuat!", "Model filesystem path detected. Model shortname is required for update, cannot continue.": "Laluan sistem fail model dikesan. Nama pendek model diperlukan untuk kemas kini, tidak boleh diteruskan.", - "Model Filtering": "", + "Model Filtering": "Penapis Model", "Model ID": "ID Model", - "Model ID is required.": "", - "Model IDs": "", - "Model Name": "", - "Model name already exists, please choose a different one": "", - "Model Name is required.": "", - "Model names and usage frequency": "", - "Model not found": "", + "Model ID is required.": "ID Model diperlukan.", + "Model IDs": "ID Model", + "Model Name": "Nama Model", + "Model name already exists, please choose a different one": "Nama model sudah wujud, sila pilih yang lain", + "Model Name is required.": "Nama Model diperlukan.", + "Model names and usage frequency": "Nama model dan frekuensi penggunaan", + "Model not found": "Model tidak dijumpai", "Model not selected": "Model tidak dipilih", - "Model Parameters": "", + "Model Parameters": "Parameter Model", "Model Params": "Model Params", - "Model Permissions": "", - "Model responses or outputs": "", - "Model unloaded successfully": "", + "Model Permissions": "Kebenaran Model", + "Model responses or outputs": "Respons atau output model", + "Model unloaded successfully": "Model dimuat keluar dengan berjaya", "Model updated successfully": "Model berjaya dikemas kini", - "Model Usage": "", - "Model(s) do not support file upload": "", + "Model Usage": "Penggunaan Model", + "Model(s) do not support file upload": "Model tidak menyokong muat naik fail", "Modelfile Content": "Kandungan Modelfail", "Models": "Model", - "Models Access": "", - "Models configuration saved successfully": "", - "Models imported successfully": "", - "Models Public Sharing": "", - "Models Sharing": "", - "Mojeek": "", - "Mojeek Search API Key": "", + "Models Access": "Akses Model", + "Models configuration saved successfully": "Konfigurasi model disimpan dengan berjaya", + "Models imported successfully": "Model diimport dengan berjaya", + "Models Public Sharing": "Perkongsian Awam Model", + "Models Sharing": "Perkongsian Model", + "Mojeek": "Mojeek", + "Mojeek Search API Key": "Kunci API Pencarian Mojeek", "More": "Lagi", - "More Concise": "", - "More options": "", - "More Options": "", - "Move": "", - "Moved {{name}}": "", - "My Terminal": "", + "More Concise": "Lebih Ringkas", + "More options": "Lebih banyak pilihan", + "More Options": "Pilihan Lanjutan", + "Move": "Pindah", + "Moved {{name}}": "{{name}} telah dipindahkan", + "My Terminal": "Terminal Saya", "Name": "Nama", - "Name and ID are required, please fill them out": "", - "Name your knowledge base": "", - "Native": "", - "New": "", - "New Button": "", + "Name and ID are required, please fill them out": "Nama dan ID diperlukan, sila isi semuanya", + "Name your knowledge base": "Namakan pangkalan pengetahuan anda", + "Native": "Asli", + "New": "Baru", + "New Button": "Butang Baru", "New Chat": "Perbualan Baru", - "New File": "", - "New Folder": "", - "New Function": "", - "New Group": "", - "New Knowledge": "", - "New Model": "", - "New Note": "", + "New File": "Fail Baru", + "New Folder": "Folder Baru", + "New Function": "Fungsi Baru", + "New Group": "Kumpulan Baru", + "New Knowledge": "Pengetahuan Baru", + "New Model": "Model Baru", + "New Note": "Nota Baru", "New Password": "Kata Laluan Baru", - "New Prompt": "", - "New Skill": "", - "New Temporary Chat": "", - "New Terminal": "", - "New Tool": "", - "New Webhook": "", - "new-channel": "", - "Next message": "", - "No access grants. Private to you.": "", - "No activity data": "", - "No authentication": "", - "No chats found": "", - "No chats found for this user.": "", - "No chats found.": "", - "No content": "", - "No content found": "", + "New Prompt": "Prompt Baru", + "New Skill": "Kemahiran Baru", + "New Temporary Chat": "Obrolan Sementara Baru", + "New Terminal": "Terminal Baru", + "New Tool": "Alat Baru", + "New Webhook": "Webhook Baru", + "new-channel": "saluran-baru", + "Next message": "Mesej Seterusnya", + "No access grants. Private to you.": "Tiada geran akses. Peribadi untuk anda.", + "No activity data": "Tiada data aktiviti", + "No authentication": "Tiada pengesahan", + "No chats found": "Tiada sembang ditemui", + "No chats found for this user.": "Tiada sembang ditemui untuk pengguna ini.", + "No chats found.": "Tiada sembang ditemui.", + "No content": "Tiada kandungan", + "No content found": "Tiada kandungan ditemui", "No content to speak": "Tiada kandungan untuk bercakap", - "No conversation to save": "", - "No data": "", - "No data found": "", - "No distance available": "", - "No expiration can pose security risks.": "", - "No feedback found": "", + "No conversation to save": "Tiada perbualan untuk disimpan", + "No data": "Tiada data", + "No data found": "Tiada data ditemui", + "No distance available": "Tiada jarak tersedia", + "No expiration can pose security risks.": "Tiada tamat tempoh boleh menimbulkan risiko keselamatan.", + "No feedback found": "Tiada maklum balas ditemui", "No file selected": "Tiada fail dipilih", - "No files found": "", - "No files in this knowledge base.": "", - "No files yet. Upload files or run Python code to create them.": "", - "No functions found": "", - "No groups found": "", - "No history available": "", - "No HTML, CSS, or JavaScript content found.": "", - "No inference engine with management support found": "", - "No kernel": "", - "No knowledge bases found.": "", - "No knowledge found": "", - "No memories to clear": "", - "No model IDs": "", - "No models available": "", - "No models found": "", - "No models selected": "", - "No Notes": "", - "No notes found": "", - "No one": "", - "No pinned messages": "", - "No prompts found": "", + "No files found": "Tiada fail ditemui", + "No files in this knowledge base.": "Tiada fail dalam pangkalan pengetahuan ini.", + "No files yet. Upload files or run Python code to create them.": "Tiada fail lagi. Muat naik fail atau jalankan kod Python untuk menciptanya.", + "No functions found": "Tiada fungsi ditemui", + "No groups found": "Tiada kumpulan ditemui", + "No history available": "Tiada sejarah tersedia", + "No HTML, CSS, or JavaScript content found.": "Tiada kandungan HTML, CSS, atau JavaScript ditemui.", + "No inference engine with management support found": "Tiada enjin inferens dengan sokongan pengurusan ditemui", + "No kernel": "Tiada kernel", + "No knowledge bases found.": "Tiada pangkalan pengetahuan ditemui.", + "No knowledge found": "Tiada pengetahuan ditemui", + "No memories to clear": "Tiada ingatan untuk dipadam", + "No model IDs": "Tiada ID model", + "No models available": "Tiada model tersedia", + "No models found": "Tiada model ditemui", + "No models selected": "Tiada model dipilih", + "No Notes": "Tiada Nota", + "No notes found": "Tiada nota ditemui", + "No one": "Tiada sesiapa", + "No pinned messages": "Tiada mesej disematkan", + "No prompts found": "Tiada prompt ditemui", "No results": "Tiada keputusan dijumpai", "No results found": "Tiada keputusan dijumpai", "No search query generated": "Tiada pertanyaan carian dijana", - "No servers detected": "", - "No skills found": "", + "No servers detected": "Tiada pelayan dikesan", + "No skills found": "Tiada kemahiran ditemui", "No source available": "Tiada sumber tersedia", - "No sources found": "", + "No sources found": "Tiada sumber ditemui", "No suggestion prompts": "Tiada prompt cadangan", - "No Terminal connection configured.": "", - "No terminal connections configured.": "", - "No tool server connections configured.": "", - "No tools found": "", - "No users were found.": "", - "No valves": "", + "No Terminal connection configured.": "Tiada sambungan Terminal dikonfigurasi.", + "No terminal connections configured.": "Tiada sambungan terminal dikonfigurasi.", + "No tool server connections configured.": "Tiada sambungan pelayan alat dikonfigurasi.", + "No tools found": "Tiada alat ditemui", + "No users were found.": "Tiada pengguna ditemui.", + "No valves": "Tiada injap", "No valves to update": "Tiada 'valve' untuk dikemas kini", - "No webhooks yet": "", - "Node Ids": "", + "No webhooks yet": "Tiada webhook lagi", + "Node Ids": "Id Nod", "None": "Tiada", "Not factually correct": "Tidak tepat secara fakta", - "Not helpful": "", - "Not Registered": "", - "Note": "", - "Note deleted successfully": "", + "Not helpful": "Tidak berguna", + "Not Registered": "Tidak Didaftar", + "Note": "Nota", + "Note deleted successfully": "Nota telah dipadamkan dengan berjaya", "Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "Nota: Jika anda menetapkan skor minimum, carian hanya akan mengembalikan dokumen dengan skor lebih besar daripada atau sama dengan skor minimum.", - "Notes": "", - "Notes Public Sharing": "", - "Notes Sharing": "", - "Notification Sound": "", - "Notification Webhook": "", + "Notes": "Nota-nota", + "Notes Public Sharing": "Perkongsian Awam Nota", + "Notes Sharing": "Perkongsian Nota", + "Notification Sound": "Bunyi Pemberitahuan", + "Notification Webhook": "Webhook Pemberitahuan", "Notifications": "Pemberitahuan", "November": "November", - "OAuth": "", - "OAuth 2.1": "", + "OAuth": "OAuth", + "OAuth 2.1": "OAuth 2.1", "OAuth ID": "ID OAuth", "October": "Oktober", "Off": "Mati", @@ -1367,777 +1367,777 @@ "OLED Dark": "OLED Gelap", "Ollama": "Ollama", "Ollama API": "API Ollama", - "Ollama API settings updated": "", - "Ollama Cloud API Key": "", + "Ollama API settings updated": "Tetapan API Ollama dikemas kini", + "Ollama Cloud API Key": "Kunci API Ollama Cloud", "Ollama Version": "Versi Ollama", "On": "Hidup", - "OneDrive": "", - "Only active when \"Paste Large Text as File\" setting is toggled on.": "", - "Only active when the chat input is in focus and an LLM is generating a response.": "", - "Only active when the chat input is in focus.": "", - "Only alphanumeric characters and hyphens are allowed": "", + "OneDrive": "OneDrive", + "Only active when \"Paste Large Text as File\" setting is toggled on.": "Hanya aktif apabila tetapan \"Tampal Teks Besar sebagai Fail\" dihidupkan.", + "Only active when the chat input is in focus and an LLM is generating a response.": "Hanya aktif apabila input sembang berada dalam fokus dan LLM sedang menjana respons.", + "Only active when the chat input is in focus.": "Hanya aktif apabila input sembang berada dalam fokus.", + "Only alphanumeric characters and hyphens are allowed": "Hanya aksara alfanumerik dan tanda hubung dibenarkan", "Only alphanumeric characters and hyphens are allowed in the command string.": "Hanya aksara alfanumerik dan sempang dibenarkan dalam rentetan arahan.", - "Only can be triggered when the chat input is in focus.": "", - "Only collections can be edited, create a new knowledge base to edit/add documents.": "", - "Only invited users can access": "", - "Only markdown files are allowed": "", - "Only select users and groups with permission can access": "", - "Only sync new/updated chats": "", + "Only can be triggered when the chat input is in focus.": "Hanya boleh dicetuskan apabila input sembang berada dalam fokus.", + "Only collections can be edited, create a new knowledge base to edit/add documents.": "Hanya koleksi yang boleh disunting, buat pangkalan pengetahuan baru untuk menyunting/menambah dokumen.", + "Only invited users can access": "Hanya pengguna yang dijemput boleh mengakses", + "Only markdown files are allowed": "Hanya fail markdown dibenarkan", + "Only select users and groups with permission can access": "Hanya pengguna dan kumpulan terpilih dengan kebenaran boleh mengakses", + "Only sync new/updated chats": "Hanya segerak sembang baharu/terkini", "Oops! Looks like the URL is invalid. Please double-check and try again.": "Maaf, didapati URL tidak sah. Sila semak semula dan cuba lagi.", - "Oops! There are files still uploading. Please wait for the upload to complete.": "", - "Oops! There was an error in the previous response.": "", + "Oops! There are files still uploading. Please wait for the upload to complete.": "Aduh! Masih ada fail sedang dimuat naik. Sila tunggu sehingga muatan selesai.", + "Oops! There was an error in the previous response.": "Oops! Ada ralat dalam respons sebelumnya.", "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Maaf, Anda menggunakan kaedah yang tidak disokong (bahagian 'frontend' sahaja). Sila sediakan WebUI dari 'backend'.", - "Open file": "", - "Open in full screen": "", - "Open link": "", - "Open modal to configure connection": "", - "Open Modal To Manage Floating Quick Actions": "", - "Open Modal To Manage Image Compression": "", - "Open Model Selector": "", - "Open Settings": "", - "Open Sidebar": "", - "Open Terminal": "", - "Open User Profile Menu": "", - "Open WebUI can use tools provided by any OpenAPI server.": "", - "Open WebUI uses faster-whisper internally.": "", - "Open WebUI uses SpeechT5 and CMU Arctic speaker embeddings.": "", - "Open WebUI version": "", + "Open file": "Buka fail", + "Open in full screen": "Buka dalam skrin penuh", + "Open link": "Buka pautan", + "Open modal to configure connection": "Buka modal untuk mengkonfigurasi sambungan", + "Open Modal To Manage Floating Quick Actions": "Buka Modal Untuk Menguruskan Tindakan Pantas Terapung", + "Open Modal To Manage Image Compression": "Buka Modal Untuk Menguruskan Pemampatan Imej", + "Open Model Selector": "Buka Pemilih Model", + "Open Settings": "Buka Tetapan", + "Open Sidebar": "Buka Bar Sisi", + "Open Terminal": "Buka Terminal", + "Open User Profile Menu": "Buka Menu Profil Pengguna", + "Open WebUI can use tools provided by any OpenAPI server.": "Open WebUI boleh menggunakan alat yang disediakan oleh mana-mana pelayan OpenAPI.", + "Open WebUI uses faster-whisper internally.": "Open WebUI menggunakan faster-whisper secara dalaman.", + "Open WebUI uses SpeechT5 and CMU Arctic speaker embeddings.": "Open WebUI menggunakan SpeechT5 dan pembenaman pembicara CMU Arctic.", + "Open WebUI version": "Versi Open WebUI", "Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "Open WebUI version (v{{OPEN_WEBUI_VERSION}}) adalah lebih rendah daripada versi yang diperlukan iaitu (v{{REQUIRED_VERSION}})", "OpenAI": "OpenAI", "OpenAI API": "API OpenAI", - "OpenAI API Base URL": "", - "OpenAI API Key": "", + "OpenAI API Base URL": "URL Asas API OpenAI", + "OpenAI API Key": "Kunci API OpenAI", "OpenAI API Key is required.": "Kekunci API OpenAI diperlukan", - "OpenAI API settings updated": "", - "OpenAI API Version": "", + "OpenAI API settings updated": "Tetapan API OpenAI telah dikemas kini", + "OpenAI API Version": "Versi API OpenAI", "OpenAI URL/Key required.": "URL/Kekunci OpenAI diperlukan", - "OpenAPI": "", - "OpenAPI Spec": "", - "openapi.json URL or Path": "", - "optional": "", - "Optional": "", + "OpenAPI": "OpenAPI", + "OpenAPI Spec": "Spesifikasi OpenAPI", + "openapi.json URL or Path": "URL atau Laluan openapi.json", + "optional": "pilihan", + "Optional": "Pilihan", "or": "atau", - "Ordered List": "", + "Ordered List": "Senarai Tertib", "Other": "Lain-lain", - "Output": "", - "OUTPUT": "", - "Output format": "", - "Output Format": "", - "Overview": "", - "page": "", - "Page": "", - "Page mode creates one document per page. Single mode combines all pages into one document for better chunking across page boundaries.": "", - "Paginate": "", - "Parameters": "", - "Parent message not found": "", - "Participate in community leaderboards and evaluations! Syncing aggregated usage stats helps drive research and improvements to Open WebUI. Your privacy is paramount: no message content is ever shared.": "", + "Output": "Output", + "OUTPUT": "OUTPUT", + "Output format": "Format output", + "Output Format": "Format Output", + "Overview": "Gambaran Keseluruhan", + "page": "halaman", + "Page": "Halaman", + "Page mode creates one document per page. Single mode combines all pages into one document for better chunking across page boundaries.": "Mode Halaman membuat satu dokumen per halaman. Mode Tunggal menggabungkan semua halaman ke dalam satu dokumen untuk chunking yang lebih baik merentas sempadan halaman.", + "Paginate": "Pagina", + "Parameters": "Parameter", + "Parent message not found": "Mesej induk tidak ditemui", + "Participate in community leaderboards and evaluations! Syncing aggregated usage stats helps drive research and improvements to Open WebUI. Your privacy is paramount: no message content is ever shared.": "Sertai papan kedudukan komuniti dan penilaian! Menyegerakkan statistik penggunaan yang diagregat membantu mendorong penyelidikan dan penambahbaikan kepada Open WebUI. Privasi anda adalah yang terpenting: kandungan mesej tidak pernah dikongsi.", "Password": "Kata Laluan", - "Passwords do not match.": "", - "Paste Large Text as File": "", + "Passwords do not match.": "Kata laluan tidak sepadan.", + "Paste Large Text as File": "Tampal Teks Besar sebagai Fail", "PDF document (.pdf)": "Dokumen PDF (.pdf)", "PDF Extract Images (OCR)": "Imej Ekstrak PDF (OCR)", - "PDF Loader Mode": "", + "PDF Loader Mode": "Mode Pemuat PDF", "pending": "tertunda", - "Pending": "", - "Pending User Overlay Content": "", - "Pending User Overlay Title": "", + "Pending": "Tertunda", + "Pending User Overlay Content": "Kandungan Lapisan Pengguna Tertunda", + "Pending User Overlay Title": "Tajuk Lapisan Pengguna Tertunda", "Permission denied when accessing media devices": "Tidak mendapat kebenaran apabila cuba mengakses peranti media", "Permission denied when accessing microphone": "Tidak mendapat kebenaran apabila cuba mengakses mikrofon", "Permission denied when accessing microphone: {{error}}": "Tidak mendapat kebenaran apabila cuba mengakses mikrofon: {{error}}", - "Permissions": "", - "Perplexity API Key": "", - "Perplexity Model": "", - "Perplexity Search API URL": "", - "Perplexity Search Context Usage": "", + "Permissions": "Kebenaran", + "Perplexity API Key": "Kunci API Perplexity", + "Perplexity Model": "Model Perplexity", + "Perplexity Search API URL": "URL API Pencarian Perplexity", + "Perplexity Search Context Usage": "Penggunaan Konteks Pencarian Perplexity", "Personalization": "Personalisasi", "Pin": "Pin", "Pinned": "Disemat", - "Pinned Messages": "", - "Pinned Models": "", - "Pioneer insights": "", - "Pipe": "", + "Pinned Messages": "Mesej Disematkan", + "Pinned Models": "Model Tersapu", + "Pioneer insights": "Panduan Pelopor", + "Pipe": "Saluran", "Pipeline deleted successfully": "'Pipeline' berjaya dipadam", "Pipeline downloaded successfully": "'Pipeline' berjaya dimuat turun", - "Pipelines": "", + "Pipelines": "Saluran Paip", "Pipelines are a plugin system with arbitrary code execution —": "Pipelines ialah sistem pemalam dengan pelaksanaan kod sewenang‑wenangnya —", "Pipelines Not Detected": "'Pipeline' tidak ditemui", "Pipelines Valves": "'Pipeline Valves'", - "Plain text (.md)": "", + "Plain text (.md)": "Teks Biasa (.md)", "Plain text (.txt)": "Teks biasa (.txt)", "Playground": "Taman Permainan", - "Playwright Timeout (ms)": "", - "Playwright WebSocket URL": "", + "Playwright Timeout (ms)": "Masa Tamat Playwright (ms)", + "Playwright WebSocket URL": "URL WebSocket Playwright", "Please carefully review the following warnings:": "Sila semak dengan teliti amaran berikut:", - "Please do not close the settings page while loading the model.": "", - "Please enter a message or attach a file.": "", - "Please enter a prompt": "", - "Please enter a valid ID": "", - "Please enter a valid JSON spec": "", - "Please enter a valid path": "", - "Please enter a valid URL": "", - "Please enter a valid URL.": "", - "Please fill in all fields.": "", - "Please register the OAuth client": "", - "Please save the connection to persist the OAuth client information and do not change the ID": "", - "Please select a model first.": "", - "Please select a model.": "", - "Please select a reason": "", - "Please select a valid JSON file": "", - "Please select at least one user for Direct Message channel.": "", - "Please wait until all files are uploaded.": "", - "Port": "", - "Ports": "", + "Please do not close the settings page while loading the model.": "Sila jangan tutup halaman tetapan semasa memuat model.", + "Please enter a message or attach a file.": "Sila masukkan mesej atau lampirkan fail.", + "Please enter a prompt": "Sila masukkan arahan", + "Please enter a valid ID": "Sila masukkan ID yang sah", + "Please enter a valid JSON spec": "Sila masukkan spesifikasi JSON yang sah", + "Please enter a valid path": "Sila masukkan laluan yang sah", + "Please enter a valid URL": "Sila masukkan URL yang sah", + "Please enter a valid URL.": "Sila masukkan URL yang sah.", + "Please fill in all fields.": "Sila isi semua medan.", + "Please register the OAuth client": "Sila daftarkan klien OAuth", + "Please save the connection to persist the OAuth client information and do not change the ID": "Sila simpan sambungan untuk mengekalkan maklumat klien OAuth dan jangan ubah ID", + "Please select a model first.": "Sila pilih model terlebih dahulu.", + "Please select a model.": "Sila pilih model.", + "Please select a reason": "Sila pilih satu sebab", + "Please select a valid JSON file": "Sila pilih fail JSON yang sah", + "Please select at least one user for Direct Message channel.": "Sila pilih sekurang-kurangnya satu pengguna untuk saluran Direct Message.", + "Please wait until all files are uploaded.": "Sila tunggu sehingga semua fail dimuat naik.", + "Port": "Port", + "Ports": "Port", "Positive attitude": "Sikap positif", - "Prefer not to say": "", - "Prefix ID": "", - "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", - "Prevent File Creation": "", - "Preview": "", + "Prefer not to say": "Lebih suka tidak menjawab", + "Prefix ID": "ID Awalan", + "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "ID Awalan digunakan untuk mengelakkan konflik dengan sambungan lain dengan menambah awalan pada ID model - biarkan kosong untuk melumpuhkan", + "Prevent File Creation": "Cegah Penciptaan Fail", + "Preview": "Pratonton", "Previous 30 days": "30 hari sebelumnya", "Previous 7 days": "7 hari sebelumnya", - "Previous message": "", - "Private": "", - "Private conversation between selected users": "", - "Production version updated": "", + "Previous message": "Mesej sebelumnya", + "Private": "Peribadi", + "Private conversation between selected users": "Perbualan peribadi antara pengguna terpilih", + "Production version updated": "Versi pengeluaran dikemas kini", "Profile": "Profil", - "Prompt": "", - "Prompt Autocompletion": "", - "Prompt Content": "Kandungan Gesaan", - "Prompt created successfully": "", - "Prompt Name": "", - "Prompt Suggestions": "", - "Prompt updated successfully": "", - "Prompts": "Gesaan", - "Prompts Access": "", - "Prompts Public Sharing": "", - "Prompts Sharing": "", - "Provider Type": "", - "Public": "", + "Prompt": "Arahan", + "Prompt Autocompletion": "Auto lengkapkan Arahan", + "Prompt Content": "Kandungan arahan", + "Prompt created successfully": "Arahan berjaya dibuat", + "Prompt Name": "Nama Arahan", + "Prompt Suggestions": "Cadangan Arahan", + "Prompt updated successfully": "Arahan dikemas kini dengan berjaya", + "Prompts": "arahan", + "Prompts Access": "Akses Arahan", + "Prompts Public Sharing": "Arahan Perkongsian Awam", + "Prompts Sharing": "Perkongsian Arahan", + "Provider Type": "Jenis Penyedia", + "Public": "Awam", "Pull \"{{searchValue}}\" from Ollama.com": "Tarik \"{{ searchValue }}\" daripada Ollama.com", "Pull a model from Ollama.com": "Tarik model dari Ollama.com", - "Pull Model": "", - "Pyodide file browser": "", - "Query Generation Prompt": "", - "Querying": "", - "Quick Actions": "", + "Pull Model": "Model Tarik", + "Pyodide file browser": "Pelayar fail Pyodide", + "Query Generation Prompt": "Prompt Penjanaan Pertanyaan", + "Querying": "Sedang Membuat Pertanyaan", + "Quick Actions": "Tindakan Pantas", "RAG Template": "Templat RAG", - "Rate {{rating}} out of 10": "", - "Rating": "", - "Re-rank models by topic similarity": "", - "Read": "", + "Rate {{rating}} out of 10": "Kadar {{rating}} daripada 10", + "Rating": "Penilaian", + "Re-rank models by topic similarity": "Susun semula model mengikut persamaan topik", + "Read": "Baca", "Read Aloud": "Baca dengan lantang", - "Read more →": "", - "Read Only": "", - "Read-Only Access": "", - "Reason": "", - "Reasoning Effort": "", - "Reasoning Tags": "", - "Record": "", + "Read more →": "Baca lanjut →", + "Read Only": "Baca Sahaja", + "Read-Only Access": "Akses Baca Sahaja", + "Reason": "Sebab", + "Reasoning Effort": "Usaha Penaakulan", + "Reasoning Tags": "Tag Penaakulan", + "Record": "Rakaman", "Record voice": "Rakam suara", "Redirecting you to Open WebUI Community": "Membawa anda ke Komuniti OpenWebUI", - "Reduces the probability of generating nonsense. A higher value (e.g. 100) will give more diverse answers, while a lower value (e.g. 10) will be more conservative.": "", + "Reduces the probability of generating nonsense. A higher value (e.g. 100) will give more diverse answers, while a lower value (e.g. 10) will be more conservative.": "Mengurangkan kebarangkalian menjana jawapan tanpa makna. Nilai yang lebih tinggi (cth. 100) akan memberikan jawapan yang lebih pelbagai, manakala nilai yang lebih rendah (cth. 10) akan lebih konservatif.", "Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Rujuk diri anda sebagai \"User\" (cth, \"Pengguna sedang belajar bahasa Sepanyol\")", - "Reference Chats": "", - "Refresh": "", + "Reference Chats": "Sembang Rujukan", + "Refresh": "Segarkan", "Refused when it shouldn't have": "Menolak dimana ia tidak sepatutnya", "Regenerate": "Jana semula", - "Regenerate Menu": "", - "Regenerate Response": "", - "Register Again": "", - "Register Client": "", - "Registered": "", - "Registration failed": "", - "Registration successful": "", - "Reindex": "", - "Reindex Knowledge Base Vectors": "", + "Regenerate Menu": "Menu Jana Semula", + "Regenerate Response": "Respons Jana Semula", + "Register Again": "Daftar Semula", + "Register Client": "Daftar Klien", + "Registered": "Didaftarkan", + "Registration failed": "Pendaftaran gagal", + "Registration successful": "Pendaftaran berjaya", + "Reindex": "Indeks semula", + "Reindex Knowledge Base Vectors": "Indeks semula Vektor Pangkalan Pengetahuan", "Release Notes": "Nota Keluaran", - "Releases": "", - "Relevance": "", - "Relevance Threshold": "", - "Remember Dismissal": "", + "Releases": "Keluaran", + "Relevance": "Perkaitan", + "Relevance Threshold": "Ambang Perkaitan", + "Remember Dismissal": "Ingat Penutupan", "Remove": "Hapuskan", - "Remove {{MODELID}} from list.": "", - "Remove action": "", - "Remove file": "", - "Remove File": "", - "Remove from favorites": "", - "Remove image": "", + "Remove {{MODELID}} from list.": "Keluarkan {{MODELID}} daripada senarai.", + "Remove action": "Keluarkan tindakan", + "Remove file": "Buang fail", + "Remove File": "Buang Fail", + "Remove from favorites": "Buang daripada kegemaran", + "Remove image": "Buang imej", "Remove Model": "Hapuskan Model", "Rename": "Namakan Semula", - "Render Markdown in Previews": "", - "Reorder Models": "", - "Reply": "", - "Reply in Thread": "", - "Reply to thread...": "", - "Replying to {{NAME}}": "", - "required": "", - "Reranking Engine": "", + "Render Markdown in Previews": "Render Markdown dalam Pratonton", + "Reorder Models": "Susun Semula Model", + "Reply": "Balas", + "Reply in Thread": "Balas dalam Benang", + "Reply to thread...": "Balas ke benang...", + "Replying to {{NAME}}": "Membalas kepada {{NAME}}", + "required": "diperlukan", + "Reranking Engine": "Enjin Penyusunan Semula", "Reranking Model": "Model 'Reranking'", "Reset": "Tetapkan Semula", - "Reset All Models": "", + "Reset All Models": "Tetapkan Semula Semua Model", "Reset Image": "Tetapkan Semula Imej", "Reset Upload Directory": "Tetapkan Semula Direktori Muat Naik", - "Reset Vector Storage/Knowledge": "", - "Reset view": "", - "Response": "", + "Reset Vector Storage/Knowledge": "Tetapkan Semula Storan Vektor/Pengetahuan", + "Reset view": "Tetapkan Semula Paparan", + "Response": "Respons", "Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Pemberitahuan respons tidak boleh diaktifkan kerana kebenaran tapak web tidak diberi. Sila lawati tetapan pelayar web anda untuk memberikan akses yang diperlukan.", - "Response splitting": "", - "Response Watermark": "", - "Responses": "", - "Restart": "", - "Result": "", + "Response splitting": "Pemisahan Respons", + "Response Watermark": "Tera Air Respons", + "Responses": "Respons", + "Restart": "Mula Semula", + "Result": "Hasil", "RESULT": "KEPUTUSAN", - "Retrieval": "", - "Retrieval Query Generation": "", - "Retrieved {{count}} sources": "", - "Retrieved {{count}} sources_other": "", - "Retrieved 1 source": "", - "Rich Text Input for Chat": "", + "Retrieval": "Pengambilan", + "Retrieval Query Generation": "Penjanaan Pertanyaan Pengambilan", + "Retrieved {{count}} sources": "Mengambil {{count}} sumber", + "Retrieved {{count}} sources_other": "Mengambil {{count}} sumber", + "Retrieved 1 source": "Mengambil 1 sumber", + "Rich Text Input for Chat": "Input Teks Kaya untuk Sembang", "Role": "Peranan", "RTL": "RTL", "Run": "Jalankan", - "Run All": "", + "Run All": "Jalankan Semua", "Running": "Sedang dijalankan", "Running...": "Sedang dijalankan...", - "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "", + "Runs embedding tasks concurrently to speed up processing. Turn off if rate limits become an issue.": "Menjalankan tugas penyisipan secara serentak untuk mempercepatkan pemprosesan. Matikan jika had kadar menjadi isu.", "Save": "Simpan", "Save & Create": "Simpan & Cipta", "Save & Update": "Simpan & Kemas Kini", - "Save As Copy": "", - "Save Chat": "", - "Saved": "", + "Save As Copy": "Simpan Sebagai Salinan", + "Save Chat": "Simpan Obrolan", + "Saved": "Tersimpan", "Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Penyimpanan log perbualan terus ke storan pelayan web anda tidak lagi disokong. Sila luangkan sedikit masa untuk memuat turun dan memadam log perbualan anda dengan mengklik butang di bawah. Jangan risau, anda boleh mengimport semula log perbualan anda dengan mudah melalui 'backend'", - "Scroll On Branch Change": "", + "Scroll On Branch Change": "Skrol Semasa Pertukaran Cabang", "Search": "Carian", "Search a model": "Cari Model", - "Search all emojis": "", - "Search and manage user memories": "", - "Search and view user chat history": "", - "Search Base": "", - "Search channels and channel messages": "", + "Search all emojis": "Cari semua emoji", + "Search and manage user memories": "Cari dan urus ingatan pengguna", + "Search and view user chat history": "Cari dan lihat sejarah obrolan pengguna", + "Search Base": "Cari Pangkalan", + "Search channels and channel messages": "Cari saluran dan mesej saluran", "Search Chats": "Cari Perbualan", - "Search Collection": "", - "Search Files": "", - "Search Filters": "", - "search for archived chats": "", - "search for folders": "", - "search for pinned chats": "", - "search for shared chats": "", - "search for tags": "", + "Search Collection": "Cari Koleksi", + "Search Files": "Cari Fail", + "Search Filters": "Penapis Carian", + "search for archived chats": "cari untuk sembang yang disarkibkan", + "search for folders": "cari untuk folder", + "search for pinned chats": "cari untuk sembang yang disematkan", + "search for shared chats": "cari untuk sembang yang dikongsi", + "search for tags": "cari untuk teg", "Search Functions": "Carian Fungsi", - "Search Groups": "", - "Search In Models": "", - "Search Knowledge": "", + "Search Groups": "Cari Kumpulan", + "Search In Models": "Cari Dalam Model", + "Search Knowledge": "Cari Pengetahuan", "Search Models": "Carian Model", - "Search Notes": "", - "Search options": "", - "Search Prompts": "Carian Gesaan", + "Search Notes": "Cari Nota", + "Search options": "Pilihan carian", + "Search Prompts": "Carian arahan", "Search Result Count": "Kiraan Hasil Carian", - "Search Skills": "", - "Search the internet": "", - "Search the web and fetch URLs": "", + "Search Skills": "Cari Kemahiran", + "Search the internet": "Cari di internet", + "Search the web and fetch URLs": "Cari di web dan ambil URL", "Search Tools": "Alat Carian", - "Search, view, and manage user notes": "", - "SearchApi API Key": "", - "SearchApi Engine": "", - "Searched {{count}} sites": "", - "Searching": "", + "Search, view, and manage user notes": "Cari, lihat, dan urus nota pengguna", + "SearchApi API Key": "Kunci API SearchApi", + "SearchApi Engine": "Enjin SearchApi", + "Searched {{count}} sites": "Telah mencari {{count}} laman", + "Searching": "Sedang mencari", "Searching \"{{searchQuery}}\"": "encari \"{{ searchQuery }}\"", - "Searching Knowledge for \"{{searchQuery}}\"": "", - "Searching the web": "", + "Searching Knowledge for \"{{searchQuery}}\"": "Mencari Pengetahuan untuk \"{{searchQuery}}\"", + "Searching the web": "Mencari di web", "Searxng Query URL": "URL Pertanyaan Searxng", - "Searxng search language (all, en, es, de, fr, etc.)": "", + "Searxng search language (all, en, es, de, fr, etc.)": "Bahasa carian Searxng (semua, en, es, de, fr, dsb.)", "See readme.md for instructions": "Lihat readme.md untuk arahan", "See what's new": "Lihat apa yang terbaru", "Seed": "Benih", - "Select": "", - "Select {{modelName}} model": "", + "Select": "Pilih", + "Select {{modelName}} model": "Pilih model {{modelName}}", "Select a base model": "Pilih model asas", - "Select a base model (e.g. llama3, gpt-4o)": "", - "Select a conversation to preview": "", + "Select a base model (e.g. llama3, gpt-4o)": "Pilih model asas (cth. llama3, gpt-4o)", + "Select a conversation to preview": "Pilih perbualan untuk pratonton", "Select a engine": "Pilih enjin", "Select a function": "Pilih fungsi", - "Select a group": "", - "Select a language": "", - "Select a mode": "", + "Select a group": "Pilih kumpulan", + "Select a language": "Pilih bahasa", + "Select a mode": "Pilih mod", "Select a model": "Pilih model", - "Select a model (optional)": "", + "Select a model (optional)": "Pilih model (pilihan)", "Select a pipeline": "Pilih 'pipeline'", "Select a pipeline url": "Pilih url 'pipeline'", - "Select a reranking model engine": "", - "Select a role": "", - "Select a theme": "", + "Select a reranking model engine": "Pilih enjin model penyusun semula", + "Select a role": "Pilih peranan", + "Select a theme": "Pilih tema", "Select a tool": "Pilih alat", - "Select a voice": "", - "Select an auth method": "", - "Select an embedding model engine": "", - "Select an engine": "", - "Select an Ollama instance": "", - "Select an option": "", - "Select an output format": "", - "Select dtype": "", - "Select Engine": "", - "Select how to split message text for TTS requests": "", - "Select Knowledge": "", - "Select Method": "", + "Select a voice": "Pilih suara", + "Select an auth method": "Pilih kaedah pengesahan", + "Select an embedding model engine": "Pilih enjin model terbenam", + "Select an engine": "Pilih enjin", + "Select an Ollama instance": "Pilih contoh Ollama", + "Select an option": "Pilih pilihan", + "Select an output format": "Pilih format keluaran", + "Select dtype": "Pilih dtype", + "Select Engine": "Pilih Enjin", + "Select how to split message text for TTS requests": "Pilih cara untuk membahagikan teks mesej untuk permintaan TTS", + "Select Knowledge": "Pilih Pengetahuan", + "Select Method": "Pilih Kaedah", "Select only one model to call": "Pilih hanya satu model untuk dipanggil", - "Select view": "", - "Selected model: {{modelName}}": "", + "Select view": "Pilih paparan", + "Selected model: {{modelName}}": "Model terpilih: {{modelName}}", "Selected model(s) do not support image inputs": "Model dipilih tidak menyokong input imej", - "Selected Models": "", - "semantic": "", + "Selected Models": "Model Terpilih", + "semantic": "semantik", "Send": "Hantar", "Send a Message": "Hantar Pesanan", "Send message": "Hantar pesanan", - "Send now": "", - "Sends `stream_options: { include_usage: true }` in the request.\nSupported providers will return token usage information in the response when set.": "", + "Send now": "Hantar sekarang", + "Sends `stream_options: { include_usage: true }` in the request.\nSupported providers will return token usage information in the response when set.": "Menghantar `stream_options: { include_usage: true }` dalam permintaan. Pembekal yang disokong akan mengembalikan maklumat penggunaan token dalam respons apabila ditetapkan.", "September": "September", - "SerpApi API Key": "", - "SerpApi Engine": "", + "SerpApi API Key": "Kunci API SerpApi", + "SerpApi Engine": "Enjin SerpApi", "Serper API Key": "Kunci API Serper", "Serply API Key": "Kunci API Serply", "Serpstack API Key": "Kunci API Serpstack", "Server connection verified": "Sambungan pelayan disahkan", - "Session": "", + "Session": "Sesi", "Set as default": "Tetapkan sebagai lalai", - "Set as Production": "", - "Set embedding model": "", + "Set as Production": "Tetapkan sebagai Pengeluaran", + "Set embedding model": "Tetapkan model pembenaman", "Set embedding model (e.g. {{model}})": "Tetapkan model benamkan (cth {{model}})", "Set reranking model (e.g. {{model}})": "Tetapkan model 'reranking' (cth {{model}})", - "Set the default models that are automatically selected for all users when a new chat is created.": "", - "Set the models that are automatically pinned to the sidebar for all users.": "", - "Set the number of layers, which will be off-loaded to GPU. Increasing this value can significantly improve performance for models that are optimized for GPU acceleration but may also consume more power and GPU resources.": "", - "Set the number of worker threads used for computation. This option controls how many threads are used to process incoming requests concurrently. Increasing this value can improve performance under high concurrency workloads but may also consume more CPU resources.": "", + "Set the default models that are automatically selected for all users when a new chat is created.": "Tetapkan model lalai yang dipilih secara automatik untuk semua pengguna apabila percakapan baharu dibuat.", + "Set the models that are automatically pinned to the sidebar for all users.": "Tetapkan model yang disematkan secara automatik ke bar sisi untuk semua pengguna.", + "Set the number of layers, which will be off-loaded to GPU. Increasing this value can significantly improve performance for models that are optimized for GPU acceleration but may also consume more power and GPU resources.": "Tetapkan bilangan lapisan yang akan dimunggahkan ke GPU. Meningkatkan nilai ini dapat meningkatkan prestasi dengan ketara untuk model yang dioptimalkan untuk pecutan GPU tetapi mungkin juga menggunakan lebih banyak kuasa dan sumber GPU.", + "Set the number of worker threads used for computation. This option controls how many threads are used to process incoming requests concurrently. Increasing this value can improve performance under high concurrency workloads but may also consume more CPU resources.": "Tetapkan bilangan benang pekerja yang digunakan untuk pengiraan. Pilihan ini mengawal berapa banyak benang yang digunakan untuk memproses permintaan masuk secara serentak. Meningkatkan nilai ini dapat meningkatkan prestasi di bawah beban kerja keserenakan tinggi tetapi mungkin juga menggunakan lebih banyak sumber CPU.", "Set Voice": "Tetapan Suara", - "Set whisper model": "", - "Set your status": "", - "Sets a flat bias against tokens that have appeared at least once. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 0.9) will be more lenient. At 0, it is disabled.": "", - "Sets a scaling bias against tokens to penalize repetitions, based on how many times they have appeared. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 0.9) will be more lenient. At 0, it is disabled.": "", - "Sets how far back for the model to look back to prevent repetition.": "", - "Sets the random number seed to use for generation. Setting this to a specific number will make the model generate the same text for the same prompt.": "", - "Sets the size of the context window used to generate the next token.": "", - "Sets the stop sequences to use. When this pattern is encountered, the LLM will stop generating text and return. Multiple stop patterns may be set by specifying multiple separate stop parameters in a modelfile.": "", - "Setting": "", + "Set whisper model": "Tetapkan model whisper", + "Set your status": "Tetapkan status anda", + "Sets a flat bias against tokens that have appeared at least once. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 0.9) will be more lenient. At 0, it is disabled.": "Menetapkan bias rata terhadap token yang telah muncul sekurang-kurangnya sekali. Nilai yang lebih tinggi (cth. 1.5) akan menghukum pengulangan dengan lebih kuat, manakala nilai yang lebih rendah (cth. 0.9) akan lebih belas kasihan. Pada 0, ia dilumpuhkan.", + "Sets a scaling bias against tokens to penalize repetitions, based on how many times they have appeared. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 0.9) will be more lenient. At 0, it is disabled.": "Menetapkan bias penskalaan terhadap token untuk menghukum pengulangan, berdasarkan berapa kali ia telah muncul. Nilai yang lebih tinggi (cth. 1.5) akan menghukum pengulangan dengan lebih kuat, manakala nilai yang lebih rendah (cth. 0.9) akan lebih belas kasihan. Pada 0, ia dilumpuhkan.", + "Sets how far back for the model to look back to prevent repetition.": "Menetapkan sejauh mana model perlu melihat ke belakang untuk mencegah pengulangan.", + "Sets the random number seed to use for generation. Setting this to a specific number will make the model generate the same text for the same prompt.": "Menetapkan benih nombor rawak yang digunakan untuk penjanaan. Menetapkan ini kepada nombor tertentu akan membuat model menjana teks yang sama untuk prompt yang sama.", + "Sets the size of the context window used to generate the next token.": "Menetapkan saiz tetingkap konteks yang digunakan untuk menjana token seterusnya.", + "Sets the stop sequences to use. When this pattern is encountered, the LLM will stop generating text and return. Multiple stop patterns may be set by specifying multiple separate stop parameters in a modelfile.": "Menetapkan jujukan berhenti yang akan digunakan. Apabila corak ini dijumpai, LLM akan berhenti menjana teks dan kembali. Berbilang corak berhenti boleh ditetapkan dengan menentukan berbilang parameter berhenti yang berasingan dalam modelfile.", + "Setting": "Tetapan", "Settings": "Tetapan", - "Settings Permissions": "", + "Settings Permissions": "Kebenaran Tetapan", "Settings saved successfully!": "Tetapan berjaya disimpan!", "Share": "Kongsi", "Share Chat": "Kongsi Perbualan", - "Share link copied to clipboard.": "", + "Share link copied to clipboard.": "Pautan kongsi telah disalin ke papan klip.", "Share to Open WebUI Community": "Kongsi kepada Komuniti OpenWebUI", - "Share your background and interests": "", - "Shared Chats": "", - "Shared with you": "", - "Sharing Permissions": "", + "Share your background and interests": "Kongsi latar belakang dan minat anda", + "Shared Chats": "Perbualan yang Dikongsi", + "Shared with you": "Dikongsi dengan anda", + "Sharing Permissions": "Kebenaran Berkongsi", "Show": "Tunjukkan", - "Show \"What's New\" modal on login": "", + "Show \"What's New\" modal on login": "Paparkan modal \"Apa yang Baru\" semasa log masuk", "Show Admin Details in Account Pending Overlay": "Tunjukkan Butiran Pentadbir dalam Akaun Menunggu Tindanan", - "Show All": "", - "Show all ({{COUNT}} characters)": "", - "Show Files": "", - "Show Formatting Toolbar": "", - "Show image preview": "", - "Show Model": "", - "Show Shortcuts": "", + "Show All": "Paparkan Semua", + "Show all ({{COUNT}} characters)": "Paparkan semua ({{COUNT}} aksara)", + "Show Files": "Paparkan Fail", + "Show Formatting Toolbar": "Paparkan Bar Alatan Format", + "Show image preview": "Tunjukkan pratonton imej", + "Show Model": "Tunjukkan Model", + "Show Shortcuts": "Tunjukkan Pintasan", "Show your support!": "Tunjukkan sokongan anda!", "Showcased creativity": "eativiti yang dipamerkan", - "Showing all messages (user + assistant) per user.": "", + "Showing all messages (user + assistant) per user.": "Menunjukkan semua mesej (pengguna + pembantu) setiap pengguna.", "Sign in": "Daftar masuk", - "Sign in to {{WEBUI_NAME}}": "", - "Sign in to {{WEBUI_NAME}} with LDAP": "", + "Sign in to {{WEBUI_NAME}}": "Daftar masuk ke {{WEBUI_NAME}}", + "Sign in to {{WEBUI_NAME}} with LDAP": "Daftar masuk ke {{WEBUI_NAME}} dengan LDAP", "Sign Out": "Daftar keluar", "Sign up": "Daftar", - "Sign up to {{WEBUI_NAME}}": "", - "Significantly improves accuracy by using an LLM to enhance tables, forms, inline math, and layout detection. Will increase latency. Defaults to False.": "", - "Signing in to {{WEBUI_NAME}}": "", - "Single": "", - "Sink List": "", - "sk-1234": "", - "Skill created successfully": "", - "Skill deleted successfully": "", - "Skill Description": "", - "Skill ID": "", - "Skill imported successfully": "", - "Skill Instructions": "", - "Skill Name": "", - "Skill updated successfully": "", - "Skills": "", - "Skills Access": "", - "Skills Public Sharing": "", - "Skills Sharing": "", - "Skip Cache": "", - "Skip the cache and re-run the inference. Defaults to False.": "", - "Something went wrong :/": "", - "Sonar": "", - "Sonar Deep Research": "", - "Sonar Pro": "", - "Sonar Reasoning": "", - "Sonar Reasoning Pro": "", - "Sort": "", - "Sort by": "", - "Sougou Search API sID": "", - "Sougou Search API SK": "", + "Sign up to {{WEBUI_NAME}}": "Daftar akaun ke {{WEBUI_NAME}}", + "Significantly improves accuracy by using an LLM to enhance tables, forms, inline math, and layout detection. Will increase latency. Defaults to False.": "Meningkatkan ketepatan secara signifikan dengan menggunakan LLM untuk meningkatkan jadual, borang, matematik sebaris, dan pengesanan susun atur. Akan meningkatkan kependaman. Lalai kepada False.", + "Signing in to {{WEBUI_NAME}}": "Sedang daftar masuk ke {{WEBUI_NAME}}", + "Single": "Tunggal", + "Sink List": "Senarai Sinki", + "sk-1234": "sk-1234", + "Skill created successfully": "Kemahiran berjaya dibuat", + "Skill deleted successfully": "Kemahiran berjaya dihapus", + "Skill Description": "Penerangan Kemahiran", + "Skill ID": "ID Kemahiran", + "Skill imported successfully": "Kemahiran berjaya diimport", + "Skill Instructions": "Arahan Kemahiran", + "Skill Name": "Nama Kemahiran", + "Skill updated successfully": "Kemahiran berjaya dikemas kini", + "Skills": "Kemahiran", + "Skills Access": "Akses Kemahiran", + "Skills Public Sharing": "Perkongsian Awam Kemahiran", + "Skills Sharing": "Perkongsian Kemahiran", + "Skip Cache": "Langkau Cache", + "Skip the cache and re-run the inference. Defaults to False.": "Langkau cache dan jalankan semula inferens. Lalai kepada False.", + "Something went wrong :/": "Ada yang salah :/", + "Sonar": "Sonar", + "Sonar Deep Research": "Penyelidikan Mendalam Sonar", + "Sonar Pro": "Sonar Pro", + "Sonar Reasoning": "Penaakulan Sonar", + "Sonar Reasoning Pro": "Penaakulan Sonar Pro", + "Sort": "Isih", + "Sort by": "Isih mengikut", + "Sougou Search API sID": "ID Sonar API Carian Sougou", + "Sougou Search API SK": "SK Sonar API Carian Sougou", "Source": "Sumber", - "Speech Playback Speed": "", + "Speech Playback Speed": "Kecepatan Pemutaran Suara", "Speech recognition error: {{error}}": "Ralat pengecaman pertuturan: {{error}}", - "Speech-to-Text": "", + "Speech-to-Text": "Pertuturan-ke-Teks", "Speech-to-Text Engine": "Enjin Ucapan-ke-Teks", - "Speech-to-Text Language": "", - "Split documents by markdown headers before applying character/token splitting.": "", - "Start a new conversation": "", + "Speech-to-Text Language": "Bahasa Pertuturan-ke-Teks", + "Split documents by markdown headers before applying character/token splitting.": "Bahagikan dokumen mengikut tajuk markdown sebelum menggunakan pemisahan aksara/token.", + "Start a new conversation": "Mulai perbualan baru", "Start of the channel": "Permulaan saluran", - "Start Tag": "", - "Starting kernel...": "", - "Status": "", - "Status cleared successfully": "", - "Status updated successfully": "", - "Status Updates": "", + "Start Tag": "Tag Permulaan", + "Starting kernel...": "Kernel sedang dimulakan...", + "Status": "Status", + "Status cleared successfully": "Status telah dihapus dengan berjaya", + "Status updated successfully": "Status telah dikemas kini dengan berjaya", + "Status Updates": "Kemas Kini Status", "STDOUT/STDERR": "STDOUT/STDERR", - "Steps": "", - "Stop": "", - "Stop Download": "", - "Stop Generating": "", + "Steps": "Langkah-langkah", + "Stop": "Henti", + "Stop Download": "Hentikan Muat Turun", + "Stop Generating": "Hentikan Penjanaan", "Stop Sequence": "Jujukan Henti", - "Stream Chat Response": "", - "Stream Delta Chunk Size": "", - "Streamable HTTP": "", - "Strikethrough": "", - "Strip Existing OCR": "", - "Strip existing OCR text from the PDF and re-run OCR. Ignored if Force OCR is enabled. Defaults to False.": "", + "Stream Chat Response": "Respons Sembang Aliran", + "Stream Delta Chunk Size": "Saiz Ketulan Delta Aliran", + "Streamable HTTP": "HTTP Boleh Alir", + "Strikethrough": "Garis Potong", + "Strip Existing OCR": "Alih Keluar OCR Sedia Ada", + "Strip existing OCR text from the PDF and re-run OCR. Ignored if Force OCR is enabled. Defaults to False.": "Alih keluar teks OCR sedia ada daripada PDF dan jalankan semula OCR. Diabaikan jika Paksa OCR didayakan. Lalai kepada Palsu.", "STT Model": "Model STT", "STT Settings": "Tetapan STT", - "Stylized PDF Export": "", - "Submit question": "", - "Submit suggestion": "", - "Subtitle": "", + "Stylized PDF Export": "Eksport PDF Bergaya", + "Submit question": "Hantar soalan", + "Submit suggestion": "Hantar cadangan", + "Subtitle": "Subtitle", "Success": "Berjaya", - "Successfully imported {{userCount}} users.": "", + "Successfully imported {{userCount}} users.": "Berjaya mengimport {{userCount}} pengguna.", "Successfully updated.": "Berjaya Dikemaskini", - "Suggest a change": "", + "Suggest a change": "Cadangkan perubahan", "Suggested": "Cadangan", "Support": "Sokongan", "Support this plugin:": "Sokong plugin ini", - "Supported MIME Types": "", - "Sync": "", - "Sync Complete!": "", - "Sync directory": "", - "Sync Failed": "", - "Sync Usage Stats": "", - "Syncing stats...": "", - "Syncing...": "", - "Syncs only chats with updates after your last sync timestamp. Disable to re-sync all chats.": "", + "Supported MIME Types": "Jenis MIME yang Disokong", + "Sync": "Sinkron", + "Sync Complete!": "Sinkron Lengkap!", + "Sync directory": "Direktori Sinkron", + "Sync Failed": "Sinkron Gagal", + "Sync Usage Stats": "Statistik Penggunaan Sinkron", + "Syncing stats...": "Mensinkronkan statistik...", + "Syncing...": "Sedang menyegerak...", + "Syncs only chats with updates after your last sync timestamp. Disable to re-sync all chats.": "Hanya menyegerak sembang dengan kemas kini selepas cap masa segerak terakhir anda. Nyahaktifkan untuk menyegerak semula semua sembang.", "System": "Sistem", - "System Instructions": "", - "System Prompt": "Gesaan Sistem", - "Tag": "", - "Tags": "", - "Tags Generation": "", - "Tags Generation Prompt": "", - "Tail free sampling is used to reduce the impact of less probable tokens from the output. A higher value (e.g., 2.0) will reduce the impact more, while a value of 1.0 disables this setting.": "", - "Talk to Model": "", + "System Instructions": "Arahan Sistem", + "System Prompt": "Arahan Sistem", + "Tag": "Tag", + "Tags": "Tag-tag", + "Tags Generation": "Penjanaan Tag", + "Tags Generation Prompt": "Arahan Penjanaan Tag", + "Tail free sampling is used to reduce the impact of less probable tokens from the output. A higher value (e.g., 2.0) will reduce the impact more, while a value of 1.0 disables this setting.": "Persampelan bebas ekor digunakan untuk mengurangkan kesan token yang kurang berkemungkinan daripada output. Nilai yang lebih tinggi (cth., 2.0) akan mengurangkan kesan lebih banyak, manakala nilai 1.0 melumpuhkan tetapan ini.", + "Talk to Model": "Bual dengan Model", "Tap to interrupt": "Sentuh untuk mengganggu", - "Task List": "", - "Task Model": "", - "Tasks": "", + "Task List": "Senarai Tugas", + "Task Model": "Model Tugas", + "Tasks": "Tugas", "Tavily API Key": "Kunci API Tavily", - "Tavily Extract Depth": "", + "Tavily Extract Depth": "Kedalaman Ekstrak Tavily", "Tell us more:": "Beritahu kami lebih lanjut", "Temperature": "Suhu", - "Temporary Chat": "", - "Temporary Chat by Default": "", - "Terminal": "", - "Terminal servers saved": "", - "Text Splitter": "", - "Text-to-Speech": "", + "Temporary Chat": "Sembang Sementara", + "Temporary Chat by Default": "Sembang Sementara secara Default", + "Terminal": "Terminal", + "Terminal servers saved": "Server Terminal Disimpan", + "Text Splitter": "Pemisah Teks", + "Text-to-Speech": "Teks-ke-Ucapan", "Text-to-Speech Engine": "Enjin Teks-ke-Ucapan", "Thanks for your feedback!": "Terima kasih atas maklum balas anda!", - "The Application Account DN you bind with for search": "", - "The base to search for users": "", - "The batch size determines how many text requests are processed together at once. A higher batch size can increase the performance and speed of the model, but it also requires more memory.": "", + "The Application Account DN you bind with for search": "DN Akaun Aplikasi yang anda ikat untuk carian", + "The base to search for users": "Pangkalan untuk mencari pengguna", + "The batch size determines how many text requests are processed together at once. A higher batch size can increase the performance and speed of the model, but it also requires more memory.": "Saiz kelompok menentukan berapa banyak permintaan teks yang diproses bersama sekaligus. Saiz kelompok yang lebih tinggi dapat meningkatkan prestasi dan kecepatan model, tetapi ia juga memerlukan lebih banyak memori.", "The developers behind this plugin are passionate volunteers from the community. If you find this plugin helpful, please consider contributing to its development.": "Pembangun di sebalik 'plugin' ini adalah sukarelawan yang bersemangat daripada komuniti. Jika anda mendapati 'plugin' ini membantu, sila pertimbangkan untuk menyumbang kepada pembangunannya.", - "The evaluation leaderboard is based on the Elo rating system and is updated in real-time.": "", - "The format to return a response in. Format can be json or a JSON schema.": "", - "The height in pixels to compress images to. Leave empty for no compression.": "", - "The language of the input audio. Supplying the input language in ISO-639-1 (e.g. en) format will improve accuracy and latency. Leave blank to automatically detect the language.": "", - "The LDAP attribute that maps to the mail that users use to sign in.": "", - "The LDAP attribute that maps to the username that users use to sign in.": "", - "The leaderboard is currently in beta, and we may adjust the rating calculations as we refine the algorithm.": "", - "The maximum file size in MB. If the file size exceeds this limit, the file will not be uploaded.": "", - "The maximum number of files that can be used at once in chat. If the number of files exceeds this limit, the files will not be uploaded.": "", - "The output format for the text. Can be 'json', 'markdown', or 'html'. Defaults to 'markdown'.": "", - "The passwords you entered don't quite match. Please double-check and try again.": "", + "The evaluation leaderboard is based on the Elo rating system and is updated in real-time.": "Papan kedudukan penilaian berdasarkan sistem penarafan Elo dan dikemas kini secara masa nyata.", + "The format to return a response in. Format can be json or a JSON schema.": "Format untuk mengembalikan respons. Format boleh berupa json atau skema JSON.", + "The height in pixels to compress images to. Leave empty for no compression.": "Ketinggian dalam piksel untuk memampatkan imej. Biarkan kosong untuk tanpa pemampatan.", + "The language of the input audio. Supplying the input language in ISO-639-1 (e.g. en) format will improve accuracy and latency. Leave blank to automatically detect the language.": "Bahasa audio input. Memberikan bahasa input dalam format ISO-639-1 (cth. en) akan meningkatkan ketepatan dan latensi. Biarkan kosong untuk mengesan bahasa secara automatik.", + "The LDAP attribute that maps to the mail that users use to sign in.": "Atribut LDAP yang dipetakan ke mel yang digunakan pengguna untuk log masuk.", + "The LDAP attribute that maps to the username that users use to sign in.": "Atribut LDAP yang dipetakan ke nama pengguna yang digunakan pengguna untuk log masuk.", + "The leaderboard is currently in beta, and we may adjust the rating calculations as we refine the algorithm.": "Papan kedudukan kini dalam versi beta, dan kami mungkin melaraskan pengiraan penarafan apabila kami menyempurnakan algoritma.", + "The maximum file size in MB. If the file size exceeds this limit, the file will not be uploaded.": "Saiz fail maksimum dalam MB. Jika saiz fail melebihi had ini, fail tidak akan dimuat naik.", + "The maximum number of files that can be used at once in chat. If the number of files exceeds this limit, the files will not be uploaded.": "Jumlah maksimum fail yang boleh digunakan sekaligus dalam chat. Jika bilangan fail melebihi had ini, fail tidak akan dimuat naik.", + "The output format for the text. Can be 'json', 'markdown', or 'html'. Defaults to 'markdown'.": "Format output untuk teks. Boleh menjadi 'json', 'markdown', atau 'html'. Lalai kepada 'markdown'.", + "The passwords you entered don't quite match. Please double-check and try again.": "Kata laluan yang anda masukkan tidak sepadan. Sila semak semula dan cuba lagi.", "The score should be a value between 0.0 (0%) and 1.0 (100%).": "Skor hendaklah berada diantara 0.0 (0%) dan 1.0 (100%).", - "The stream delta chunk size for the model. Increasing the chunk size will make the model respond with larger pieces of text at once.": "", - "The temperature of the model. Increasing the temperature will make the model answer more creatively.": "", - "The Weight of BM25 Hybrid Search. 0 more semantic, 1 more lexical. Default 0.5": "", - "The width in pixels to compress images to. Leave empty for no compression.": "", + "The stream delta chunk size for the model. Increasing the chunk size will make the model respond with larger pieces of text at once.": "Saiz chunk delta aliran untuk model. Meningkatkan saiz chunk akan menyebabkan model bertindak balas dengan sekeping teks yang lebih besar sekaligus.", + "The temperature of the model. Increasing the temperature will make the model answer more creatively.": "Suhu model. Meningkatkan suhu akan menyebabkan model menjawab dengan lebih kreatif.", + "The Weight of BM25 Hybrid Search. 0 more semantic, 1 more lexical. Default 0.5": "Berat Carian Hibrid BM25. 0 lebih semantik, 1 lebih leksikal. Lalai 0.5", + "The width in pixels to compress images to. Leave empty for no compression.": "Lebar dalam piksel untuk memampatkan imej. Biarkan kosong untuk tanpa mampatan.", "Theme": "Tema", - "There was an error syncing your stats. Please try again.": "", + "There was an error syncing your stats. Please try again.": "Terdapat ralat dalam menyegerakkan statistik anda. Sila cuba lagi.", "Thinking...": "Berfikir...", "This action cannot be undone. Do you wish to continue?": "Tindakan ini tidak boleh diubah semula kepada asal. Adakah anda ingin teruskan", - "This channel was created on {{createdAt}}. This is the very beginning of the {{channelName}} channel.": "", - "This chat won't appear in history and your messages will not be saved.": "", + "This channel was created on {{createdAt}}. This is the very beginning of the {{channelName}} channel.": "Saluran ini telah diwujudkan pada {{createdAt}}. Ini adalah permulaan saluran {{channelName}}.", + "This chat won't appear in history and your messages will not be saved.": "Perbualan ini tidak akan dipaparkan dalam sejarah dan mesej anda tidak akan disimpan.", "This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Ini akan memastikan bahawa perbualan berharga anda disimpan dengan selamat ke pangkalan data 'backend' anda. Terima kasih!", - "This feature is currently experimental and may not work as expected.": "", - "This feature is experimental and may be modified or discontinued without notice.": "", - "This folder is empty": "", - "This is a default user permission and will remain enabled.": "", + "This feature is currently experimental and may not work as expected.": "Ciri ini sedang dalam peringkat eksperimental dan mungkin tidak berfungsi seperti yang dijangkakan.", + "This feature is experimental and may be modified or discontinued without notice.": "Ciri ini sedang dalam peringkat eksperimental dan mungkin diubah atau dihentikan tanpa notis.", + "This folder is empty": "Folder ini kosong", + "This is a default user permission and will remain enabled.": "Ini ialah kebenaran pengguna lalai dan akan tetap didayakan.", "This is an experimental feature, it may not function as expected and is subject to change at any time.": "ni adalah ciri percubaan, ia mungkin tidak berfungsi seperti yang diharapkan dan tertakluk kepada perubahan pada bila-bila masa.", - "This model is not publicly available. Please select another model.": "", - "This option controls how long the model will stay loaded into memory following the request (default: 5m)": "", - "This option controls how many tokens are preserved when refreshing the context. For example, if set to 2, the last 2 tokens of the conversation context will be retained. Preserving context can help maintain the continuity of a conversation, but it may reduce the ability to respond to new topics.": "", - "This option enables or disables the use of the reasoning feature in Ollama, which allows the model to think before generating a response. When enabled, the model can take a moment to process the conversation context and generate a more thoughtful response.": "", - "This option sets the maximum number of tokens the model can generate in its response. Increasing this limit allows the model to provide longer answers, but it may also increase the likelihood of unhelpful or irrelevant content being generated.": "", - "This option will delete all existing files in the collection and replace them with newly uploaded files.": "", - "This response was generated by \"{{model}}\"": "", + "This model is not publicly available. Please select another model.": "Model ini tidak tersedia secara terbuka. Sila pilih model lain.", + "This option controls how long the model will stay loaded into memory following the request (default: 5m)": "Pilihan ini mengawal berapa lama model akan tetap dimuatkan ke dalam memori selepas permintaan (lalai: 5m)", + "This option controls how many tokens are preserved when refreshing the context. For example, if set to 2, the last 2 tokens of the conversation context will be retained. Preserving context can help maintain the continuity of a conversation, but it may reduce the ability to respond to new topics.": "Pilihan ini mengawal berapa banyak token yang disimpan apabila menyegarkan konteks. Sebagai contoh, jika ditetapkan kepada 2, 2 token terakhir konteks perbualan akan dikekalkan. Memelihara konteks boleh membantu mengekalkan kesinambungan perbualan, tetapi ia mungkin mengurangkan keupayaan untuk bertindak balas terhadap topik baru.", + "This option enables or disables the use of the reasoning feature in Ollama, which allows the model to think before generating a response. When enabled, the model can take a moment to process the conversation context and generate a more thoughtful response.": "Pilihan ini mendayakan atau melumpuhkan penggunaan ciri penalaran dalam Ollama, yang membenarkan model untuk berfikir sebelum menjana respons. Apabila didayakan, model boleh mengambil masa untuk memproses konteks perbualan dan menjana respons yang lebih teliti.", + "This option sets the maximum number of tokens the model can generate in its response. Increasing this limit allows the model to provide longer answers, but it may also increase the likelihood of unhelpful or irrelevant content being generated.": "Pilihan ini menetapkan bilangan maksimum token yang boleh dijana oleh model dalam responsnya. Meningkatkan had ini membenarkan model memberikan jawapan yang lebih panjang, tetapi ia juga mungkin meningkatkan kemungkinan kandungan yang tidak berguna atau tidak relevan dijana.", + "This option will delete all existing files in the collection and replace them with newly uploaded files.": "Pilihan ini akan memadamkan semua fail sedia ada dalam koleksi dan menggantinya dengan fail yang baru dimuat naik.", + "This response was generated by \"{{model}}\"": "Respons ini dijana oleh \"{{model}}\"", "This will delete": "Ini akan memadam", - "This will delete {{NAME}} and all its contents.": "", - "This will delete all models including custom models": "", - "This will delete all models including custom models and cannot be undone.": "", - "This will reset the knowledge base and sync all files. Do you wish to continue?": "", + "This will delete {{NAME}} and all its contents.": "Ini akan memadam {{NAME}} dan semua kandungannya.", + "This will delete all models including custom models": "Ini akan memadam semua model termasuk model tersuai", + "This will delete all models including custom models and cannot be undone.": "Ini akan memadam semua model termasuk model tersuai dan tidak boleh dibuat asal.", + "This will reset the knowledge base and sync all files. Do you wish to continue?": "Ini akan menetapkan semula pangkalan pengetahuan dan menyegerakkan semua fail. Adakah anda ingin meneruskan?", "Thorough explanation": "Penjelasan menyeluruh", - "Thought for {{DURATION}}": "", - "Thought for {{DURATION}} seconds": "", - "Thought for less than a second": "", + "Thought for {{DURATION}}": "Berfikir selama {{DURATION}}", + "Thought for {{DURATION}} seconds": "Berfikir selama {{DURATION}} saat", + "Thought for less than a second": "Berfikir selama kurang dari satu saat", "Thread": "Utas", - "Thumbs up/down ratings from users on model responses": "", + "Thumbs up/down ratings from users on model responses": "Rating ibu jari naik/turun daripada pengguna pada respons model", "Tika": "Tika", "Tika Server URL required.": "URL Pelayan Tika diperlukan.", - "Tiktoken": "", - "Time & Calculation": "", - "Timeout": "", + "Tiktoken": "Tiktoken", + "Time & Calculation": "Masa & Pengiraan", + "Timeout": "Tamat Masa", "Title": "Tajuk", "Title Auto-Generation": "Penjanaan Auto Tajuk", "Title cannot be an empty string.": "Tajuk tidak boleh menjadi rentetan kosong", - "Title Generation": "", - "Title Generation Prompt": "Gesaan Penjanaan Tajuk", - "TLS": "", + "Title Generation": "Penjanaan Tajuk", + "Title Generation Prompt": "Arahan Penjanaan Tajuk", + "TLS": "TLS", "To access the available model names for downloading,": "Untuk mengakses nama model yang tersedia untuk dimuat turun,", "To access the GGUF models available for downloading,": "Untuk mengakses model GGUF yang tersedia untuk dimuat turun,", "To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Untuk mengakses WebUI , sila hubungi pentadbir. Pentadbir boleh menguruskan status pengguna daripada Panel Pentadbiran", - "To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "", - "To learn more about available endpoints, visit our documentation.": "", - "To select skills here, add them to the \"Skills\" workspace first.": "", + "To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "Untuk melampirkan pangkalan pengetahuan di sini, tambahkannya ke ruang kerja \"Knowledge\" terlebih dahulu.", + "To learn more about available endpoints, visit our documentation.": "Untuk mengetahui lebih lanjut tentang titik akhir yang tersedia, lawati dokumentasi kami.", + "To select skills here, add them to the \"Skills\" workspace first.": "Untuk memilih kemahiran di sini, tambahkannya ke ruang kerja \"Skills\" terlebih dahulu.", "To select toolkits here, add them to the \"Tools\" workspace first.": "Untuk memilih kit alatan di sini, tambahkannya pada ruang kerja \"Tools\" dahulu.", - "Toast notifications for new updates": "", + "Toast notifications for new updates": "Pemberitahuan Toast untuk kemas kini baharu", "Today": "Hari Ini", - "Today at {{LOCALIZED_TIME}}": "", - "Toggle {{COUNT}} sources": "", - "Toggle 1 source": "", - "Toggle Dictation": "", - "Toggle Sidebar": "", - "Toggle status history": "", - "Toggle whether current connection is active.": "", - "Token": "", - "Token counts are estimates and may not reflect actual API usage": "", - "tokens": "", - "Tokens": "", - "Too verbose": "", + "Today at {{LOCALIZED_TIME}}": "Hari ini pada {{LOCALIZED_TIME}}", + "Toggle {{COUNT}} sources": "Togol {{COUNT}} sumber", + "Toggle 1 source": "Togol 1 sumber", + "Toggle Dictation": "Togol Diktasi", + "Toggle Sidebar": "Togol Sisi Bar", + "Toggle status history": "Togol sejarah status", + "Toggle whether current connection is active.": "Togol sama ada sambungan semasa aktif.", + "Token": "Token", + "Token counts are estimates and may not reflect actual API usage": "Kiraan token adalah anggaran dan mungkin tidak mencerminkan penggunaan API sebenar", + "tokens": "token", + "Tokens": "Token", + "Too verbose": "Terlalu verbose", "Tool created successfully": "Alat berjaya dibuat", "Tool deleted successfully": "Alat berjaya dipadamkan", - "Tool Description": "", - "Tool ID": "", + "Tool Description": "Deskripsi Alat", + "Tool ID": "ID Alat", "Tool imported successfully": "Alat berjaya diimport", - "Tool Name": "", - "Tool Servers": "", + "Tool Name": "Nama Alat", + "Tool Servers": "Server Alat", "Tool updated successfully": "Alat berjaya dikemas kini", "Tools": "Alatan", - "Tools Access": "", + "Tools Access": "Akses Alat", "Tools are a function calling system with arbitrary code execution": "Alatan ialah sistem panggilan fungsi dengan pelaksanaan kod sewenang-wenangnya", - "Tools Function Calling Prompt": "", + "Tools Function Calling Prompt": "Prompt Pemanggilan Fungsi Alat", "Tools have a function calling system that allows arbitrary code execution.": "Alatan mempunyai sistem panggilan fungsi yang membolehkan pelaksanaan kod sewenang-wenangnya.", - "Tools Public Sharing": "", - "Tools Sharing": "", - "Top": "", + "Tools Public Sharing": "Perkongsian Awam Alat", + "Tools Sharing": "Perkongsian Alat", + "Top": "Teratas", "Top K": "'Top K'", - "Top K Reranker": "", - "Transformers": "", + "Top K Reranker": "Pemeringkat K Teratas", + "Transformers": "Transformers", "Trouble accessing Ollama?": "Masalah mengakses Ollama?", - "Trust Proxy Environment": "", - "Try adjusting your search or filter to find what you are looking for.": "", - "Try Again": "", + "Trust Proxy Environment": "Persekitaran Proksi Terpercaya", + "Try adjusting your search or filter to find what you are looking for.": "Coba sesuaikan pencarian atau penapis anda untuk mencari apa yang anda cari.", + "Try Again": "Cuba Lagi", "TTS Model": "Model TTS", "TTS Settings": "Tetapan TTS", "TTS Voice": "Suara TTS", "Type": "jenis", - "Type here...": "", + "Type here...": "Taip di sini...", "Type Hugging Face Resolve (Download) URL": "Taip URL 'Hugging Face Resolve (Download)'", - "Uh-oh! There was an issue with the response.": "", + "Uh-oh! There was an issue with the response.": "Alamak! Ada masalah dengan respons.", "UI": "UI", - "UI Scale": "", - "Unarchive All": "", - "Unarchive All Archived Chats": "", - "Unarchive Chat": "", - "Underline": "", - "Unknown": "", - "Unknown User": "", - "Unloads {{FROM_NOW}}": "", - "Unlock mysteries": "", + "UI Scale": "Skala UI", + "Unarchive All": "Nyaharkibkan Semua", + "Unarchive All Archived Chats": "Nyaharkibkan Semua Sembang Terarkib", + "Unarchive Chat": "Nyaharkibkan Sembang", + "Underline": "Garis Bawah", + "Unknown": "Tidak Diketahui", + "Unknown User": "Pengguna Tidak Diketahui", + "Unloads {{FROM_NOW}}": "Membuang {{FROM_NOW}}", + "Unlock mysteries": "Buka Misteri", "Unpin": "Nyahsematkan", - "Unravel secrets": "", - "Unshare Chat": "", - "Unsupported file type.": "", - "Untagged": "", - "Untitled": "", + "Unravel secrets": "Ungkap Rahsia", + "Unshare Chat": "Batalkan Perkongsian Sembang", + "Unsupported file type.": "Jenis fail tidak disokong.", + "Untagged": "Tanpa Tag", + "Untitled": "Tanpa Tajuk", "Update": "Kemaskini", "Update and Copy Link": "Kemaskini dan salin pautan", - "Update for the latest features and improvements.": "", + "Update for the latest features and improvements.": "Kemas kini untuk fitur dan peningkatan terbaru.", "Update password": "Kemaskini Kata Laluan", - "Update your status": "", - "Updated": "", + "Update your status": "Kemas kini status anda", + "Updated": "Dikemas kini", "Updated at": "Dikemaskini pada", - "Updated At": "", - "Upgrade to a licensed plan for enhanced capabilities, including custom theming and branding, and dedicated support.": "", + "Updated At": "Dikemas kini Pada", + "Upgrade to a licensed plan for enhanced capabilities, including custom theming and branding, and dedicated support.": "Tingkatkan ke pelan berlesen untuk keupayaan yang ditingkatkan, termasuk tema khusus dan penjenamaan, serta sokongan berdedikasi.", "Upload": "Muatnaik", "Upload a GGUF model": "Muatnaik model GGUF", - "Upload Audio": "", - "Upload directory": "", - "Upload files": "", + "Upload Audio": "Muat Naik Audio", + "Upload directory": "Muat Naik Direktori", + "Upload files": "Muat Naik Fail", "Upload Files": "Muatnaik fail", - "Upload Model": "", + "Upload Model": "Muat Naik Model", "Upload Pipeline": "Muatnaik 'Pipeline'", - "Upload profile image": "", + "Upload profile image": "Muat Naik Imej Profil", "Upload Progress": "Kemajuan Muatnaik", - "Upload Progress: {{uploadedFiles}}/{{totalFiles}} ({{percentage}}%)": "", - "Uploaded files or images": "", - "Uploading file...": "", - "Uploading...": "", - "URL": "", - "URL is required": "", + "Upload Progress: {{uploadedFiles}}/{{totalFiles}} ({{percentage}}%)": "Kemajuan Muat Naik: {{uploadedFiles}}/{{totalFiles}} ({{percentage}}%)", + "Uploaded files or images": "Fail atau imej yang dimuat naik", + "Uploading file...": "Memuat naik fail...", + "Uploading...": "Memuat naik...", + "URL": "URL", + "URL is required": "URL diperlukan", "URL Mode": "Mod URL", - "Usage": "", - "Use": "", - "Use '#' in the prompt input to load and include your knowledge.": "", - "Use /v1/chat/completions endpoint instead of /v1/audio/transcriptions for potentially better accuracy.": "", - "Use Chat Completions API": "", - "Use groups to organize your users and assign permissions.": "", - "Use LLM": "", - "Use no proxy to fetch page contents.": "", - "Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "", + "Usage": "Penggunaan", + "Use": "Gunakan", + "Use '#' in the prompt input to load and include your knowledge.": "Gunakan '#' dalam input gesaran untuk memuatkan dan memasukkan pengetahuan anda.", + "Use /v1/chat/completions endpoint instead of /v1/audio/transcriptions for potentially better accuracy.": "Gunakan titik akhir /v1/chat/completions daripada /v1/audio/transcriptions untuk ketepatan yang berpotensi lebih baik.", + "Use Chat Completions API": "Gunakan Chat Completions API", + "Use groups to organize your users and assign permissions.": "Gunakan kumpulan untuk mengorganisir pengguna anda dan menetapkan kebenaran.", + "Use LLM": "Gunakan LLM", + "Use no proxy to fetch page contents.": "Jangan gunakan proksi untuk mengambil kandungan halaman.", + "Use proxy designated by http_proxy and https_proxy environment variables to fetch page contents.": "Gunakan proksi yang ditetapkan oleh pembolehubah persekitaran http_proxy dan https_proxy untuk mengambil kandungan halaman.", "user": "pengguna", - "User": "", - "User Activity": "", - "User Groups": "", + "User": "Pengguna", + "User Activity": "Aktiviti Pengguna", + "User Groups": "Kumpulan Pengguna", "User location successfully retrieved.": "Lokasi pengguna berjaya diambil.", - "User menu": "", - "User ratings (thumbs up/down)": "", - "User Status": "", - "User Webhooks": "", - "Username": "", - "users": "", + "User menu": "Menu Pengguna", + "User ratings (thumbs up/down)": "Penilaian Pengguna (ibu jari naik/turun)", + "User Status": "Status Pengguna", + "User Webhooks": "Webhook Pengguna", + "Username": "Nama Pengguna", + "users": "pengguna", "Users": "Pengguna", - "Uses DefaultAzureCredential to authenticate": "", - "Uses OAuth 2.1 Dynamic Client Registration": "", - "Using Entire Document": "", - "Using Focused Retrieval": "", - "Using the default arena model with all models. Click the plus button to add custom models.": "", + "Uses DefaultAzureCredential to authenticate": "Menggunakan DefaultAzureCredential untuk pengesahan", + "Uses OAuth 2.1 Dynamic Client Registration": "Menggunakan Pendaftaran Klien Dinamik OAuth 2.1", + "Using Entire Document": "Menggunakan Seluruh Dokumen", + "Using Focused Retrieval": "Menggunakan Pengambilan Tertumpu", + "Using the default arena model with all models. Click the plus button to add custom models.": "Menggunakan model arena lalai dengan semua model. Klik butang tambah untuk menambah model tersuai.", "Valid time units:": "Unit masa yang sah:", - "Validate certificate": "", + "Validate certificate": "Sahkan Sijil", "Valves": "'Valves'", "Valves updated": "'Valves' dikemaskini", "Valves updated successfully": "'Valves' berjaya dikemaskini", "variable": "pembolehubah", - "Verify Connection": "", - "Verify SSL Certificate": "", + "Verify Connection": "Sahkan Sambungan", + "Verify SSL Certificate": "Sahkan Sijil SSL", "Version": "Versi", - "Version {{selectedVersion}} of {{totalVersions}}": "", - "Version deleted": "", - "View Replies": "", - "View Result from **{{NAME}}**": "", - "View source: {{name}}": "", - "View source: {{title}}": "", - "Visibility": "", - "Visible": "", - "Visible to all users": "", - "Vision": "", + "Version {{selectedVersion}} of {{totalVersions}}": "Versi {{selectedVersion}} daripada {{totalVersions}}", + "Version deleted": "Versi telah dihapus", + "View Replies": "Lihat Balasan", + "View Result from **{{NAME}}**": "Lihat Hasil daripada **{{NAME}}**", + "View source: {{name}}": "Lihat sumber: {{name}}", + "View source: {{title}}": "Lihat sumber: {{title}}", + "Visibility": "Ketampakan", + "Visible": "Boleh Dilihat", + "Visible to all users": "Terlihat kepada semua pengguna", + "Vision": "Penglihatan", "Voice": "Suara", - "Voice Input": "", - "Voice mode": "", - "Voice Mode Custom Prompt": "", - "Voice Mode Prompt": "", - "Waiting for upload...": "", + "Voice Input": "Input Suara", + "Voice mode": "Mode Suara", + "Voice Mode Custom Prompt": "Prompt Kustom Mode Suara", + "Voice Mode Prompt": "Prompt Mode Suara", + "Waiting for upload...": "Menunggu pemuat...", "Warning": "Amaran", "Warning:": "Amaran:", - "Warning: Enabling this will allow users to upload arbitrary code on the server.": "", - "Warning: Jupyter execution enables arbitrary code execution, posing severe security risks—proceed with extreme caution.": "", + "Warning: Enabling this will allow users to upload arbitrary code on the server.": "Amaran: Mengaktifkan ini akan membenarkan pengguna memuat naik kod arbitrari pada pelayan.", + "Warning: Jupyter execution enables arbitrary code execution, posing severe security risks—proceed with extreme caution.": "Amaran: Pelaksanaan Jupyter membolehkan pelaksanaan kod arbitrari, menimbulkan risiko keselamatan yang teruk—teruskan dengan berhati-hati.", "Web": "Web", "Web API": "API Web", - "Web Loader Engine": "", + "Web Loader Engine": "Enjin Pemuatan Web", "Web Search": "Carian Web", "Web Search Engine": "Enjin Carian Web", - "Web Search in Chat": "", - "Web Search Query Generation": "", - "Webhook Name": "", + "Web Search in Chat": "Carian Web dalam Sembang", + "Web Search Query Generation": "Penjanaan Pertanyaan Carian Web", + "Webhook Name": "Nama Webhook", "Webhook URL": "URL 'Webhook'", - "Webhooks": "", - "Webpage URLs": "", + "Webhooks": "Webhook", + "Webpage URLs": "URL Halaman Web", "WebUI Settings": "Tetapan WebUI", - "WebUI URL": "", - "WebUI will make requests to \"{{url}}\"": "", - "WebUI will make requests to \"{{url}}/api/chat\"": "", - "WebUI will make requests to \"{{url}}/chat/completions\"": "", - "What are you trying to achieve?": "", - "What are you working on?": "", - "What is NOT shared:": "", - "What is shared:": "", + "WebUI URL": "URL WebUI", + "WebUI will make requests to \"{{url}}\"": "WebUI akan membuat permintaan ke \"{{url}}\"", + "WebUI will make requests to \"{{url}}/api/chat\"": "WebUI akan membuat permintaan ke \"{{url}}/api/chat\"", + "WebUI will make requests to \"{{url}}/chat/completions\"": "WebUI akan membuat permintaan ke \"{{url}}/chat/completions\"", + "What are you trying to achieve?": "Apa yang ingin anda capai?", + "What are you working on?": "Apa yang sedang anda kerjakan?", + "What is NOT shared:": "Apa yang TIDAK dikongsi:", + "What is shared:": "Apa yang dikongsi:", "What's New in": "Apakah yang terbaru dalam", - "What's on your mind?": "", - "When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "", - "wherever you are": "", - "Whether to paginate the output. Each page will be separated by a horizontal rule and page number. Defaults to False.": "", + "What's on your mind?": "Apa yang terlintas di fikiran anda?", + "When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "Apabila didayakan, model akan bertindak balas kepada setiap mesej sembang secara masa nyata, menjana respons sebaik sahaja pengguna menghantar mesej. Mod ini berguna untuk aplikasi sembang langsung, tetapi mungkin menjejaskan prestasi pada perkakasan yang lebih perlahan.", + "wherever you are": "di mana pun anda berada", + "Whether to paginate the output. Each page will be separated by a horizontal rule and page number. Defaults to False.": "Sama ada untuk memisahkan output mengikut halaman. Setiap halaman akan dipisahkan oleh garis mendatar dan nombor halaman. Lalai kepada False.", "Whisper (Local)": "Whisper (Local)", - "Who can share to this group": "", - "Why?": "", + "Who can share to this group": "Siapa yang boleh berkongsi kepada kumpulan ini", + "Why?": "Mengapa?", "Widescreen Mode": "Mod Skrin Lebar", - "Width": "", - "Wikipedia": "", - "Won": "", - "Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text.": "", + "Width": "Lebar", + "Wikipedia": "Wikipedia", + "Won": "Menang", + "Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text.": "Berfungsi bersama dengan top-k. Nilai yang lebih tinggi (contohnya, 0.95) akan menghasilkan teks yang lebih pelbagai, manakala nilai yang lebih rendah (contohnya, 0.5) akan menghasilkan teks yang lebih fokus dan konservatif.", "Workspace": "Ruangan Kerja", - "Workspace Permissions": "", - "Write": "", + "Workspace Permissions": "Kebenaran Ruang Kerja", + "Write": "Tulis", "Write a summary in 50 words that summarizes {{topic}}.": "Tulis ringkasan dalam 50 patah perkataan yang meringkaskan [topik atau kata kunci].", - "Write something...": "", + "Write something...": "Tulis sesuatu...", "Write your model system prompt content here\ne.g.) You are Mario from Super Mario Bros, acting as an assistant.": "Tulis kandungan arahan sistem (system prompt) model anda di sini\ncth.: Anda ialah Mario daripada Super Mario Bros dan bertindak sebagai pembantu.", - "Yacy Instance URL": "", - "Yacy Password": "", - "Yacy Username": "", - "Yahoo": "", - "Yandex": "", - "Yandex Web Search API Key": "", - "Yandex Web Search config": "", - "Yandex Web Search URL": "", + "Yacy Instance URL": "URL Instans Yacy", + "Yacy Password": "Kata Laluan Yacy", + "Yacy Username": "Nama Pengguna Yacy", + "Yahoo": "Yahoo", + "Yandex": "Yandex", + "Yandex Web Search API Key": "Kunci API Pencarian Web Yandex", + "Yandex Web Search config": "Konfigurasi Pencarian Web Yandex", + "Yandex Web Search URL": "URL Pencarian Web Yandex", "Yesterday": "Semalam", - "Yesterday at {{LOCALIZED_TIME}}": "", + "Yesterday at {{LOCALIZED_TIME}}": "Semalam pada {{LOCALIZED_TIME}}", "You": "Anda", - "You are currently using a trial license. Please contact support to upgrade your license.": "", - "You can only chat with a maximum of {{maxCount}} file(s) at a time.": "", + "You are currently using a trial license. Please contact support to upgrade your license.": "Anda sedang menggunakan lesen percubaan. Sila hubungi sokongan untuk menaik taraf lesen anda.", + "You can only chat with a maximum of {{maxCount}} file(s) at a time.": "Anda hanya boleh berbual dengan maksimum {{maxCount}} fail sekaligus.", "You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "Anda boleh memperibadikan interaksi anda dengan LLM dengan menambahkan memori melalui butang 'Urus' di bawah, menjadikannya lebih membantu dan disesuaikan dengan anda.", - "You cannot upload an empty file.": "", - "You do not have permission to edit this model": "", - "You do not have permission to edit this prompt.": "", - "You do not have permission to edit this skill.": "", - "You do not have permission to edit this tool": "", - "You do not have permission to make this public": "", - "You do not have permission to send messages in this channel.": "", - "You do not have permission to send messages in this thread.": "", - "You do not have permission to upload files to this knowledge base.": "", - "You do not have permission to upload files.": "", - "You do not have permission to upload web content.": "", + "You cannot upload an empty file.": "Anda tidak boleh memuat naik fail kosong.", + "You do not have permission to edit this model": "Anda tidak mempunyai kebenaran untuk mengedit model ini.", + "You do not have permission to edit this prompt.": "Anda tidak mempunyai kebenaran untuk mengedit gesaran ini.", + "You do not have permission to edit this skill.": "Anda tidak mempunyai kebenaran untuk mengedit kemahiran ini.", + "You do not have permission to edit this tool": "Anda tidak mempunyai kebenaran untuk mengedit alat ini.", + "You do not have permission to make this public": "Anda tidak mempunyai kebenaran untuk menjadikan ini awam.", + "You do not have permission to send messages in this channel.": "Anda tidak mempunyai kebenaran untuk menghantar mesej dalam saluran ini.", + "You do not have permission to send messages in this thread.": "Anda tidak mempunyai kebenaran untuk menghantar mesej dalam utas ini.", + "You do not have permission to upload files to this knowledge base.": "Anda tidak mempunyai kebenaran untuk memuat naik fail ke pangkalan pengetahuan ini.", + "You do not have permission to upload files.": "Anda tidak mempunyai kebenaran untuk memuat naik fail.", + "You do not have permission to upload web content.": "Anda tidak mempunyai kebenaran untuk memuat naik kandungan web.", "You have no archived conversations.": "Anda tidak mempunyai perbualan yang diarkibkan", - "You have no shared conversations.": "", + "You have no shared conversations.": "Anda tidak mempunyai perbualan yang dikongsi.", "You have shared this chat": "Anda telah berkongsi perbualan ini", - "You.com API Key": "", + "You.com API Key": "Kunci API You.com", "You're a helpful assistant.": "Anda seorang pembantu yang bagus", "You're now logged in.": "Anda kini telah log masuk.", - "Your Account": "", + "Your Account": "Akaun Anda", "Your account status is currently pending activation.": "Status akaun anda ialah sedang menunggu pengaktifan.", - "Your browser does not support the audio tag.": "", - "Your browser does not support the video tag.": "", + "Your browser does not support the audio tag.": "Pelayar anda tidak menyokong teg audio.", + "Your browser does not support the video tag.": "Pelayar anda tidak menyokong teg video.", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Seluruh sumbangan anda akan dihantar terus kepada pembangun 'plugin'; Open WebUI tidak mengambil sebarang peratusan keuntungan daripadanya. Walau bagaimanapun, platform pembiayaan yang dipilih mungkin mempunyai caj tersendiri.", - "Your message text or inputs": "", - "Your usage stats have been successfully synced.": "", + "Your message text or inputs": "Teks atau input mesej anda", + "Your usage stats have been successfully synced.": "Statistik penggunaan anda telah berjaya disegerakkan.", "YouTube": "Youtube", - "Youtube Language": "", - "Youtube Proxy URL": "" + "Youtube Language": "Bahasa Youtube", + "Youtube Proxy URL": "URL Proksi Youtube" } From 2c35bdbcf5729227a932703f505a9d2aba5b2cd4 Mon Sep 17 00:00:00 2001 From: Alvin Tang <104285249+alvinttang@users.noreply.github.com> Date: Mon, 9 Mar 2026 05:39:09 +0800 Subject: [PATCH 0835/1854] fix: replace bare string raises with proper exception types (#22446) `raise "string"` in Python raises TypeError instead of the intended error, making error messages confusing and debugging difficult. Co-authored-by: gambletan Co-authored-by: Claude Opus 4.6 --- backend/open_webui/retrieval/utils.py | 4 ++-- backend/open_webui/routers/ollama.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/open_webui/retrieval/utils.py b/backend/open_webui/retrieval/utils.py index 86b4acc06d..e19563861b 100644 --- a/backend/open_webui/retrieval/utils.py +++ b/backend/open_webui/retrieval/utils.py @@ -590,7 +590,7 @@ def generate_openai_batch_embeddings( if "data" in data: return [elem["embedding"] for elem in data["data"]] else: - raise "Something went wrong :/" + raise ValueError("Unexpected OpenAI embeddings response: missing 'data' key") except Exception as e: log.exception(f"Error generating openai batch embeddings: {e}") return None @@ -767,7 +767,7 @@ def generate_ollama_batch_embeddings( if "embeddings" in data: return data["embeddings"] else: - raise "Something went wrong :/" + raise ValueError("Unexpected Ollama embeddings response: missing 'embeddings' key") except Exception as e: log.exception(f"Error generating ollama batch embeddings: {e}") return None diff --git a/backend/open_webui/routers/ollama.py b/backend/open_webui/routers/ollama.py index 926e2c02ad..f1170b8f88 100644 --- a/backend/open_webui/routers/ollama.py +++ b/backend/open_webui/routers/ollama.py @@ -1747,7 +1747,7 @@ async def download_file_stream( yield f"data: {json.dumps(res)}\n\n" else: - raise "Ollama: Could not create blob, Please try again." + raise RuntimeError("Ollama: Could not create blob, Please try again.") # url = "https://huggingface.co/TheBloke/stablelm-zephyr-3b-GGUF/resolve/main/stablelm-zephyr-3b.Q2_K.gguf" From 67e26fd3af8fc156958297b84903b70ce959590d Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sun, 8 Mar 2026 16:40:20 -0500 Subject: [PATCH 0836/1854] refac --- backend/open_webui/routers/tools.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backend/open_webui/routers/tools.py b/backend/open_webui/routers/tools.py index 938e3c3ee8..351c491bdc 100644 --- a/backend/open_webui/routers/tools.py +++ b/backend/open_webui/routers/tools.py @@ -30,7 +30,11 @@ from open_webui.utils.plugin import ( ) from open_webui.utils.tools import get_tool_specs from open_webui.utils.auth import get_admin_user, get_verified_user -from open_webui.utils.access_control import has_permission, filter_allowed_access_grants +from open_webui.utils.access_control import ( + has_permission, + has_access, + filter_allowed_access_grants, +) from open_webui.utils.tools import get_tool_servers from open_webui.config import CACHE_DIR, BYPASS_ADMIN_ACCESS_CONTROL From 710320601a3b15dc65acc3944c81455257be46ac Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sun, 8 Mar 2026 16:41:21 -0500 Subject: [PATCH 0837/1854] refac --- backend/open_webui/retrieval/loaders/main.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/open_webui/retrieval/loaders/main.py b/backend/open_webui/retrieval/loaders/main.py index 83adb8823f..d4cc4391aa 100644 --- a/backend/open_webui/retrieval/loaders/main.py +++ b/backend/open_webui/retrieval/loaders/main.py @@ -86,6 +86,9 @@ known_source_ext = [ "hs", "lhs", "json", + "yaml", + "yml", + "toml", ] From 63a0befd3cd05d9a83ed7ee3da2be961dcac6cb4 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 8 Mar 2026 22:41:42 +0100 Subject: [PATCH 0838/1854] fix: add missing opentelemetry-instrumentation-system-metrics dependency (#22447) --- backend/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/requirements.txt b/backend/requirements.txt index 3d3a54965d..86bb8d23a1 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -155,3 +155,4 @@ opentelemetry-instrumentation-requests==0.61b0 opentelemetry-instrumentation-logging==0.61b0 opentelemetry-instrumentation-httpx==0.61b0 opentelemetry-instrumentation-aiohttp-client==0.61b0 +opentelemetry-instrumentation-system-metrics==0.61b0 From bbbe2b66b42e07cc73d83e7e8dfaf5b514dc02e4 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 8 Mar 2026 22:44:03 +0100 Subject: [PATCH 0839/1854] fix: use static month names in getTimeRange to prevent OS locale leaking into sidebar (#22454) getTimeRange returns month names that are used as i18n translation keys (consumed via \.t(chat.time_range) in the sidebar, search modal, etc.). The keys must be exact English strings like 'January', 'February', etc. Previously, toLocaleString('default', { month: 'long' }) was used to generate these keys. The 'default' locale defers to the browser's locale resolution, which in Firefox with intl.regional_prefs.use_os_locales=true picks up OS regional settings instead of the browser language. This caused German month names (e.g. 'Februar', 'Januar') to appear in the sidebar for users whose OS region is set to Germany, even when both browser and app language are set to English. Chrome was unaffected because it ignores OS regional settings for the 'default' locale. Since i18n has no translation key for 'Februar', the German string passed through untranslated. Replace toLocaleString with a static MONTH_NAMES array lookup to make the intent explicit and eliminate any browser/OS locale dependency. --- src/lib/utils/index.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index 61ecb75c8b..41b1328810 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -1094,6 +1094,22 @@ export const approximateToHumanReadable = (nanoseconds: number) => { return results.reverse().join(' '); }; +// Month names used as i18n translation keys — must be English regardless of locale +const MONTH_NAMES = [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December' +]; + export const getTimeRange = (timestamp) => { const now = new Date(); const date = new Date(timestamp * 1000); // Convert Unix timestamp to milliseconds @@ -1119,7 +1135,7 @@ export const getTimeRange = (timestamp) => { } else if (diffDays <= 30) { return 'Previous 30 days'; } else if (nowYear === dateYear) { - return date.toLocaleString('default', { month: 'long' }); + return MONTH_NAMES[dateMonth]; } else { return date.getFullYear().toString(); } From f78b238b40a9dc927e6cbf4c6ee9bee5dfabdca2 Mon Sep 17 00:00:00 2001 From: Alvin Tang <104285249+alvinttang@users.noreply.github.com> Date: Mon, 9 Mar 2026 05:44:35 +0800 Subject: [PATCH 0840/1854] fix: prevent pipeline filter from corrupting payload on HTTP error (#22445) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In both inlet and outlet filter processing, response.json() was called BEFORE response.raise_for_status(). When a filter endpoint returns an HTTP error, the user's chat payload gets silently overwritten with the error response body. If the error is not caught, the corrupted payload propagates through subsequent filters and into the chat completion. Swapped the order so raise_for_status() runs first — payload is only updated on success. Co-authored-by: gambletan --- backend/open_webui/routers/pipelines.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/routers/pipelines.py b/backend/open_webui/routers/pipelines.py index ebedd3027d..fa1b77a09c 100644 --- a/backend/open_webui/routers/pipelines.py +++ b/backend/open_webui/routers/pipelines.py @@ -92,8 +92,8 @@ async def process_pipeline_inlet_filter(request, payload, user, models): json=request_data, ssl=AIOHTTP_CLIENT_SESSION_SSL, ) as response: - payload = await response.json() response.raise_for_status() + payload = await response.json() except aiohttp.ClientResponseError as e: res = ( await response.json() @@ -145,8 +145,8 @@ async def process_pipeline_outlet_filter(request, payload, user, models): json=request_data, ssl=AIOHTTP_CLIENT_SESSION_SSL, ) as response: - payload = await response.json() response.raise_for_status() + payload = await response.json() except aiohttp.ClientResponseError as e: try: res = ( From 3e513be96343f39a024aad0b4ebd1597352011fb Mon Sep 17 00:00:00 2001 From: Alvin Tang <104285249+alvinttang@users.noreply.github.com> Date: Mon, 9 Mar 2026 05:45:21 +0800 Subject: [PATCH 0841/1854] fix: prevent TypeError in Teams webhook when user data is missing (#22444) json.loads(event_data.get("user", {})) crashes with TypeError when the "user" key is absent because the default value {} is a dict, not a JSON string. json.loads expects str/bytes, not dict. Also handle the case where "user" is already a dict (not serialized JSON) to make the webhook more robust. Co-authored-by: gambletan --- backend/open_webui/utils/webhook.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/backend/open_webui/utils/webhook.py b/backend/open_webui/utils/webhook.py index eb2688851f..62d35f299f 100644 --- a/backend/open_webui/utils/webhook.py +++ b/backend/open_webui/utils/webhook.py @@ -26,9 +26,14 @@ async def post_webhook(name: str, url: str, message: str, event_data: dict) -> b # Microsoft Teams Webhooks elif "webhook.office.com" in url: action = event_data.get("action", "undefined") + user_data = event_data.get("user", "{}") + if isinstance(user_data, dict): + user_dict = user_data + else: + user_dict = json.loads(user_data) facts = [ {"name": name, "value": value} - for name, value in json.loads(event_data.get("user", {})).items() + for name, value in user_dict.items() ] payload = { "@type": "MessageCard", From 7a3c5c0f8a5e1f6174bcdff8b21c7da309a872f6 Mon Sep 17 00:00:00 2001 From: "Ethan T." Date: Mon, 9 Mar 2026 05:45:36 +0800 Subject: [PATCH 0842/1854] fix: replace bare except with except Exception in main.py (#22423) From 138c4cbfcf5734d882c4b6ae27fe596223c25a41 Mon Sep 17 00:00:00 2001 From: Fu-Jie <33599649+Fu-Jie@users.noreply.github.com> Date: Mon, 9 Mar 2026 05:46:56 +0800 Subject: [PATCH 0843/1854] fix: filter out internal tool methods starting with underscore (#22408) --- backend/open_webui/utils/tools.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/utils/tools.py b/backend/open_webui/utils/tools.py index 081e2f5fab..e525a8284c 100644 --- a/backend/open_webui/utils/tools.py +++ b/backend/open_webui/utils/tools.py @@ -707,8 +707,8 @@ def get_functions_from_tool(tool: object) -> list[Callable]: getattr(tool, func) ) # checks if the attribute is callable (a method or function). and not func.startswith( - "__" - ) # filters out special (dunder) methods like init, str, etc. — these are usually built-in functions of an object that you might not need to use directly. + "_" + ) # filters out internal methods (starting with _) and special (dunder) methods. and not inspect.isclass( getattr(tool, func) ) # ensures that the callable is not a class itself, just a method or function. From a97f5adf95016813ab992b68d15ef132bed060ae Mon Sep 17 00:00:00 2001 From: "Ethan T." Date: Mon, 9 Mar 2026 05:47:47 +0800 Subject: [PATCH 0844/1854] fix: URL-encode OAuth error message in redirect URL (#22415) - URL-encodes the OAuth error message when constructing the redirect URL in the OIDC callback handler - Without encoding, error messages containing spaces, ampersands, or other special characters produce malformed URLs that the frontend cannot parse correctly - The custom OAuth client callback handler already correctly uses urllib.parse.quote_plus() for the same purpose; this fix brings the OIDC handler in line with that pattern Co-authored-by: gambletan --- backend/open_webui/utils/oauth.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/open_webui/utils/oauth.py b/backend/open_webui/utils/oauth.py index 249cc62d74..4b6568bee7 100644 --- a/backend/open_webui/utils/oauth.py +++ b/backend/open_webui/utils/oauth.py @@ -1706,7 +1706,7 @@ class OAuthManager: redirect_url = f"{redirect_base_url}/auth" if error_message: - redirect_url = f"{redirect_url}?error={error_message}" + redirect_url = f"{redirect_url}?error={urllib.parse.quote_plus(error_message)}" return RedirectResponse(url=redirect_url, headers=response.headers) response = RedirectResponse(url=redirect_url, headers=response.headers) From 7aa7bbc390c9a2a1bab23c1a4846ed72865e473d Mon Sep 17 00:00:00 2001 From: Alvin Tang <104285249+alvinttang@users.noreply.github.com> Date: Mon, 9 Mar 2026 05:50:25 +0800 Subject: [PATCH 0845/1854] fix: correct Azure TTS locale extraction for SSML xml:lang (#22443) The locale for Azure TTS SSML was being extracted with `split("-")[:1]`, which only takes the first segment (e.g., "en" from "en-US"). The xml:lang attribute in SSML requires a full locale like "en-US", not just a language code. This caused Azure TTS to either fail or use incorrect pronunciation rules. Changed `[:1]` to `[:2]` to properly extract the locale (e.g., "en-US"). Co-authored-by: gambletan --- backend/open_webui/routers/audio.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/open_webui/routers/audio.py b/backend/open_webui/routers/audio.py index 3156078326..65d17d53dd 100644 --- a/backend/open_webui/routers/audio.py +++ b/backend/open_webui/routers/audio.py @@ -492,7 +492,7 @@ async def speech(request: Request, user=Depends(get_verified_user)): region = request.app.state.config.TTS_AZURE_SPEECH_REGION or "eastus" base_url = request.app.state.config.TTS_AZURE_SPEECH_BASE_URL language = request.app.state.config.TTS_VOICE - locale = "-".join(request.app.state.config.TTS_VOICE.split("-")[:1]) + locale = "-".join(request.app.state.config.TTS_VOICE.split("-")[:2]) output_format = request.app.state.config.TTS_AZURE_SPEECH_OUTPUT_FORMAT try: From 3e952044bdf5c79d7281998c478dc61401e8c4ec Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sun, 8 Mar 2026 17:09:41 -0500 Subject: [PATCH 0846/1854] refac --- src/lib/components/layout/Sidebar/ChatItem.svelte | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/lib/components/layout/Sidebar/ChatItem.svelte b/src/lib/components/layout/Sidebar/ChatItem.svelte index 36a76a932c..2653f6ca9b 100644 --- a/src/lib/components/layout/Sidebar/ChatItem.svelte +++ b/src/lib/components/layout/Sidebar/ChatItem.svelte @@ -78,10 +78,6 @@ let chat = null; let mouseOver = false; - let draggable = false; - $: if (mouseOver) { - loadChat(); - } const loadChat = async () => { if (!chat) { @@ -375,7 +371,7 @@ id="sidebar-chat-group" bind:this={itemElement} class=" w-full {className} relative group" - draggable={draggable && !confirmEdit} + draggable={!confirmEdit} > {#if confirmEdit}
Date: Sun, 8 Mar 2026 23:11:12 +0100 Subject: [PATCH 0847/1854] fix: add missing group_id filter to analytics token usage query (#22167) The get_token_usage_by_user query lacked group_id filtering, while the companion get_message_count_by_user query already supported it. When an admin filtered analytics by user group, message counts were correctly scoped to the group but token usage totals included data from all users. Add the group_id parameter and subquery filter to get_token_usage_by_user, matching the pattern used by get_message_count_by_user and other analytics queries, and pass group_id through from the analytics endpoint. --- backend/open_webui/models/chat_messages.py | 9 +++++++++ backend/open_webui/routers/analytics.py | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/backend/open_webui/models/chat_messages.py b/backend/open_webui/models/chat_messages.py index b707ab358b..00609ce7f0 100644 --- a/backend/open_webui/models/chat_messages.py +++ b/backend/open_webui/models/chat_messages.py @@ -420,11 +420,13 @@ class ChatMessageTable: self, start_date: Optional[int] = None, end_date: Optional[int] = None, + group_id: Optional[str] = None, db: Optional[Session] = None, ) -> dict[str, dict]: """Aggregate token usage by user using database-level aggregation.""" with get_db_context(db) as db: from sqlalchemy import func, cast, Integer + from open_webui.models.groups import GroupMember dialect = db.bind.dialect.name @@ -464,6 +466,13 @@ class ChatMessageTable: query = query.filter(ChatMessage.created_at >= start_date) if end_date: query = query.filter(ChatMessage.created_at <= end_date) + if group_id: + group_users = ( + db.query(GroupMember.user_id) + .filter(GroupMember.group_id == group_id) + .subquery() + ) + query = query.filter(ChatMessage.user_id.in_(group_users)) results = query.group_by(ChatMessage.user_id).all() diff --git a/backend/open_webui/routers/analytics.py b/backend/open_webui/routers/analytics.py index 1bd12f7bdb..9579845a49 100644 --- a/backend/open_webui/routers/analytics.py +++ b/backend/open_webui/routers/analytics.py @@ -86,7 +86,7 @@ async def get_user_analytics( start_date=start_date, end_date=end_date, group_id=group_id, db=db ) token_usage = ChatMessages.get_token_usage_by_user( - start_date=start_date, end_date=end_date, db=db + start_date=start_date, end_date=end_date, group_id=group_id, db=db ) # Get user info for top users From 265d1b28242b157026ebfa048e34d00d1c6fa285 Mon Sep 17 00:00:00 2001 From: Code with love <30664075+seulement55@users.noreply.github.com> Date: Mon, 9 Mar 2026 05:13:14 +0700 Subject: [PATCH 0848/1854] Add support for mariadb-vector as backing vector DB (#21931) --- Dockerfile | 1 + backend/open_webui/config.py | 72 +++ .../retrieval/vector/dbs/mariadb_vector.py | 570 ++++++++++++++++++ .../open_webui/retrieval/vector/factory.py | 4 + backend/open_webui/retrieval/vector/type.py | 1 + backend/requirements.txt | 1 + pyproject.toml | 4 + 7 files changed, 653 insertions(+) create mode 100644 backend/open_webui/retrieval/vector/dbs/mariadb_vector.py diff --git a/Dockerfile b/Dockerfile index 1c0ae0b3c8..2a7e9bd20c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -127,6 +127,7 @@ RUN chown -R $UID:$GID /app $HOME RUN apt-get update && \ apt-get install -y --no-install-recommends \ git build-essential pandoc gcc netcat-openbsd curl jq \ + libmariadb-dev \ python3-dev \ ffmpeg libsm6 libxext6 zstd \ && rm -rf /var/lib/apt/lists/* diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index f029b6ba2b..114ccfae7d 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -2359,6 +2359,78 @@ if VECTOR_DB == "chroma": CHROMA_HTTP_SSL = os.environ.get("CHROMA_HTTP_SSL", "false").lower() == "true" # this uses the model defined in the Dockerfile ENV variable. If you dont use docker or docker based deployments such as k8s, the default embedding model will be used (sentence-transformers/all-MiniLM-L6-v2) + +# MariaDB Vector (mariadb-vector) +MARIADB_VECTOR_DB_URL = os.environ.get("MARIADB_VECTOR_DB_URL", "").strip() + +MARIADB_VECTOR_INITIALIZE_MAX_VECTOR_LENGTH = int( + os.environ.get("MARIADB_VECTOR_INITIALIZE_MAX_VECTOR_LENGTH", "1536").strip() or "1536" +) + +# Distance strategy: +# - cosine => vec_distance_cosine(...) +# - euclidean => vec_distance_euclidean(...) +MARIADB_VECTOR_DISTANCE_STRATEGY = ( + os.environ.get("MARIADB_VECTOR_DISTANCE_STRATEGY", "cosine").strip().lower() +) + +# HNSW M parameter (MariaDB VECTOR INDEX ... M=) +MARIADB_VECTOR_INDEX_M = int(os.environ.get("MARIADB_VECTOR_INDEX_M", "8").strip() or "8") + +# Pooling (MariaDB-Vector) +MARIADB_VECTOR_POOL_SIZE = os.environ.get("MARIADB_VECTOR_POOL_SIZE", None) + +if MARIADB_VECTOR_POOL_SIZE != None: + try: + MARIADB_VECTOR_POOL_SIZE = int(MARIADB_VECTOR_POOL_SIZE) + except Exception: + MARIADB_VECTOR_POOL_SIZE = None + +MARIADB_VECTOR_POOL_MAX_OVERFLOW = os.environ.get("MARIADB_VECTOR_POOL_MAX_OVERFLOW", 0) + +if MARIADB_VECTOR_POOL_MAX_OVERFLOW == "": + MARIADB_VECTOR_POOL_MAX_OVERFLOW = 0 +else: + try: + MARIADB_VECTOR_POOL_MAX_OVERFLOW = int(MARIADB_VECTOR_POOL_MAX_OVERFLOW) + except Exception: + MARIADB_VECTOR_POOL_MAX_OVERFLOW = 0 + +MARIADB_VECTOR_POOL_TIMEOUT = os.environ.get("MARIADB_VECTOR_POOL_TIMEOUT", 30) + +if MARIADB_VECTOR_POOL_TIMEOUT == "": + MARIADB_VECTOR_POOL_TIMEOUT = 30 +else: + try: + MARIADB_VECTOR_POOL_TIMEOUT = int(MARIADB_VECTOR_POOL_TIMEOUT) + except Exception: + MARIADB_VECTOR_POOL_TIMEOUT = 30 + +MARIADB_VECTOR_POOL_RECYCLE = os.environ.get("MARIADB_VECTOR_POOL_RECYCLE", 3600) + +if MARIADB_VECTOR_POOL_RECYCLE == "": + MARIADB_VECTOR_POOL_RECYCLE = 3600 +else: + try: + MARIADB_VECTOR_POOL_RECYCLE = int(MARIADB_VECTOR_POOL_RECYCLE) + except Exception: + MARIADB_VECTOR_POOL_RECYCLE = 3600 + +ENABLE_MARIADB_VECTOR = True +if VECTOR_DB == "mariadb-vector": + if not MARIADB_VECTOR_DB_URL: + ENABLE_MARIADB_VECTOR = False + else: + try: + parsed = urlparse(MARIADB_VECTOR_DB_URL) + scheme = (parsed.scheme or "").lower() + # Require official driver so VECTOR binds as float32 bytes correctly + if scheme != "mariadb+mariadbconnector": + ENABLE_MARIADB_VECTOR = False + except Exception: + ENABLE_MARIADB_VECTOR = False + + # Milvus MILVUS_URI = os.environ.get("MILVUS_URI", f"{DATA_DIR}/vector_db/milvus.db") MILVUS_DB = os.environ.get("MILVUS_DB", "default") diff --git a/backend/open_webui/retrieval/vector/dbs/mariadb_vector.py b/backend/open_webui/retrieval/vector/dbs/mariadb_vector.py new file mode 100644 index 0000000000..06d11adec6 --- /dev/null +++ b/backend/open_webui/retrieval/vector/dbs/mariadb_vector.py @@ -0,0 +1,570 @@ +from __future__ import annotations + +import array +import json +import logging +import math +import re +import sys +from contextlib import contextmanager +from typing import Any, Dict, List, Optional, Tuple + +from sqlalchemy import create_engine +from sqlalchemy.pool import NullPool, QueuePool + +from open_webui.config import ( + MARIADB_VECTOR_DB_URL, + MARIADB_VECTOR_DISTANCE_STRATEGY, + MARIADB_VECTOR_INDEX_M, + MARIADB_VECTOR_INITIALIZE_MAX_VECTOR_LENGTH, + MARIADB_VECTOR_POOL_SIZE, + MARIADB_VECTOR_POOL_MAX_OVERFLOW, + MARIADB_VECTOR_POOL_TIMEOUT, + MARIADB_VECTOR_POOL_RECYCLE, +) +from open_webui.retrieval.vector.main import GetResult, SearchResult, VectorDBBase, VectorItem +from open_webui.retrieval.vector.utils import process_metadata + +log = logging.getLogger(__name__) + +VECTOR_LENGTH = int(MARIADB_VECTOR_INITIALIZE_MAX_VECTOR_LENGTH) + + +def _embedding_to_f32_bytes(vec: List[float]) -> bytes: + """ + Convert a Python float vector into the binary payload expected by MariaDB VECTOR. + + MariaDB Vector expects the vector argument to be bound as a little-endian float32 + byte sequence. We use array('f') to avoid a numpy dependency and byteswap on + big-endian platforms for portability. + """ + a = array.array("f", [float(x) for x in vec]) # float32 + if sys.byteorder != "little": + a.byteswap() + return a.tobytes() + + +def _safe_json(v: Any) -> Dict[str, Any]: + """ + Normalize a potentially JSON-like value into a Python dict. + + Accepts: + - dict: returned as-is + - str / bytes: parsed as JSON if possible + - None / other types: returns {} + """ + if v is None: + return {} + if isinstance(v, dict): + return v + if isinstance(v, (bytes, bytearray)): + try: + v = v.decode("utf-8") + except Exception: + return {} + if isinstance(v, str): + try: + j = json.loads(v) + return j if isinstance(j, dict) else {} + except Exception: + return {} + return {} + + +class MariaDBVectorClient(VectorDBBase): + """ + MariaDB + MariaDB Vector backend using DBAPI cursor parameter binding. + + IMPORTANT: + - Intended for: mariadb+mariadbconnector://... (official MariaDB driver). + - Uses qmark ("?") params and binds vectors as float32 bytes. + - Uses binary binding for BOTH inserts/updates and distance computations. + """ + + def __init__( + self, + db_url: Optional[str] = None, + vector_length: int = VECTOR_LENGTH, + distance_strategy: str = MARIADB_VECTOR_DISTANCE_STRATEGY, + index_m: int = MARIADB_VECTOR_INDEX_M, + ) -> None: + """ + Initialize a MariaDB Vector-backed VectorDBBase implementation. + + Validates URL scheme/driver requirements, ensures schema exists, and guards + against dimension mismatch with an existing VECTOR(n) column. + """ + self.db_url = (db_url or MARIADB_VECTOR_DB_URL).strip() + self.vector_length = int(vector_length) + self.distance_strategy = (distance_strategy or "cosine").strip().lower() + self.index_m = int(index_m) + + if self.distance_strategy not in {"cosine", "euclidean"}: + raise ValueError("distance_strategy must be 'cosine' or 'euclidean'") + + if not self.db_url.lower().startswith("mariadb+mariadbconnector://"): + raise ValueError( + "MariaDBVectorClient requires mariadb+mariadbconnector:// (official MariaDB driver) " + "to ensure qmark paramstyle and correct VECTOR binding." + ) + + if isinstance(MARIADB_VECTOR_POOL_SIZE, int): + if MARIADB_VECTOR_POOL_SIZE > 0: + self.engine = create_engine( + self.db_url, + pool_size=MARIADB_VECTOR_POOL_SIZE, + max_overflow=MARIADB_VECTOR_POOL_MAX_OVERFLOW, + pool_timeout=MARIADB_VECTOR_POOL_TIMEOUT, + pool_recycle=MARIADB_VECTOR_POOL_RECYCLE, + pool_pre_ping=True, + poolclass=QueuePool, + ) + else: + self.engine = create_engine( + self.db_url, pool_pre_ping=True, poolclass=NullPool + ) + else: + self.engine = create_engine(self.db_url, pool_pre_ping=True) + self._init_schema() + self._check_vector_length() + + @contextmanager + def _connect(self): + """ + Yield a context-managed DBAPI connection (SQLAlchemy raw_connection()). + + Callers can use: + with self._connect() as conn: + with conn.cursor() as cur: + ... + """ + conn = self.engine.raw_connection() + try: + yield conn + finally: + try: + conn.close() + except Exception: + pass + + def _init_schema(self) -> None: + """ + Create the backing table and vector index if they do not exist. + + Uses a PK definition compatible with MariaDB Vector's VECTOR INDEX key-size constraints. + """ + with self._connect() as conn: + with conn.cursor() as cur: + try: + dist = self.distance_strategy + cur.execute( + f""" + CREATE TABLE IF NOT EXISTS document_chunk ( + -- MariaDB Vector requires the table PRIMARY KEY used with a VECTOR INDEX to be <= 256 bytes. + -- VARCHAR has internal length/metadata overhead, so VARCHAR(255) can exceed the 256-byte limit. + -- We use VARCHAR(254) to stay safely under the limit, and force ASCII (1 byte/char) so the byte + -- size is predictable (avoid utf8mb4 where a "255 char" key could be up to 1020 bytes). + -- ascii_bin gives bytewise, case-sensitive comparisons for stable ID matching. + id VARCHAR(254) CHARACTER SET ascii COLLATE ascii_bin PRIMARY KEY, + embedding VECTOR({self.vector_length}) NOT NULL, + collection_name VARCHAR(255) NOT NULL, + text LONGTEXT NULL, + vmetadata JSON NULL, + VECTOR INDEX (embedding) M={self.index_m} DISTANCE={dist}, + INDEX idx_document_chunk_collection_name (collection_name) + ) ENGINE=InnoDB; + """ + ) + conn.commit() + except Exception as e: + conn.rollback() + log.exception(f"Error during database initialization: {e}") + raise + + def _check_vector_length(self) -> None: + """ + Validate that the existing VECTOR column dimension matches this client's configured dimension. + + Dimension guard: if table already exists with + a different VECTOR(n), refuse to silently mismatch. + """ + with self._connect() as conn: + with conn.cursor() as cur: + cur.execute("SHOW CREATE TABLE document_chunk") + row = cur.fetchone() + if not row or len(row) < 2: + return + ddl = row[1] + m = re.search(r"vector\\((\\d+)\\)", ddl, flags=re.IGNORECASE) + if not m: + return + existing = int(m.group(1)) + if existing != int(self.vector_length): + raise Exception( + f"VECTOR_LENGTH {self.vector_length} does not match existing vector column dimension {existing}. " + "Cannot change vector size after initialization without migrating the data." + ) + + def adjust_vector_length(self, vector: List[float]) -> List[float]: + """ + Pad or truncate a vector to match `self.vector_length`. + """ + n = len(vector) + if n < self.vector_length: + return vector + [0.0] * (self.vector_length - n) + if n > self.vector_length: + return vector[: self.vector_length] + return vector + + def _dist_fn(self) -> str: + """ + Return the MariaDB Vector distance function name for the configured strategy. + """ + return "vec_distance_cosine" if self.distance_strategy == "cosine" else "vec_distance_euclidean" + + def _score_from_dist(self, dist: float) -> float: + """ + Convert a DB distance value into a normalized score in (0, 1]. + + - cosine: score ~= 1 - cosine_distance, clamped to [0, 1] + - euclidean: score = 1 / (1 + dist) + """ + if self.distance_strategy == "cosine": + score = 1.0 - dist + if score < 0.0: + score = 0.0 + if score > 1.0: + score = 1.0 + return score + return 1.0 / (1.0 + max(0.0, dist)) + + def _build_filter_sql_qmark(self, expr: Any) -> Tuple[str, List[Any]]: + """ + Build a WHERE-clause fragment and qmark params from a minimal Mongo-like filter. + + Supported forms: + - {"field": "v"} + - {"field": {"$in": ["a","b"]}} + - {"$and": [ ... ]} + - {"$or": [ ... ]} + """ + if not expr or not isinstance(expr, dict): + return "", [] + + if "$and" in expr: + parts: List[str] = [] + params: List[Any] = [] + for e in expr.get("$and") or []: + s, p = self._build_filter_sql_qmark(e) + if s: + parts.append(s) + params.extend(p) + return ("(" + " AND ".join(parts) + ")") if parts else "", params + + if "$or" in expr: + parts: List[str] = [] + params: List[Any] = [] + for e in expr.get("$or") or []: + s, p = self._build_filter_sql_qmark(e) + if s: + parts.append(s) + params.extend(p) + return ("(" + " OR ".join(parts) + ")") if parts else "", params + + clauses: List[str] = [] + params: List[Any] = [] + for key, value in expr.items(): + if key.startswith("$"): + continue + json_expr = f"JSON_UNQUOTE(JSON_EXTRACT(vmetadata, '$.{key}'))" + if isinstance(value, dict) and "$in" in value: + vals = [str(v) for v in (value.get("$in") or [])] + if not vals: + clauses.append("0=1") + continue + ors = [] + for v in vals: + ors.append(f"{json_expr} = ?") + params.append(v) + clauses.append("(" + " OR ".join(ors) + ")") + else: + clauses.append(f"{json_expr} = ?") + params.append(str(value)) + return ("(" + " AND ".join(clauses) + ")") if clauses else "", params + + def insert(self, collection_name: str, items: List[VectorItem]) -> None: + """ + Insert items into the given collection (best-effort, ignores duplicates). + + Uses executemany() with binary VECTOR binding for high-throughput ingestion. + """ + if not items: + return + with self._connect() as conn: + with conn.cursor() as cur: + try: + sql = """ + INSERT IGNORE INTO document_chunk + (id, embedding, collection_name, text, vmetadata) + VALUES + (?, ?, ?, ?, ?) + """ + params: List[Tuple[Any, ...]] = [] + for item in items: + v = self.adjust_vector_length(item["vector"]) + emb = _embedding_to_f32_bytes(v) + meta = process_metadata(item.get("metadata") or {}) + params.append( + ( + item["id"], + emb, + collection_name, + item.get("text"), + json.dumps(meta), + ) + ) + cur.executemany(sql, params) + conn.commit() + except Exception as e: + conn.rollback() + log.exception(f"Error during insert: {e}") + raise + + def upsert(self, collection_name: str, items: List[VectorItem]) -> None: + """ + Insert or update items in the given collection by primary key. + + Uses executemany() and updates embedding/text/metadata on conflicts. + """ + if not items: + return + with self._connect() as conn: + with conn.cursor() as cur: + try: + sql = """ + INSERT INTO document_chunk + (id, embedding, collection_name, text, vmetadata) + VALUES + (?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + embedding = VALUES(embedding), + collection_name = VALUES(collection_name), + text = VALUES(text), + vmetadata = VALUES(vmetadata) + """ + params: List[Tuple[Any, ...]] = [] + for item in items: + v = self.adjust_vector_length(item["vector"]) + emb = _embedding_to_f32_bytes(v) + meta = process_metadata(item.get("metadata") or {}) + params.append( + ( + item["id"], + emb, + collection_name, + item.get("text"), + json.dumps(meta), + ) + ) + cur.executemany(sql, params) + conn.commit() + except Exception as e: + conn.rollback() + log.exception(f"Error during upsert: {e}") + raise + + def search( + self, + collection_name: str, + vectors: List[List[float]], + filter: Optional[Dict[str, Any]] = None, + limit: int = 10, + ) -> Optional[SearchResult]: + """ + Perform a vector similarity search. + + Args: + collection_name: Logical collection partition key. + vectors: One or more query vectors. + filter: Optional metadata filter (Mongo-like subset). + limit: Top-k per query vector. + + Returns a SearchResult where distances are normalized scores (higher is better). + """ + if not vectors: + return None + + dist_fn = self._dist_fn() + ids: List[List[str]] = [[] for _ in vectors] + distances: List[List[float]] = [[] for _ in vectors] + documents: List[List[str]] = [[] for _ in vectors] + metadatas: List[List[Any]] = [[] for _ in vectors] + + try: + with self._connect() as conn: + with conn.cursor() as cur: + fsql, fparams = self._build_filter_sql_qmark(filter or {}) + where = "collection_name = ?" + base_params: List[Any] = [collection_name] + if fsql: + where = where + " AND " + fsql + base_params.extend(fparams) + + sql = f""" + SELECT + id, + text, + vmetadata, + {dist_fn}(embedding, ?) AS dist + FROM document_chunk + WHERE {where} + ORDER BY dist ASC + LIMIT ? + """ + + for q_idx, q in enumerate(vectors): + qv = self.adjust_vector_length(q) + qbin = _embedding_to_f32_bytes(qv) + params = [qbin] + list(base_params) + [int(limit)] + cur.execute(sql, params) + rows = cur.fetchall() + + for r in rows: + rid, rtext, rmeta, rdist = r[0], r[1], r[2], r[3] + ids[q_idx].append(str(rid)) + try: + dist = float(rdist) if rdist is not None else 1.0 + except Exception: + dist = 1.0 + if math.isnan(dist) or math.isinf(dist): + dist = 1.0 + distances[q_idx].append(self._score_from_dist(dist)) + documents[q_idx].append(rtext) + metadatas[q_idx].append(_safe_json(rmeta)) + + return SearchResult(ids=ids, distances=distances, documents=documents, metadatas=metadatas) + except Exception as e: + log.exception(f"[MARIADB_VECTOR] search() failed: {e}") + return None + + def query(self, collection_name: str, filter: Dict[str, Any], limit: Optional[int] = None) -> Optional[GetResult]: + """ + Retrieve documents by metadata filter (non-vector query). + """ + with self._connect() as conn: + with conn.cursor() as cur: + fsql, fparams = self._build_filter_sql_qmark(filter or {}) + where = "collection_name = ?" + params: List[Any] = [collection_name] + if fsql: + where = where + " AND " + fsql + params.extend(fparams) + sql = f"SELECT id, text, vmetadata FROM document_chunk WHERE {where}" + if limit is not None: + sql += " LIMIT ?" + params.append(int(limit)) + cur.execute(sql, params) + rows = cur.fetchall() + if not rows: + return None + ids = [[str(r[0]) for r in rows]] + documents = [[r[1] for r in rows]] + metadatas = [[_safe_json(r[2]) for r in rows]] + return GetResult(ids=ids, documents=documents, metadatas=metadatas) + + def get(self, collection_name: str, limit: Optional[int] = None) -> Optional[GetResult]: + """ + Retrieve documents in a collection without filtering (optionally limited). + """ + with self._connect() as conn: + with conn.cursor() as cur: + sql = "SELECT id, text, vmetadata FROM document_chunk WHERE collection_name = ?" + params: List[Any] = [collection_name] + if limit is not None: + sql += " LIMIT ?" + params.append(int(limit)) + cur.execute(sql, params) + rows = cur.fetchall() + if not rows: + return None + ids = [[str(r[0]) for r in rows]] + documents = [[r[1] for r in rows]] + metadatas = [[_safe_json(r[2]) for r in rows]] + return GetResult(ids=ids, documents=documents, metadatas=metadatas) + + def delete( + self, + collection_name: str, + ids: Optional[List[str]] = None, + filter: Optional[Dict[str, Any]] = None, + ) -> None: + """ + Delete rows from a collection by id list and/or metadata filter. + + If both are provided, they are combined with AND semantics. + """ + with self._connect() as conn: + with conn.cursor() as cur: + try: + where = ["collection_name = ?"] + params: List[Any] = [collection_name] + + if ids: + ph = ", ".join(["?"] * len(ids)) + where.append(f"id IN ({ph})") + params.extend(ids) + + if filter: + fsql, fparams = self._build_filter_sql_qmark(filter) + if fsql: + where.append(fsql) + params.extend(fparams) + + sql = "DELETE FROM document_chunk WHERE " + " AND ".join(where) + cur.execute(sql, params) + conn.commit() + except Exception as e: + conn.rollback() + log.exception(f"Error during delete: {e}") + raise + + def reset(self) -> None: + """ + Truncate the vector table (drops all collections). + """ + with self._connect() as conn: + with conn.cursor() as cur: + try: + cur.execute("TRUNCATE TABLE document_chunk") + conn.commit() + except Exception as e: + conn.rollback() + log.exception(f"Error during reset: {e}") + raise + + def has_collection(self, collection_name: str) -> bool: + """ + Return True if the collection contains at least one row, else False. + """ + try: + with self._connect() as conn: + with conn.cursor() as cur: + cur.execute("SELECT 1 FROM document_chunk WHERE collection_name = ? LIMIT 1", (collection_name,)) + return cur.fetchone() is not None + except Exception: + return False + + def delete_collection(self, collection_name: str) -> None: + """ + Delete all rows in a collection. + """ + self.delete(collection_name) + + def close(self) -> None: + """ + Dispose the underlying SQLAlchemy engine. + """ + try: + self.engine.dispose() + except Exception as e: + log.exception(f"Error during dispose the underlying SQLAlchemy engine: {e}") diff --git a/backend/open_webui/retrieval/vector/factory.py b/backend/open_webui/retrieval/vector/factory.py index 68595fb595..f1ead76d84 100644 --- a/backend/open_webui/retrieval/vector/factory.py +++ b/backend/open_webui/retrieval/vector/factory.py @@ -57,6 +57,10 @@ class Vector: from open_webui.retrieval.vector.dbs.opengauss import OpenGaussClient return OpenGaussClient() + case VectorType.MARIADB_VECTOR: + from open_webui.retrieval.vector.dbs.mariadb_vector import MariaDBVectorClient + + return MariaDBVectorClient() case VectorType.ELASTICSEARCH: from open_webui.retrieval.vector.dbs.elasticsearch import ( ElasticsearchClient, diff --git a/backend/open_webui/retrieval/vector/type.py b/backend/open_webui/retrieval/vector/type.py index de20133fce..df9453aa3e 100644 --- a/backend/open_webui/retrieval/vector/type.py +++ b/backend/open_webui/retrieval/vector/type.py @@ -3,6 +3,7 @@ from enum import StrEnum class VectorType(StrEnum): MILVUS = "milvus" + MARIADB_VECTOR = "mariadb-vector" QDRANT = "qdrant" CHROMA = "chroma" PINECONE = "pinecone" diff --git a/backend/requirements.txt b/backend/requirements.txt index 86bb8d23a1..295b6cfa89 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -119,6 +119,7 @@ pgvector==0.4.2 PyMySQL==1.1.2 boto3==1.42.62 +mariadb==1.1.14 pymilvus==2.6.9 qdrant-client==1.17.0 diff --git a/pyproject.toml b/pyproject.toml index 251240ac48..2ec9d033b9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -137,11 +137,15 @@ postgres = [ "psycopg2-binary==2.9.11", "pgvector==0.4.2", ] +mariadb = [ + "mariadb==1.1.14", +] all = [ "pymongo", "psycopg2-binary==2.9.11", "pgvector==0.4.2", + "mariadb==1.1.14", "moto[s3]>=5.0.26", "gcp-storage-emulator>=2024.8.3", "docker~=7.1.0", From d513eb8c4d5e2d881392f8390f905c93219ced70 Mon Sep 17 00:00:00 2001 From: fama-05 <185788143+fama-05@users.noreply.github.com> Date: Sun, 8 Mar 2026 23:14:43 +0100 Subject: [PATCH 0849/1854] Update Citations.svelte (#21897) Add on:error handler to img --- src/lib/components/chat/Messages/Citations.svelte | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib/components/chat/Messages/Citations.svelte b/src/lib/components/chat/Messages/Citations.svelte index 1940448685..8f0d93ce6d 100644 --- a/src/lib/components/chat/Messages/Citations.svelte +++ b/src/lib/components/chat/Messages/Citations.svelte @@ -178,6 +178,9 @@ src="https://www.google.com/s2/favicons?sz=32&domain={citation.source.name}" alt="favicon" class="size-4 rounded-full shrink-0 border border-white dark:border-gray-850 bg-white dark:bg-gray-900" + on:error={(e) => { + e.target.src = '/favicon.png'; + }} /> {/each}
From c97767424f6ac7daf61daa84e15cdb10f1965d36 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sun, 8 Mar 2026 17:26:29 -0500 Subject: [PATCH 0850/1854] refac/fix --- backend/open_webui/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index 202bd32c1d..f13d317108 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -1732,8 +1732,8 @@ async def chat_completion( } # Check base model existence for custom models - if model_info_params.get("base_model_id"): - base_model_id = model_info_params.get("base_model_id") + if model_info and model_info.base_model_id: + base_model_id = model_info.base_model_id if base_model_id not in request.app.state.MODELS: if ENABLE_CUSTOM_MODEL_FALLBACK: default_models = ( From defeddf21b450e207d51ec9479049a905a7ee9e0 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sun, 8 Mar 2026 17:28:26 -0500 Subject: [PATCH 0851/1854] fix: display image thumbnails in pending message queue Previously, QueuedMessageItem only rendered text content and ignored the files array, causing queued messages with only images to appear blank. Now passes files to the component and renders image thumbnails and file name indicators inline. Fixes #22256 --- src/lib/components/chat/MessageInput.svelte | 1 + .../MessageInput/QueuedMessageItem.svelte | 33 +++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index 9bf3a08139..4664940d3a 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -1187,6 +1187,7 @@ import { getContext } from 'svelte'; import Tooltip from '$lib/components/common/Tooltip.svelte'; + import Image from '$lib/components/common/Image.svelte'; import GarbageBin from '$lib/components/icons/GarbageBin.svelte'; import EditPencil from '$lib/components/icons/EditPencil.svelte'; import ArrowForward from '$lib/components/icons/ArrowForward.svelte'; + import { WEBUI_API_BASE_URL } from '$lib/constants'; const i18n = getContext('i18n'); export let id: string; export let content: string; + export let files: any[] = []; export let onSendNow: (id: string) => void; export let onEdit: (id: string) => void; export let onDelete: (id: string) => void; @@ -21,8 +24,34 @@
-
-

{content}

+
+ {#if files.length > 0} +
+ {#each files as file} + {#if file.type === 'image' || (file?.content_type ?? '').startsWith('image/')} + {@const fileUrl = + file.url?.startsWith('data') || file.url?.startsWith('http') + ? file.url + : `${WEBUI_API_BASE_URL}/files/${file.url}${file?.content_type ? '/content' : ''}`} + + {:else} +
+ {file.name ?? 'file'} +
+ {/if} + {/each} +
+ {/if} + + {#if content} +

{content}

+ {:else if files.length === 0} +

{$i18n.t('Empty message')}

+ {/if}
From 9d8f590fc516d8ba80e2eaa86f82a6a37f9e4b51 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sun, 8 Mar 2026 17:43:23 -0500 Subject: [PATCH 0852/1854] feat: support pipe filters for per-message content truncation in task templates Add |middletruncate:n, |start:n, and |end:n pipe filters to the {{MESSAGES}} template variable, enabling per-message character truncation for task models (title, tags, follow-up, etc.). Example: {{MESSAGES:END:2|middletruncate:500}} This optimizes task model prompt size for conversations with very long messages (e.g. pasted documents), reducing latency for local models and API costs. Closes #21499 --- backend/open_webui/utils/task.py | 126 +++++++++++++++++++++++++------ 1 file changed, 105 insertions(+), 21 deletions(-) diff --git a/backend/open_webui/utils/task.py b/backend/open_webui/utils/task.py index abc8920884..f5177eb787 100644 --- a/backend/open_webui/utils/task.py +++ b/backend/open_webui/utils/task.py @@ -142,41 +142,125 @@ def replace_prompt_variable(template: str, prompt: str) -> str: return template +def truncate_content(content: str, max_chars: int, mode: str = "middletruncate") -> str: + """Truncate a string to max_chars using the specified mode. + + Modes: + - middletruncate: keep beginning and end, join with '...' + - start: keep first max_chars characters + - end: keep last max_chars characters + """ + if not content or len(content) <= max_chars: + return content + + if mode == "start": + return content[:max_chars] + elif mode == "end": + return content[-max_chars:] + else: # middletruncate + half = max_chars // 2 + return f"{content[:half]}...{content[-(max_chars - half):]}" + + +def apply_content_filter( + messages: list[dict], filter_str: str +) -> list[dict]: + """Apply a content filter to each message's content. + + filter_str is like 'middletruncate:500', 'start:200', or 'end:200'. + Returns a new list with truncated content (original messages are not mutated). + """ + parts = filter_str.split(":") + if len(parts) != 2: + return messages + + mode = parts[0].lower() + try: + max_chars = int(parts[1]) + except ValueError: + return messages + + if mode not in ("middletruncate", "start", "end"): + return messages + + result = [] + for msg in messages: + new_msg = dict(msg) + if isinstance(new_msg.get("content"), str): + new_msg["content"] = truncate_content(new_msg["content"], max_chars, mode) + elif isinstance(new_msg.get("content"), list): + new_content = [] + for item in new_msg["content"]: + if isinstance(item, dict) and item.get("type") == "text": + new_item = dict(item) + new_item["text"] = truncate_content( + item.get("text", ""), max_chars, mode + ) + new_content.append(new_item) + else: + new_content.append(item) + new_msg["content"] = new_content + result.append(new_msg) + return result + + def replace_messages_variable( template: str, messages: Optional[list[dict]] = None ) -> str: def replacement_function(match): - full_match = match.group(0) - start_length = match.group(1) - end_length = match.group(2) - middle_length = match.group(3) + # Groups: (1) filter for bare MESSAGES + # (2) START count, (3) filter for START + # (4) END count, (5) filter for END + # (6) MIDDLE count,(7) filter for MIDDLE + bare_filter = match.group(1) + start_length = match.group(2) + start_filter = match.group(3) + end_length = match.group(4) + end_filter = match.group(5) + middle_length = match.group(6) + middle_filter = match.group(7) + # If messages is None, handle it as an empty list if messages is None: return "" - # Process messages based on the number of messages required - if full_match == "{{MESSAGES}}": - return get_messages_content(messages) - elif start_length is not None: - return get_messages_content(messages[: int(start_length)]) + # Select messages based on the variant + if start_length is not None: + selected = messages[: int(start_length)] + content_filter = start_filter elif end_length is not None: - return get_messages_content(messages[-int(end_length) :]) + selected = messages[-int(end_length) :] + content_filter = end_filter elif middle_length is not None: mid = int(middle_length) - if len(messages) <= mid: - return get_messages_content(messages) - # Handle middle truncation: split to get start and end portions of the messages list - half = mid // 2 - start_msgs = messages[:half] - end_msgs = messages[-half:] if mid % 2 == 0 else messages[-(half + 1) :] - formatted_start = get_messages_content(start_msgs) - formatted_end = get_messages_content(end_msgs) - return f"{formatted_start}\n{formatted_end}" - return "" + selected = messages + else: + half = mid // 2 + start_msgs = messages[:half] + end_msgs = ( + messages[-half:] if mid % 2 == 0 else messages[-(half + 1) :] + ) + selected = start_msgs + end_msgs + content_filter = middle_filter + else: + # Bare {{MESSAGES}} or {{MESSAGES|filter}} + selected = messages + content_filter = bare_filter + + # Apply content filter if present + if content_filter: + selected = apply_content_filter(selected, content_filter) + + return get_messages_content(selected) template = re.sub( - r"{{MESSAGES}}|{{MESSAGES:START:(\d+)}}|{{MESSAGES:END:(\d+)}}|{{MESSAGES:MIDDLETRUNCATE:(\d+)}}", + r"(?:" + r"\{\{MESSAGES(?:\|(\w+:\d+))?\}\}" + r"|\{\{MESSAGES:START:(\d+)(?:\|(\w+:\d+))?\}\}" + r"|\{\{MESSAGES:END:(\d+)(?:\|(\w+:\d+))?\}\}" + r"|\{\{MESSAGES:MIDDLETRUNCATE:(\d+)(?:\|(\w+:\d+))?\}\}" + r")", replacement_function, template, ) From 3f350f865920daf2844769a758b2d2e6a7ee3efa Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sun, 8 Mar 2026 17:52:49 -0500 Subject: [PATCH 0853/1854] refac --- backend/open_webui/config.py | 11 +++++++++-- backend/open_webui/routers/auths.py | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index 114ccfae7d..79421874eb 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -469,6 +469,12 @@ OPENID_PROVIDER_URL = PersistentConfig( os.environ.get("OPENID_PROVIDER_URL", ""), ) +OPENID_END_SESSION_ENDPOINT = PersistentConfig( + "OPENID_END_SESSION_ENDPOINT", + "oauth.oidc.end_session_endpoint", + os.environ.get("OPENID_END_SESSION_ENDPOINT", ""), +) + OPENID_REDIRECT_URI = PersistentConfig( "OPENID_REDIRECT_URI", "oauth.oidc.redirect_uri", @@ -844,13 +850,14 @@ def load_oauth_providers(): if FEISHU_CLIENT_ID.value: configured_providers.append("Feishu") - if configured_providers and not OPENID_PROVIDER_URL.value: + if configured_providers and not OPENID_PROVIDER_URL.value and not OPENID_END_SESSION_ENDPOINT.value: provider_list = ", ".join(configured_providers) log.warning( f"⚠️ OAuth providers configured ({provider_list}) but OPENID_PROVIDER_URL not set - logout will not work!" ) log.warning( - f"Set OPENID_PROVIDER_URL to your OAuth provider's OpenID Connect discovery endpoint to fix logout functionality." + f"Set OPENID_PROVIDER_URL to your OAuth provider's OpenID Connect discovery endpoint," + f" or set OPENID_END_SESSION_ENDPOINT to a custom logout URL to fix logout functionality." ) diff --git a/backend/open_webui/routers/auths.py b/backend/open_webui/routers/auths.py index f3c4fbc6d4..f5a60c59e6 100644 --- a/backend/open_webui/routers/auths.py +++ b/backend/open_webui/routers/auths.py @@ -46,6 +46,7 @@ from fastapi import APIRouter, Depends, HTTPException, Request, status from fastapi.responses import RedirectResponse, Response, JSONResponse from open_webui.config import ( OPENID_PROVIDER_URL, + OPENID_END_SESSION_ENDPOINT, ENABLE_OAUTH_SIGNUP, ENABLE_LDAP, ENABLE_PASSWORD_AUTH, @@ -824,6 +825,19 @@ async def signout( response.delete_cookie("oauth_session_id") session = OAuthSessions.get_session_by_id(oauth_session_id, db=db) + + # If a custom end_session_endpoint is configured (e.g. AWS Cognito), redirect + # there directly instead of attempting OIDC discovery. + if OPENID_END_SESSION_ENDPOINT.value: + return JSONResponse( + status_code=200, + content={ + "status": True, + "redirect_url": OPENID_END_SESSION_ENDPOINT.value, + }, + headers=response.headers, + ) + oauth_server_metadata_url = ( request.app.state.oauth_manager.get_server_metadata_url(session.provider) if session From 2cb28369b76434ef9a7ae318e27cb3f28951cfa9 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sun, 8 Mar 2026 18:08:12 -0500 Subject: [PATCH 0854/1854] refac --- backend/open_webui/models/files.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/models/files.py b/backend/open_webui/models/files.py index 09060f9bde..59459cfb90 100644 --- a/backend/open_webui/models/files.py +++ b/backend/open_webui/models/files.py @@ -289,7 +289,7 @@ class FilesTable: db: Optional database session. Returns: - List of matching FileModel objects, ordered by updated_at descending. + List of matching FileModel objects, ordered by created_at descending. """ with get_db_context(db) as db: query = db.query(File) @@ -303,7 +303,7 @@ class FilesTable: return [ FileModel.model_validate(file) - for file in query.order_by(File.updated_at.desc()) + for file in query.order_by(File.created_at.desc(), File.id.desc()) .offset(skip) .limit(limit) .all() From 352391fa76a42384963753f9d5b6ec1bdb37930d Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sun, 8 Mar 2026 18:14:09 -0500 Subject: [PATCH 0855/1854] chore: format --- backend/open_webui/config.py | 13 +++++-- backend/open_webui/retrieval/utils.py | 8 +++- .../retrieval/vector/dbs/mariadb_vector.py | 39 ++++++++++++++----- .../open_webui/retrieval/vector/factory.py | 4 +- backend/open_webui/routers/files.py | 1 + backend/open_webui/routers/ollama.py | 4 +- backend/open_webui/utils/oauth.py | 4 +- backend/open_webui/utils/task.py | 8 +--- backend/open_webui/utils/webhook.py | 3 +- .../MessageInput/QueuedMessageItem.svelte | 14 +++---- src/lib/i18n/locales/ar-BH/translation.json | 1 + src/lib/i18n/locales/ar/translation.json | 1 + src/lib/i18n/locales/bg-BG/translation.json | 1 + src/lib/i18n/locales/bn-BD/translation.json | 1 + src/lib/i18n/locales/bo-TB/translation.json | 1 + src/lib/i18n/locales/bs-BA/translation.json | 1 + src/lib/i18n/locales/ca-ES/translation.json | 1 + src/lib/i18n/locales/ceb-PH/translation.json | 1 + src/lib/i18n/locales/cs-CZ/translation.json | 1 + src/lib/i18n/locales/da-DK/translation.json | 1 + src/lib/i18n/locales/de-DE/translation.json | 1 + src/lib/i18n/locales/dg-DG/translation.json | 1 + src/lib/i18n/locales/el-GR/translation.json | 1 + src/lib/i18n/locales/en-GB/translation.json | 1 + src/lib/i18n/locales/en-US/translation.json | 1 + src/lib/i18n/locales/es-ES/translation.json | 1 + src/lib/i18n/locales/et-EE/translation.json | 1 + src/lib/i18n/locales/eu-ES/translation.json | 1 + src/lib/i18n/locales/fa-IR/translation.json | 1 + src/lib/i18n/locales/fi-FI/translation.json | 1 + src/lib/i18n/locales/fr-CA/translation.json | 1 + src/lib/i18n/locales/fr-FR/translation.json | 1 + src/lib/i18n/locales/gl-ES/translation.json | 1 + src/lib/i18n/locales/he-IL/translation.json | 1 + src/lib/i18n/locales/hi-IN/translation.json | 1 + src/lib/i18n/locales/hr-HR/translation.json | 1 + src/lib/i18n/locales/hu-HU/translation.json | 1 + src/lib/i18n/locales/id-ID/translation.json | 1 + src/lib/i18n/locales/ie-GA/translation.json | 1 + src/lib/i18n/locales/it-IT/translation.json | 1 + src/lib/i18n/locales/ja-JP/translation.json | 1 + src/lib/i18n/locales/ka-GE/translation.json | 1 + src/lib/i18n/locales/kab-DZ/translation.json | 1 + src/lib/i18n/locales/ko-KR/translation.json | 1 + src/lib/i18n/locales/lt-LT/translation.json | 1 + src/lib/i18n/locales/lv-LV/translation.json | 1 + src/lib/i18n/locales/ms-MY/translation.json | 1 + src/lib/i18n/locales/nb-NO/translation.json | 1 + src/lib/i18n/locales/nl-NL/translation.json | 1 + src/lib/i18n/locales/pa-IN/translation.json | 1 + src/lib/i18n/locales/pl-PL/translation.json | 1 + src/lib/i18n/locales/pt-BR/translation.json | 1 + src/lib/i18n/locales/pt-PT/translation.json | 1 + src/lib/i18n/locales/ro-RO/translation.json | 1 + src/lib/i18n/locales/ru-RU/translation.json | 1 + src/lib/i18n/locales/sk-SK/translation.json | 1 + src/lib/i18n/locales/sr-RS/translation.json | 1 + src/lib/i18n/locales/sv-SE/translation.json | 1 + src/lib/i18n/locales/th-TH/translation.json | 1 + src/lib/i18n/locales/tk-TM/translation.json | 1 + src/lib/i18n/locales/tr-TR/translation.json | 1 + src/lib/i18n/locales/ug-CN/translation.json | 1 + src/lib/i18n/locales/uk-UA/translation.json | 1 + src/lib/i18n/locales/ur-PK/translation.json | 1 + .../i18n/locales/uz-Cyrl-UZ/translation.json | 1 + .../i18n/locales/uz-Latn-Uz/translation.json | 1 + src/lib/i18n/locales/vi-VN/translation.json | 1 + src/lib/i18n/locales/zh-CN/translation.json | 1 + src/lib/i18n/locales/zh-TW/translation.json | 1 + 69 files changed, 124 insertions(+), 33 deletions(-) diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index 79421874eb..fb313e2785 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -850,7 +850,11 @@ def load_oauth_providers(): if FEISHU_CLIENT_ID.value: configured_providers.append("Feishu") - if configured_providers and not OPENID_PROVIDER_URL.value and not OPENID_END_SESSION_ENDPOINT.value: + if ( + configured_providers + and not OPENID_PROVIDER_URL.value + and not OPENID_END_SESSION_ENDPOINT.value + ): provider_list = ", ".join(configured_providers) log.warning( f"⚠️ OAuth providers configured ({provider_list}) but OPENID_PROVIDER_URL not set - logout will not work!" @@ -2371,7 +2375,8 @@ if VECTOR_DB == "chroma": MARIADB_VECTOR_DB_URL = os.environ.get("MARIADB_VECTOR_DB_URL", "").strip() MARIADB_VECTOR_INITIALIZE_MAX_VECTOR_LENGTH = int( - os.environ.get("MARIADB_VECTOR_INITIALIZE_MAX_VECTOR_LENGTH", "1536").strip() or "1536" + os.environ.get("MARIADB_VECTOR_INITIALIZE_MAX_VECTOR_LENGTH", "1536").strip() + or "1536" ) # Distance strategy: @@ -2382,7 +2387,9 @@ MARIADB_VECTOR_DISTANCE_STRATEGY = ( ) # HNSW M parameter (MariaDB VECTOR INDEX ... M=) -MARIADB_VECTOR_INDEX_M = int(os.environ.get("MARIADB_VECTOR_INDEX_M", "8").strip() or "8") +MARIADB_VECTOR_INDEX_M = int( + os.environ.get("MARIADB_VECTOR_INDEX_M", "8").strip() or "8" +) # Pooling (MariaDB-Vector) MARIADB_VECTOR_POOL_SIZE = os.environ.get("MARIADB_VECTOR_POOL_SIZE", None) diff --git a/backend/open_webui/retrieval/utils.py b/backend/open_webui/retrieval/utils.py index e19563861b..5030a6eecb 100644 --- a/backend/open_webui/retrieval/utils.py +++ b/backend/open_webui/retrieval/utils.py @@ -590,7 +590,9 @@ def generate_openai_batch_embeddings( if "data" in data: return [elem["embedding"] for elem in data["data"]] else: - raise ValueError("Unexpected OpenAI embeddings response: missing 'data' key") + raise ValueError( + "Unexpected OpenAI embeddings response: missing 'data' key" + ) except Exception as e: log.exception(f"Error generating openai batch embeddings: {e}") return None @@ -767,7 +769,9 @@ def generate_ollama_batch_embeddings( if "embeddings" in data: return data["embeddings"] else: - raise ValueError("Unexpected Ollama embeddings response: missing 'embeddings' key") + raise ValueError( + "Unexpected Ollama embeddings response: missing 'embeddings' key" + ) except Exception as e: log.exception(f"Error generating ollama batch embeddings: {e}") return None diff --git a/backend/open_webui/retrieval/vector/dbs/mariadb_vector.py b/backend/open_webui/retrieval/vector/dbs/mariadb_vector.py index 06d11adec6..b1b8996263 100644 --- a/backend/open_webui/retrieval/vector/dbs/mariadb_vector.py +++ b/backend/open_webui/retrieval/vector/dbs/mariadb_vector.py @@ -22,7 +22,12 @@ from open_webui.config import ( MARIADB_VECTOR_POOL_TIMEOUT, MARIADB_VECTOR_POOL_RECYCLE, ) -from open_webui.retrieval.vector.main import GetResult, SearchResult, VectorDBBase, VectorItem +from open_webui.retrieval.vector.main import ( + GetResult, + SearchResult, + VectorDBBase, + VectorItem, +) from open_webui.retrieval.vector.utils import process_metadata log = logging.getLogger(__name__) @@ -157,8 +162,7 @@ class MariaDBVectorClient(VectorDBBase): with conn.cursor() as cur: try: dist = self.distance_strategy - cur.execute( - f""" + cur.execute(f""" CREATE TABLE IF NOT EXISTS document_chunk ( -- MariaDB Vector requires the table PRIMARY KEY used with a VECTOR INDEX to be <= 256 bytes. -- VARCHAR has internal length/metadata overhead, so VARCHAR(255) can exceed the 256-byte limit. @@ -173,8 +177,7 @@ class MariaDBVectorClient(VectorDBBase): VECTOR INDEX (embedding) M={self.index_m} DISTANCE={dist}, INDEX idx_document_chunk_collection_name (collection_name) ) ENGINE=InnoDB; - """ - ) + """) conn.commit() except Exception as e: conn.rollback() @@ -220,7 +223,11 @@ class MariaDBVectorClient(VectorDBBase): """ Return the MariaDB Vector distance function name for the configured strategy. """ - return "vec_distance_cosine" if self.distance_strategy == "cosine" else "vec_distance_euclidean" + return ( + "vec_distance_cosine" + if self.distance_strategy == "cosine" + else "vec_distance_euclidean" + ) def _score_from_dist(self, dist: float) -> float: """ @@ -442,12 +449,19 @@ class MariaDBVectorClient(VectorDBBase): documents[q_idx].append(rtext) metadatas[q_idx].append(_safe_json(rmeta)) - return SearchResult(ids=ids, distances=distances, documents=documents, metadatas=metadatas) + return SearchResult( + ids=ids, + distances=distances, + documents=documents, + metadatas=metadatas, + ) except Exception as e: log.exception(f"[MARIADB_VECTOR] search() failed: {e}") return None - def query(self, collection_name: str, filter: Dict[str, Any], limit: Optional[int] = None) -> Optional[GetResult]: + def query( + self, collection_name: str, filter: Dict[str, Any], limit: Optional[int] = None + ) -> Optional[GetResult]: """ Retrieve documents by metadata filter (non-vector query). """ @@ -472,7 +486,9 @@ class MariaDBVectorClient(VectorDBBase): metadatas = [[_safe_json(r[2]) for r in rows]] return GetResult(ids=ids, documents=documents, metadatas=metadatas) - def get(self, collection_name: str, limit: Optional[int] = None) -> Optional[GetResult]: + def get( + self, collection_name: str, limit: Optional[int] = None + ) -> Optional[GetResult]: """ Retrieve documents in a collection without filtering (optionally limited). """ @@ -549,7 +565,10 @@ class MariaDBVectorClient(VectorDBBase): try: with self._connect() as conn: with conn.cursor() as cur: - cur.execute("SELECT 1 FROM document_chunk WHERE collection_name = ? LIMIT 1", (collection_name,)) + cur.execute( + "SELECT 1 FROM document_chunk WHERE collection_name = ? LIMIT 1", + (collection_name,), + ) return cur.fetchone() is not None except Exception: return False diff --git a/backend/open_webui/retrieval/vector/factory.py b/backend/open_webui/retrieval/vector/factory.py index f1ead76d84..d92b335864 100644 --- a/backend/open_webui/retrieval/vector/factory.py +++ b/backend/open_webui/retrieval/vector/factory.py @@ -58,7 +58,9 @@ class Vector: return OpenGaussClient() case VectorType.MARIADB_VECTOR: - from open_webui.retrieval.vector.dbs.mariadb_vector import MariaDBVectorClient + from open_webui.retrieval.vector.dbs.mariadb_vector import ( + MariaDBVectorClient, + ) return MariaDBVectorClient() case VectorType.ELASTICSEARCH: diff --git a/backend/open_webui/routers/files.py b/backend/open_webui/routers/files.py index 6e3271d7ec..15eb817703 100644 --- a/backend/open_webui/routers/files.py +++ b/backend/open_webui/routers/files.py @@ -583,6 +583,7 @@ def update_file_data_content_by_id( request, ProcessFileForm(file_id=id, content=form_data.content), user=user, + db=db, ) file = Files.get_file_by_id(id=id, db=db) except Exception as e: diff --git a/backend/open_webui/routers/ollama.py b/backend/open_webui/routers/ollama.py index f1170b8f88..14ff55b109 100644 --- a/backend/open_webui/routers/ollama.py +++ b/backend/open_webui/routers/ollama.py @@ -1747,7 +1747,9 @@ async def download_file_stream( yield f"data: {json.dumps(res)}\n\n" else: - raise RuntimeError("Ollama: Could not create blob, Please try again.") + raise RuntimeError( + "Ollama: Could not create blob, Please try again." + ) # url = "https://huggingface.co/TheBloke/stablelm-zephyr-3b-GGUF/resolve/main/stablelm-zephyr-3b.Q2_K.gguf" diff --git a/backend/open_webui/utils/oauth.py b/backend/open_webui/utils/oauth.py index 4b6568bee7..636ad957d7 100644 --- a/backend/open_webui/utils/oauth.py +++ b/backend/open_webui/utils/oauth.py @@ -1706,7 +1706,9 @@ class OAuthManager: redirect_url = f"{redirect_base_url}/auth" if error_message: - redirect_url = f"{redirect_url}?error={urllib.parse.quote_plus(error_message)}" + redirect_url = ( + f"{redirect_url}?error={urllib.parse.quote_plus(error_message)}" + ) return RedirectResponse(url=redirect_url, headers=response.headers) response = RedirectResponse(url=redirect_url, headers=response.headers) diff --git a/backend/open_webui/utils/task.py b/backend/open_webui/utils/task.py index f5177eb787..0ea525c93e 100644 --- a/backend/open_webui/utils/task.py +++ b/backend/open_webui/utils/task.py @@ -162,9 +162,7 @@ def truncate_content(content: str, max_chars: int, mode: str = "middletruncate") return f"{content[:half]}...{content[-(max_chars - half):]}" -def apply_content_filter( - messages: list[dict], filter_str: str -) -> list[dict]: +def apply_content_filter(messages: list[dict], filter_str: str) -> list[dict]: """Apply a content filter to each message's content. filter_str is like 'middletruncate:500', 'start:200', or 'end:200'. @@ -238,9 +236,7 @@ def replace_messages_variable( else: half = mid // 2 start_msgs = messages[:half] - end_msgs = ( - messages[-half:] if mid % 2 == 0 else messages[-(half + 1) :] - ) + end_msgs = messages[-half:] if mid % 2 == 0 else messages[-(half + 1) :] selected = start_msgs + end_msgs content_filter = middle_filter else: diff --git a/backend/open_webui/utils/webhook.py b/backend/open_webui/utils/webhook.py index 62d35f299f..b3a3c6bcd1 100644 --- a/backend/open_webui/utils/webhook.py +++ b/backend/open_webui/utils/webhook.py @@ -32,8 +32,7 @@ async def post_webhook(name: str, url: str, message: str, event_data: dict) -> b else: user_dict = json.loads(user_data) facts = [ - {"name": name, "value": value} - for name, value in user_dict.items() + {"name": name, "value": value} for name, value in user_dict.items() ] payload = { "@type": "MessageCard", diff --git a/src/lib/components/chat/MessageInput/QueuedMessageItem.svelte b/src/lib/components/chat/MessageInput/QueuedMessageItem.svelte index d1c9850743..ed0adce37e 100644 --- a/src/lib/components/chat/MessageInput/QueuedMessageItem.svelte +++ b/src/lib/components/chat/MessageInput/QueuedMessageItem.svelte @@ -33,13 +33,11 @@ file.url?.startsWith('data') || file.url?.startsWith('http') ? file.url : `${WEBUI_API_BASE_URL}/files/${file.url}${file?.content_type ? '/content' : ''}`} - + {:else} -
+
{file.name ?? 'file'}
{/if} @@ -50,7 +48,9 @@ {#if content}

{content}

{:else if files.length === 0} -

{$i18n.t('Empty message')}

+

+ {$i18n.t('Empty message')} +

{/if}
diff --git a/src/lib/i18n/locales/ar-BH/translation.json b/src/lib/i18n/locales/ar-BH/translation.json index dff6be6fe7..8c940b7a24 100644 --- a/src/lib/i18n/locales/ar-BH/translation.json +++ b/src/lib/i18n/locales/ar-BH/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "نموذج التضمين", "Embedding Model Engine": "تضمين محرك النموذج", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/ar/translation.json b/src/lib/i18n/locales/ar/translation.json index c98f286a19..db010bd2f0 100644 --- a/src/lib/i18n/locales/ar/translation.json +++ b/src/lib/i18n/locales/ar/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "نموذج التضمين", "Embedding Model Engine": "تضمين محرك النموذج", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "تفعيل توليد الإكمال التلقائي لرسائل الدردشة", diff --git a/src/lib/i18n/locales/bg-BG/translation.json b/src/lib/i18n/locales/bg-BG/translation.json index 9d1d0ec7a1..7d5b9cacf8 100644 --- a/src/lib/i18n/locales/bg-BG/translation.json +++ b/src/lib/i18n/locales/bg-BG/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Модел за вграждане", "Embedding Model Engine": "Двигател на модела за вграждане", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Активиране на автоматично довършване на съобщения в чата", diff --git a/src/lib/i18n/locales/bn-BD/translation.json b/src/lib/i18n/locales/bn-BD/translation.json index df3b6aaea8..f5c7bef4ad 100644 --- a/src/lib/i18n/locales/bn-BD/translation.json +++ b/src/lib/i18n/locales/bn-BD/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "ইমেজ ইমেবডিং মডেল", "Embedding Model Engine": "ইমেজ ইমেবডিং মডেল ইঞ্জিন", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/bo-TB/translation.json b/src/lib/i18n/locales/bo-TB/translation.json index 6a4fe45090..768a0de0ca 100644 --- a/src/lib/i18n/locales/bo-TB/translation.json +++ b/src/lib/i18n/locales/bo-TB/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "ཚུད་འཇུག་དཔེ་དབྱིབས།", "Embedding Model Engine": "ཚུད་འཇུག་དཔེ་དབྱིབས་འཕྲུལ་འཁོར།", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "ཁ་བརྡའི་འཕྲིན་ཡིག་གི་ཆེད་དུ་རང་འཚང་བཟོ་སྐྲུན་སྒུལ་བསྐྱོད་བྱེད་པ།", diff --git a/src/lib/i18n/locales/bs-BA/translation.json b/src/lib/i18n/locales/bs-BA/translation.json index a62d7e5d24..1b694a5478 100644 --- a/src/lib/i18n/locales/bs-BA/translation.json +++ b/src/lib/i18n/locales/bs-BA/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Embedding model", "Embedding Model Engine": "Embedding model pogon", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/ca-ES/translation.json b/src/lib/i18n/locales/ca-ES/translation.json index 89228d5a78..9b297744ed 100644 --- a/src/lib/i18n/locales/ca-ES/translation.json +++ b/src/lib/i18n/locales/ca-ES/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "Peticions concurrents d'incrustació", "Embedding Model": "Model d'incrustació", "Embedding Model Engine": "Motor de model d'incrustació", + "Empty message": "", "Enable All": "Habilitar tot", "Enable API Keys": "Permetre claus API", "Enable autocomplete generation for chat messages": "Activar la generació automàtica per als missatges del xat", diff --git a/src/lib/i18n/locales/ceb-PH/translation.json b/src/lib/i18n/locales/ceb-PH/translation.json index b0ff5202f2..eed49b3f14 100644 --- a/src/lib/i18n/locales/ceb-PH/translation.json +++ b/src/lib/i18n/locales/ceb-PH/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "", "Embedding Model Engine": "", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/cs-CZ/translation.json b/src/lib/i18n/locales/cs-CZ/translation.json index 8941640667..f8c4ea4007 100644 --- a/src/lib/i18n/locales/cs-CZ/translation.json +++ b/src/lib/i18n/locales/cs-CZ/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Model pro vektorizaci", "Embedding Model Engine": "Jádro modelu pro vektorizaci", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Povolit generování automatického dokončování pro zprávy v konverzaci", diff --git a/src/lib/i18n/locales/da-DK/translation.json b/src/lib/i18n/locales/da-DK/translation.json index 27e62191dc..343a79c33c 100644 --- a/src/lib/i18n/locales/da-DK/translation.json +++ b/src/lib/i18n/locales/da-DK/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Embedding Model", "Embedding Model Engine": "Embedding Model engine", + "Empty message": "", "Enable All": "", "Enable API Keys": "Aktiver API nøgler", "Enable autocomplete generation for chat messages": "Aktiver autofuldførsel for chatbeskeder", diff --git a/src/lib/i18n/locales/de-DE/translation.json b/src/lib/i18n/locales/de-DE/translation.json index 673bcaaba4..672f451bcf 100644 --- a/src/lib/i18n/locales/de-DE/translation.json +++ b/src/lib/i18n/locales/de-DE/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "Gleichzeitige Embedding Anfragen", "Embedding Model": "Embedding-Modell", "Embedding Model Engine": "Embedding-Modell-Engine", + "Empty message": "", "Enable All": "Alle aktivieren", "Enable API Keys": "API-Schlüssel aktivieren", "Enable autocomplete generation for chat messages": "Autovervollständigung für Chat-Nachrichten aktivieren", diff --git a/src/lib/i18n/locales/dg-DG/translation.json b/src/lib/i18n/locales/dg-DG/translation.json index 8774cee65e..11ebfa8b75 100644 --- a/src/lib/i18n/locales/dg-DG/translation.json +++ b/src/lib/i18n/locales/dg-DG/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "", "Embedding Model Engine": "", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/el-GR/translation.json b/src/lib/i18n/locales/el-GR/translation.json index 21441dc201..d017f2531e 100644 --- a/src/lib/i18n/locales/el-GR/translation.json +++ b/src/lib/i18n/locales/el-GR/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Μοντέλο Ενσωμάτωσης", "Embedding Model Engine": "Μηχανή Μοντέλου Ενσωμάτωσης", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Ενεργοποίηση αυτόματης συμπλήρωσης για συνομιλίες", diff --git a/src/lib/i18n/locales/en-GB/translation.json b/src/lib/i18n/locales/en-GB/translation.json index 06b8ac6a1c..8738a4e69a 100644 --- a/src/lib/i18n/locales/en-GB/translation.json +++ b/src/lib/i18n/locales/en-GB/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "", "Embedding Model Engine": "", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/en-US/translation.json b/src/lib/i18n/locales/en-US/translation.json index 77d52c6446..40b81d8712 100644 --- a/src/lib/i18n/locales/en-US/translation.json +++ b/src/lib/i18n/locales/en-US/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "", "Embedding Model Engine": "", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/es-ES/translation.json b/src/lib/i18n/locales/es-ES/translation.json index 76765f0047..4b8b8ac5d6 100644 --- a/src/lib/i18n/locales/es-ES/translation.json +++ b/src/lib/i18n/locales/es-ES/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "Número de Peticiones Concurrentes en Incrustración", "Embedding Model": "Modelo de Incrustación", "Embedding Model Engine": "Motor del Modelo de Incrustación", + "Empty message": "", "Enable All": "Habilitar Todo", "Enable API Keys": "Habilitar Claves API", "Enable autocomplete generation for chat messages": "Habilitar generación de autocompletado para mensajes de chat", diff --git a/src/lib/i18n/locales/et-EE/translation.json b/src/lib/i18n/locales/et-EE/translation.json index 535e195b29..a6827ff48a 100644 --- a/src/lib/i18n/locales/et-EE/translation.json +++ b/src/lib/i18n/locales/et-EE/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Manustamise mudel", "Embedding Model Engine": "Manustamise mudeli mootor", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Luba automaattäitmise genereerimine vestlussõnumitele", diff --git a/src/lib/i18n/locales/eu-ES/translation.json b/src/lib/i18n/locales/eu-ES/translation.json index d46fe503b7..acac50bbda 100644 --- a/src/lib/i18n/locales/eu-ES/translation.json +++ b/src/lib/i18n/locales/eu-ES/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Embedding Eredua", "Embedding Model Engine": "Embedding Eredu Motorea", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/fa-IR/translation.json b/src/lib/i18n/locales/fa-IR/translation.json index f01fb5f7a5..c14f225200 100644 --- a/src/lib/i18n/locales/fa-IR/translation.json +++ b/src/lib/i18n/locales/fa-IR/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "مدل پیدائش", "Embedding Model Engine": "محرک مدل پیدائش", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "فعال\u200cسازی تولید تکمیل خودکار برای پیام\u200cهای چت", diff --git a/src/lib/i18n/locales/fi-FI/translation.json b/src/lib/i18n/locales/fi-FI/translation.json index a3a549fba2..f2297cdc6a 100644 --- a/src/lib/i18n/locales/fi-FI/translation.json +++ b/src/lib/i18n/locales/fi-FI/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "Samanaikaiset upotuspyynnöt", "Embedding Model": "Upotusmalli", "Embedding Model Engine": "Upotusmallin moottori", + "Empty message": "", "Enable All": "Ota kaikki käyttöön", "Enable API Keys": "Ota API-avaimet käyttöön", "Enable autocomplete generation for chat messages": "Ota automaattinen täydennys käyttöön keskusteluviesteissä", diff --git a/src/lib/i18n/locales/fr-CA/translation.json b/src/lib/i18n/locales/fr-CA/translation.json index 903522f047..66df34c8f7 100644 --- a/src/lib/i18n/locales/fr-CA/translation.json +++ b/src/lib/i18n/locales/fr-CA/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Modèle d'embedding", "Embedding Model Engine": "Moteur de modèle d'embedding", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Activer la génération des suggestions pour les messages", diff --git a/src/lib/i18n/locales/fr-FR/translation.json b/src/lib/i18n/locales/fr-FR/translation.json index a226b43bc5..9b31e6901a 100644 --- a/src/lib/i18n/locales/fr-FR/translation.json +++ b/src/lib/i18n/locales/fr-FR/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Modèle d'embedding", "Embedding Model Engine": "Moteur de modèle d'embedding", + "Empty message": "", "Enable All": "Activer tout", "Enable API Keys": "Autoriser les clés API", "Enable autocomplete generation for chat messages": "Activer la génération des suggestions pour les messages", diff --git a/src/lib/i18n/locales/gl-ES/translation.json b/src/lib/i18n/locales/gl-ES/translation.json index 63b37f9391..e2425db491 100644 --- a/src/lib/i18n/locales/gl-ES/translation.json +++ b/src/lib/i18n/locales/gl-ES/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Modelo de Embedding", "Embedding Model Engine": "Motor de Modelo de Embedding", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Habilitar xeneración de autocompletado para mensaxes de chat", diff --git a/src/lib/i18n/locales/he-IL/translation.json b/src/lib/i18n/locales/he-IL/translation.json index ab44c359e8..b8a360efac 100644 --- a/src/lib/i18n/locales/he-IL/translation.json +++ b/src/lib/i18n/locales/he-IL/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "מודל הטמעה", "Embedding Model Engine": "מנוע מודל הטמעה", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/hi-IN/translation.json b/src/lib/i18n/locales/hi-IN/translation.json index 54938dabca..c3894c9546 100644 --- a/src/lib/i18n/locales/hi-IN/translation.json +++ b/src/lib/i18n/locales/hi-IN/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "मॉडेल अनुकूलन", "Embedding Model Engine": "एंबेडिंग मॉडल इंजन", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/hr-HR/translation.json b/src/lib/i18n/locales/hr-HR/translation.json index 5bacffb41f..f60e902a1f 100644 --- a/src/lib/i18n/locales/hr-HR/translation.json +++ b/src/lib/i18n/locales/hr-HR/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Embedding model", "Embedding Model Engine": "Embedding model pogon", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/hu-HU/translation.json b/src/lib/i18n/locales/hu-HU/translation.json index da7cdd4481..9485825248 100644 --- a/src/lib/i18n/locales/hu-HU/translation.json +++ b/src/lib/i18n/locales/hu-HU/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Beágyazási modell", "Embedding Model Engine": "Beágyazási modell motor", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Automatikus kiegészítés engedélyezése csevegőüzenetekhez", diff --git a/src/lib/i18n/locales/id-ID/translation.json b/src/lib/i18n/locales/id-ID/translation.json index 2ce4e232bb..d6f1dd0b96 100644 --- a/src/lib/i18n/locales/id-ID/translation.json +++ b/src/lib/i18n/locales/id-ID/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Model Penyematan", "Embedding Model Engine": "Mesin Model Penyematan", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/ie-GA/translation.json b/src/lib/i18n/locales/ie-GA/translation.json index e12c645495..dcc43a8475 100644 --- a/src/lib/i18n/locales/ie-GA/translation.json +++ b/src/lib/i18n/locales/ie-GA/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "Iarratais Chomhuaineacha a Leabú", "Embedding Model": "Samhail Leabháilte", "Embedding Model Engine": "Inneall Samhail Leabaithe", + "Empty message": "", "Enable All": "Cumasaigh Gach Rud", "Enable API Keys": "Cumasaigh Eochracha API", "Enable autocomplete generation for chat messages": "Cumasaigh giniúint uathchríochnaithe le haghaidh teachtaireachtaí comhrá", diff --git a/src/lib/i18n/locales/it-IT/translation.json b/src/lib/i18n/locales/it-IT/translation.json index 135cca43b6..2d6bd18226 100644 --- a/src/lib/i18n/locales/it-IT/translation.json +++ b/src/lib/i18n/locales/it-IT/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Modello Embedding", "Embedding Model Engine": "Motore Modello di Embedding", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Abilita generazione autocompletamento per i messaggi di chat", diff --git a/src/lib/i18n/locales/ja-JP/translation.json b/src/lib/i18n/locales/ja-JP/translation.json index 71a84cbf04..fc52326773 100644 --- a/src/lib/i18n/locales/ja-JP/translation.json +++ b/src/lib/i18n/locales/ja-JP/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "埋め込みモデル", "Embedding Model Engine": "埋め込みモデルエンジン", + "Empty message": "", "Enable All": "", "Enable API Keys": "API キーを有効にする", "Enable autocomplete generation for chat messages": "チャットメッセージの自動補完を有効にする", diff --git a/src/lib/i18n/locales/ka-GE/translation.json b/src/lib/i18n/locales/ka-GE/translation.json index 5775c767e4..d9834853ed 100644 --- a/src/lib/i18n/locales/ka-GE/translation.json +++ b/src/lib/i18n/locales/ka-GE/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "მოდელის ჩაშენება", "Embedding Model Engine": "ჩაშენებული მოდელის ძრავა", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/kab-DZ/translation.json b/src/lib/i18n/locales/kab-DZ/translation.json index 7132052c02..06dd0559ba 100644 --- a/src/lib/i18n/locales/kab-DZ/translation.json +++ b/src/lib/i18n/locales/kab-DZ/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Tamudemt n ujmak", "Embedding Model Engine": "Amsedday n tmudemt n ujmak", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Rmed tasuta tawurmant tummidt i udiwenni iznan", diff --git a/src/lib/i18n/locales/ko-KR/translation.json b/src/lib/i18n/locales/ko-KR/translation.json index cd847b89ce..0016d8e2ec 100644 --- a/src/lib/i18n/locales/ko-KR/translation.json +++ b/src/lib/i18n/locales/ko-KR/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "임베딩 모델", "Embedding Model Engine": "임베딩 모델 엔진", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "채팅 메시지에 대한 자동 완성 생성 활성화", diff --git a/src/lib/i18n/locales/lt-LT/translation.json b/src/lib/i18n/locales/lt-LT/translation.json index 8479aa0f6d..69c413b827 100644 --- a/src/lib/i18n/locales/lt-LT/translation.json +++ b/src/lib/i18n/locales/lt-LT/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Embedding modelis", "Embedding Model Engine": "Embedding modelio variklis", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/lv-LV/translation.json b/src/lib/i18n/locales/lv-LV/translation.json index 07202c58a6..a6b9888ae7 100644 --- a/src/lib/i18n/locales/lv-LV/translation.json +++ b/src/lib/i18n/locales/lv-LV/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Iegulšanas modelis", "Embedding Model Engine": "Iegulšanas modeļa dzinējs", + "Empty message": "", "Enable All": "", "Enable API Keys": "Iespējot API atslēgas", "Enable autocomplete generation for chat messages": "Iespējot automātisko pabeigšanu tērzēšanas ziņojumiem", diff --git a/src/lib/i18n/locales/ms-MY/translation.json b/src/lib/i18n/locales/ms-MY/translation.json index 91340356df..403999ff7d 100644 --- a/src/lib/i18n/locales/ms-MY/translation.json +++ b/src/lib/i18n/locales/ms-MY/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "Permintaan Serentak Pembenaman", "Embedding Model": "Model Benamkan", "Embedding Model Engine": "Enjin Model Benamkan", + "Empty message": "", "Enable All": "Dayakan Semua", "Enable API Keys": "Dayakan Kunci API", "Enable autocomplete generation for chat messages": "Aktifkan penjanaan auto-lengkap untuk mesej sembang", diff --git a/src/lib/i18n/locales/nb-NO/translation.json b/src/lib/i18n/locales/nb-NO/translation.json index b7e521cd93..0691b1aaa5 100644 --- a/src/lib/i18n/locales/nb-NO/translation.json +++ b/src/lib/i18n/locales/nb-NO/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Innbyggingsmodell", "Embedding Model Engine": "Motor for innbygging av modeller", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Aktiver automatisk utfylling av chatmeldinger", diff --git a/src/lib/i18n/locales/nl-NL/translation.json b/src/lib/i18n/locales/nl-NL/translation.json index 7013db4a44..70661dcb5f 100644 --- a/src/lib/i18n/locales/nl-NL/translation.json +++ b/src/lib/i18n/locales/nl-NL/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Embedding Model", "Embedding Model Engine": "Embedding Model Engine", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Automatische aanvullingsgeneratie voor chatberichten inschakelen", diff --git a/src/lib/i18n/locales/pa-IN/translation.json b/src/lib/i18n/locales/pa-IN/translation.json index b824faf43d..98ff23a3f8 100644 --- a/src/lib/i18n/locales/pa-IN/translation.json +++ b/src/lib/i18n/locales/pa-IN/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "ਐਮਬੈੱਡਿੰਗ ਮਾਡਲ", "Embedding Model Engine": "ਐਮਬੈੱਡਿੰਗ ਮਾਡਲ ਇੰਜਣ", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/pl-PL/translation.json b/src/lib/i18n/locales/pl-PL/translation.json index d2420efd8c..d4e3da9a0f 100644 --- a/src/lib/i18n/locales/pl-PL/translation.json +++ b/src/lib/i18n/locales/pl-PL/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Model embeddingów", "Embedding Model Engine": "Silnik modelu embeddingów", + "Empty message": "", "Enable All": "", "Enable API Keys": "Włącz klucze API", "Enable autocomplete generation for chat messages": "Włącz autouzupełnianie w czacie", diff --git a/src/lib/i18n/locales/pt-BR/translation.json b/src/lib/i18n/locales/pt-BR/translation.json index 2333523217..c29dc729ad 100644 --- a/src/lib/i18n/locales/pt-BR/translation.json +++ b/src/lib/i18n/locales/pt-BR/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "Solicitações Simultâneas de Embedding", "Embedding Model": "Modelo de Embedding", "Embedding Model Engine": "Motor do Modelo de Embedding", + "Empty message": "", "Enable All": "Ativar tudo", "Enable API Keys": "Habilitar Chaves de API", "Enable autocomplete generation for chat messages": "Habilitar geração de preenchimento automático para mensagens do chat", diff --git a/src/lib/i18n/locales/pt-PT/translation.json b/src/lib/i18n/locales/pt-PT/translation.json index b45ec49cc1..4fe00e6f67 100644 --- a/src/lib/i18n/locales/pt-PT/translation.json +++ b/src/lib/i18n/locales/pt-PT/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Modelo de Embedding", "Embedding Model Engine": "Motor de Modelo de Embedding", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/ro-RO/translation.json b/src/lib/i18n/locales/ro-RO/translation.json index 37cc71aa3c..89e6ce06e0 100644 --- a/src/lib/i18n/locales/ro-RO/translation.json +++ b/src/lib/i18n/locales/ro-RO/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Model de Încapsulare", "Embedding Model Engine": "Motor de Model de Încapsulare", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Activează generarea automată pentru mesajele de chat", diff --git a/src/lib/i18n/locales/ru-RU/translation.json b/src/lib/i18n/locales/ru-RU/translation.json index 99a5189ae0..5b9872d07e 100644 --- a/src/lib/i18n/locales/ru-RU/translation.json +++ b/src/lib/i18n/locales/ru-RU/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Модель встраивания", "Embedding Model Engine": "Движок модели встраивания", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Включить генерацию автозаполнения для сообщений чата", diff --git a/src/lib/i18n/locales/sk-SK/translation.json b/src/lib/i18n/locales/sk-SK/translation.json index 693e6734fb..b63dbdf47c 100644 --- a/src/lib/i18n/locales/sk-SK/translation.json +++ b/src/lib/i18n/locales/sk-SK/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Vkladací model (Embedding Model)", "Embedding Model Engine": "", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/sr-RS/translation.json b/src/lib/i18n/locales/sr-RS/translation.json index 2146eec353..ed38bc8da3 100644 --- a/src/lib/i18n/locales/sr-RS/translation.json +++ b/src/lib/i18n/locales/sr-RS/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Модел уградње", "Embedding Model Engine": "Мотор модела уградње", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/sv-SE/translation.json b/src/lib/i18n/locales/sv-SE/translation.json index 2bd95feb58..86e715140b 100644 --- a/src/lib/i18n/locales/sv-SE/translation.json +++ b/src/lib/i18n/locales/sv-SE/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Inbäddningsmodell", "Embedding Model Engine": "Motor för inbäddningsmodell", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Aktivera automatisk komplettering av generering för chattmeddelanden", diff --git a/src/lib/i18n/locales/th-TH/translation.json b/src/lib/i18n/locales/th-TH/translation.json index e2b451c7c2..6b8051c1c5 100644 --- a/src/lib/i18n/locales/th-TH/translation.json +++ b/src/lib/i18n/locales/th-TH/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "โมเดล Embedding", "Embedding Model Engine": "เอ็นจินโมเดล Embedding", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "เปิดใช้งานการเติมข้อความอัตโนมัติสำหรับข้อความแชท", diff --git a/src/lib/i18n/locales/tk-TM/translation.json b/src/lib/i18n/locales/tk-TM/translation.json index 651254fa29..2786872cbd 100644 --- a/src/lib/i18n/locales/tk-TM/translation.json +++ b/src/lib/i18n/locales/tk-TM/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "", "Embedding Model Engine": "", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/tr-TR/translation.json b/src/lib/i18n/locales/tr-TR/translation.json index 9c0d3c9bd6..c442363e68 100644 --- a/src/lib/i18n/locales/tr-TR/translation.json +++ b/src/lib/i18n/locales/tr-TR/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Gömme Modeli", "Embedding Model Engine": "Gömme Modeli Motoru", + "Empty message": "", "Enable All": "Tümünü Etkinleştir", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Sohbet mesajları için otomatik tamamlama üretimini etkinleştir", diff --git a/src/lib/i18n/locales/ug-CN/translation.json b/src/lib/i18n/locales/ug-CN/translation.json index 3b45c2202c..d5530c937d 100644 --- a/src/lib/i18n/locales/ug-CN/translation.json +++ b/src/lib/i18n/locales/ug-CN/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "سىڭدۈرۈش مودېلى", "Embedding Model Engine": "سىڭدۈرۈش مودېل ماتورى", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "سۆھبەت ئۇچۇرلىرىغا ئاپتوماتىك تولدۇرۇش قوزغىتىش", diff --git a/src/lib/i18n/locales/uk-UA/translation.json b/src/lib/i18n/locales/uk-UA/translation.json index 6c949f2fee..cdd32362ff 100644 --- a/src/lib/i18n/locales/uk-UA/translation.json +++ b/src/lib/i18n/locales/uk-UA/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Модель вбудовування", "Embedding Model Engine": "Рушій моделі вбудовування ", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Увімкнути генерацію автозаповнення для повідомлень чату", diff --git a/src/lib/i18n/locales/ur-PK/translation.json b/src/lib/i18n/locales/ur-PK/translation.json index b165ac17fe..2bd69a6b0a 100644 --- a/src/lib/i18n/locales/ur-PK/translation.json +++ b/src/lib/i18n/locales/ur-PK/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "ایمبیڈنگ ماڈل", "Embedding Model Engine": "ایمبیڈنگ ماڈل انجن", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "", diff --git a/src/lib/i18n/locales/uz-Cyrl-UZ/translation.json b/src/lib/i18n/locales/uz-Cyrl-UZ/translation.json index b1168b60df..4fe68bfb54 100644 --- a/src/lib/i18n/locales/uz-Cyrl-UZ/translation.json +++ b/src/lib/i18n/locales/uz-Cyrl-UZ/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Ўрнатиш модели", "Embedding Model Engine": "Двигател моделини ўрнатиш", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Чат хабарлари учун автоматик тўлдиришни яратишни ёқинг", diff --git a/src/lib/i18n/locales/uz-Latn-Uz/translation.json b/src/lib/i18n/locales/uz-Latn-Uz/translation.json index 9087fe70e0..dee9c103c6 100644 --- a/src/lib/i18n/locales/uz-Latn-Uz/translation.json +++ b/src/lib/i18n/locales/uz-Latn-Uz/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "O'rnatish modeli", "Embedding Model Engine": "Dvigatel modelini o'rnatish", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Chat xabarlari uchun avtomatik to‘ldirishni yaratishni yoqing", diff --git a/src/lib/i18n/locales/vi-VN/translation.json b/src/lib/i18n/locales/vi-VN/translation.json index 5b190c6b1c..ae40e383f1 100644 --- a/src/lib/i18n/locales/vi-VN/translation.json +++ b/src/lib/i18n/locales/vi-VN/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Mô hình embedding", "Embedding Model Engine": "Trình xử lý embedding", + "Empty message": "", "Enable All": "", "Enable API Keys": "", "Enable autocomplete generation for chat messages": "Bật tạo tự động hoàn thành cho tin nhắn chat", diff --git a/src/lib/i18n/locales/zh-CN/translation.json b/src/lib/i18n/locales/zh-CN/translation.json index 6ca92acdc0..6300a44f2e 100644 --- a/src/lib/i18n/locales/zh-CN/translation.json +++ b/src/lib/i18n/locales/zh-CN/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "嵌入并发请求数", "Embedding Model": "嵌入模型", "Embedding Model Engine": "嵌入模型引擎", + "Empty message": "", "Enable All": "全部启用", "Enable API Keys": "启用接口密钥", "Enable autocomplete generation for chat messages": "启用对话输入框内容自动补全", diff --git a/src/lib/i18n/locales/zh-TW/translation.json b/src/lib/i18n/locales/zh-TW/translation.json index dcff1e5746..ee1b588ac2 100644 --- a/src/lib/i18n/locales/zh-TW/translation.json +++ b/src/lib/i18n/locales/zh-TW/translation.json @@ -633,6 +633,7 @@ "Embedding Concurrent Requests": "嵌入並發請求數", "Embedding Model": "嵌入模型", "Embedding Model Engine": "嵌入模型引擎", + "Empty message": "", "Enable All": "全部啟用", "Enable API Keys": "啟用 API 金鑰", "Enable autocomplete generation for chat messages": "啟用對話訊息的自動完成", From 1364df09136af2f30365a187ad4bf716435926e9 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sun, 8 Mar 2026 18:26:36 -0500 Subject: [PATCH 0856/1854] refac --- backend/open_webui/models/files.py | 10 ++++++- backend/open_webui/utils/misc.py | 45 ++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/backend/open_webui/models/files.py b/backend/open_webui/models/files.py index 59459cfb90..84dd43f5e8 100644 --- a/backend/open_webui/models/files.py +++ b/backend/open_webui/models/files.py @@ -4,6 +4,7 @@ from typing import Optional from sqlalchemy.orm import Session from open_webui.internal.db import Base, JSONField, get_db, get_db_context +from open_webui.utils.misc import sanitize_metadata from pydantic import BaseModel, ConfigDict, model_validator from sqlalchemy import BigInteger, Column, String, Text, JSON @@ -127,9 +128,16 @@ class FilesTable: self, user_id: str, form_data: FileForm, db: Optional[Session] = None ) -> Optional[FileModel]: with get_db_context(db) as db: + file_data = form_data.model_dump() + + # Sanitize meta to remove non-JSON-serializable objects + # (e.g. callable tool functions, MCP client instances from middleware) + if file_data.get("meta"): + file_data["meta"] = sanitize_metadata(file_data["meta"]) + file = FileModel( **{ - **form_data.model_dump(), + **file_data, "user_id": user_id, "created_at": int(time.time()), "updated_at": int(time.time()), diff --git a/backend/open_webui/utils/misc.py b/backend/open_webui/utils/misc.py index 35e19d70ce..bab1bb4bbf 100644 --- a/backend/open_webui/utils/misc.py +++ b/backend/open_webui/utils/misc.py @@ -566,6 +566,51 @@ def sanitize_data_for_db(obj): return obj +def sanitize_metadata(metadata: dict) -> dict: + """ + Return a JSON-safe copy of a metadata dict for database storage. + + The middleware metadata accumulates non-serializable Python objects + (e.g. callable tool functions, MCP client instances) that cause + PostgreSQL JSON inserts to fail. This helper strips those out while + preserving the primitive data needed for file-to-chat linking. + """ + if not isinstance(metadata, dict): + return metadata + + def _sanitize(obj): + if isinstance(obj, (str, int, float, bool, type(None))): + return obj + if isinstance(obj, dict): + return { + k: _sanitize(v) + for k, v in obj.items() + if not callable(v) and _is_serializable(v) + } + if isinstance(obj, list): + return [_sanitize(v) for v in obj if not callable(v) and _is_serializable(v)] + if callable(obj): + return None + # Last resort: try to see if it's serializable + try: + json.dumps(obj) + return obj + except (TypeError, ValueError): + return None + + def _is_serializable(obj): + """Quick check whether a value can survive JSON serialization.""" + if isinstance(obj, (str, int, float, bool, type(None), dict, list)): + return True + try: + json.dumps(obj) + return True + except (TypeError, ValueError): + return False + + return _sanitize(metadata) + + def extract_folders_after_data_docs(path): # Convert the path to a Path object if it's not already path = Path(path) From 0bfacca0a0a9e71fb4f2a1dea3fb09196dc01192 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sun, 8 Mar 2026 18:30:16 -0500 Subject: [PATCH 0857/1854] refac --- backend/open_webui/routers/files.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/backend/open_webui/routers/files.py b/backend/open_webui/routers/files.py index 15eb817703..5268ea657d 100644 --- a/backend/open_webui/routers/files.py +++ b/backend/open_webui/routers/files.py @@ -590,6 +590,29 @@ def update_file_data_content_by_id( log.exception(e) log.error(f"Error processing file: {file.id}") + # Propagate content change to all knowledge collections referencing + # this file. Without this the old embeddings remain in the knowledge + # collection and RAG returns both stale and current data (#20558). + knowledges = Knowledges.get_knowledges_by_file_id(id, db=db) + for knowledge in knowledges: + try: + # Remove old embeddings for this file from the KB collection + VECTOR_DB_CLIENT.delete( + collection_name=knowledge.id, filter={"file_id": id} + ) + # Re-add from the now-updated file-{file_id} collection + process_file( + request, + ProcessFileForm(file_id=id, collection_name=knowledge.id), + user=user, + db=db, + ) + except Exception as e: + log.warning( + f"Failed to update knowledge {knowledge.id} after " + f"content change for file {id}: {e}" + ) + return {"content": file.data.get("content", "")} else: raise HTTPException( From c3e1d2d894038104253a6336a5ac5db078d9bb59 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sun, 8 Mar 2026 18:40:47 -0500 Subject: [PATCH 0858/1854] refac --- backend/open_webui/routers/audio.py | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/routers/audio.py b/backend/open_webui/routers/audio.py index 65d17d53dd..41b6a07c1c 100644 --- a/backend/open_webui/routers/audio.py +++ b/backend/open_webui/routers/audio.py @@ -852,17 +852,36 @@ def transcription_handler(request, file_path, metadata, user=None): except requests.exceptions.RequestException as e: log.exception(e) detail = None + status_code = getattr(r, "status_code", 500) if r else 500 try: if r is not None and r.status_code != 200: res = r.json() - if "error" in res: + # Azure returns {"code": "...", "message": "...", "innerError": {...}} + if "code" in res and "message" in res: + azure_code = res.get("innerError", {}).get( + "code", res["code"] + ) + user_facing_codes = { + "EmptyAudioFile", + "AudioLengthLimitExceeded", + "NoLanguageIdentified", + "MultipleLanguagesIdentified", + } + if azure_code in user_facing_codes: + detail = res["message"] + else: + log.error( + f"Azure STT error [{azure_code}]: {res['message']}" + ) + detail = "An error occurred during transcription." + elif "error" in res: detail = f"External: {res['error'].get('message', '')}" except Exception: detail = f"External: {e}" raise HTTPException( - status_code=getattr(r, "status_code", 500) if r else 500, + status_code=status_code, detail=detail if detail else "Open WebUI: Server Connection Error", ) @@ -1087,6 +1106,8 @@ def transcribe( for future in futures: try: results.append(future.result()) + except HTTPException: + raise except Exception as transcribe_exc: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, @@ -1226,6 +1247,8 @@ def transcription( "filename": os.path.basename(file_path), } + except HTTPException: + raise except Exception as e: log.exception(e) @@ -1234,6 +1257,8 @@ def transcription( detail="Transcription failed.", ) + except HTTPException: + raise except Exception as e: log.exception(e) From 61366cbcda45d2989807eab2451178e021e42284 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sun, 8 Mar 2026 18:57:20 -0500 Subject: [PATCH 0859/1854] refac --- backend/open_webui/retrieval/vector/dbs/s3vector.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/backend/open_webui/retrieval/vector/dbs/s3vector.py b/backend/open_webui/retrieval/vector/dbs/s3vector.py index 96e487f111..4a1e70cdc4 100644 --- a/backend/open_webui/retrieval/vector/dbs/s3vector.py +++ b/backend/open_webui/retrieval/vector/dbs/s3vector.py @@ -61,6 +61,11 @@ class S3VectorClient(VectorDBBase): dataType=data_type, dimension=dimension, distanceMetric=distance_metric, + metadataConfiguration={ + "nonFilterableMetadataKeys": [ + "text", + ] + }, ) log.info( f"Created S3 index: {index_name} (dim={dimension}, type={data_type}, metric={distance_metric})" From cb73257f140fc2599619009b6f453d24cc96fee7 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Mon, 9 Mar 2026 00:58:01 +0100 Subject: [PATCH 0860/1854] chore: Changelog updates (#22460) * Add v0.8.10 changelog entry * changelog: docker startup fix for missing opentelemetry dependency * changelog: add translation updates for v0.8.10 * changelog: oauth-error-handling, exception-messages * changelog: fix YAML file processing with Docling (#22399) * changelog: tool access fix for non-admin users * changelog: fix time range month names localization * changelog: pipeline filter, webhook crash, shutdown handling * changelog: tool method filtering, OAuth URL encoding, Azure TTS * changelog: add analytics group filtering fix * changelog: api-calls, optimization, performance * changelog: add MariaDB Vector support entry * changelog: add web search favicon fallback fix * changelog: custom model fallback fix * changelog: pending message image display fix (#22256) * changelog: task message truncation for title and tag generation * changelog: oidc, logout, custom-endpoint * changelog: files list stability fix for issue #21879 * Remove empty Changed section from v0.8.10 * changelog: file metadata sanitization fix * Remove empty Changed section from v0.8.10 * changelog: fix knowledge file embedding updates for RAG * changelog: add Azure speech transcription error fix --- CHANGELOG.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 259f2f61ee..722ed67172 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,40 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.8.10] - 2026-03-08 + +### Added + +- ⚡ **API call optimization.** Reduced excessive API calls when hovering over the model selector or scrolling through chat history by adding a 30-second cooldown to model list fetches and a 200ms debounce to chat loading. [#22457](https://github.com/open-webui/open-webui/pull/22457) +- 🗄️ **MariaDB Vector support.** Added MariaDB Vector as a new vector database backend, enabling deployments with VECTOR_DB=mariadb-vector; supports cosine and euclidean distance strategies with configurable HNSW indexing. [#21931](https://github.com/open-webui/open-webui/pull/21931) +- 📝 **Task message truncation.** Chat messages sent to task models for title and tag generation can now be truncated using a filter in the prompt template, reducing token usage and processing time for long conversations. [#21499](https://github.com/open-webui/open-webui/issues/21499) +- 🔐 **Custom OIDC logout endpoint.** Administrators can now configure a custom OpenID Connect logout URL via OPENID_END_SESSION_ENDPOINT, enabling logout functionality for OIDC providers that require custom endpoints like AWS Cognito. [Commit](https://github.com/open-webui/open-webui/commit/3f350f865920daf2844769a758b2d2e6a7ee3efa) +- 🔄 **General improvements.** Various improvements were implemented across the application to enhance performance, stability, and security. +- 🌐 Translations for Portuguese (Brazil), Spanish, and Malay were enhanced and expanded. + +### Fixed + +- 🔗 **Pipeline filter HTTP errors.** Fixed a bug where HTTP errors in pipeline inlet/outlet filters would silently corrupt the user's chat payload; errors are now properly raised before parsing the response. [#22445](https://github.com/open-webui/open-webui/pull/22445) +- 📚 **Knowledge file embedding updates.** Fixed a bug where updating knowledge files left old embeddings in the database, causing search results to include duplicate and stale data. [#20558](https://github.com/open-webui/open-webui/issues/20558) +- 📁 **Files list stability.** Fixed the files list ordering to use created_at with id as secondary sort, ensuring consistent ordering and preventing page crashes when managing many files. [#21879](https://github.com/open-webui/open-webui/issues/21879) +- 📨 **Teams webhook crash.** Fixed a TypeError crash in the Teams webhook handler when user data is missing from the event payload. [#22444](https://github.com/open-webui/open-webui/pull/22444) +- 🛠️ **Process shutdown handling.** Fixed bare except clauses in the main process that prevented clean shutdown; replaced with proper exception handling. [#22423](https://github.com/open-webui/open-webui/pull/22423) +- 🐳 **Docker deployment startup.** Docker deployments now start correctly; the missing OpenTelemetry system metrics dependency was added. [#22447](https://github.com/open-webui/open-webui/pull/22447), [#22401](https://github.com/open-webui/open-webui/issues/22401) +- 🛠️ **Tool access for non-admin users.** Fixed a NameError that prevented non-admin users from viewing tools; the missing has_access function is now properly imported. [#22393](https://github.com/open-webui/open-webui/issues/22393) +- 🔐 **OAuth error handling.** Fixed a bug where bare except clauses silently caught SystemExit and KeyboardInterrupt, preventing clean process shutdown during OAuth authentication. [#22420](https://github.com/open-webui/open-webui/pull/22420) +- 🛠️ **Exception error messages.** Fixed three locations where incorrect exception raising caused confusing TypeError messages instead of proper error descriptions, making debugging much easier. [#22446](https://github.com/open-webui/open-webui/pull/22446) +- 📄 **YAML file processing.** Fixed an error when uploading YAML files with Docling enabled; YAML and YML files are now properly recognized as text files and processed correctly. [#22399](https://github.com/open-webui/open-webui/pull/22399), [#22263](https://github.com/open-webui/open-webui/issues/22263) +- 📅 **Time range month names.** Fixed month names in time range labels appearing in the wrong language when OS regional settings differ from browser language; month names now consistently display in English. [#22454](https://github.com/open-webui/open-webui/pull/22454) +- 🔐 **OAuth error URL encoding.** Fixed OAuth error messages with special characters causing malformed redirect URLs; error messages are now properly URL-encoded. [#22415](https://github.com/open-webui/open-webui/pull/22415) +- 🛠️ **Internal tool method filtering.** Tools no longer expose internal methods starting with underscore to the LLM, reducing clutter and improving accuracy. [#22408](https://github.com/open-webui/open-webui/pull/22408) +- 🔊 **Azure TTS locale extraction.** Fixed Azure text-to-speech using incomplete locale codes in SSML; now correctly uses full locale like "en-US" instead of just "en". [#22443](https://github.com/open-webui/open-webui/pull/22443) +- 🎤 **Azure speech transcription errors.** Improved Azure AI Speech error handling to display user-friendly messages instead of generic connection errors; empty transcripts, no language identified, and other Azure-specific errors now show clear descriptions. [#20485](https://github.com/open-webui/open-webui/issues/20485) +- 📊 **Analytics group filtering.** Fixed token usage analytics not being filtered by user group; the query now properly respects group filters like other analytics metrics. [#22167](https://github.com/open-webui/open-webui/pull/22167) +- 🔍 **Web search favicon fallback.** Fixed web search sources showing broken image icons when favicons couldn't be loaded from external sources; now falls back to the default Open WebUI favicon. [#21897](https://github.com/open-webui/open-webui/pull/21897) +- 🔄 **Custom model fallback.** Fixed custom model fallback not working when the base model is unavailable; the base model ID is now correctly retrieved from model info instead of empty params. [#22456](https://github.com/open-webui/open-webui/issues/22456) +- 🖼️ **Pending message image display.** Fixed images in queued messages appearing blank; image thumbnails are now properly displayed in the pending message queue. [#22256](https://github.com/open-webui/open-webui/issues/22256) +- 🛠️ **File metadata sanitization.** Fixed file uploads failing with JSON serialization errors when metadata contained non-serializable objects like callable functions; metadata is now sanitized before database insertion. [#20561](https://github.com/open-webui/open-webui/issues/20561) + ## [0.8.9] - 2026-03-07 ### Added From 97cc94756e92f481e8ea58da3002db39bfad17fc Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sun, 8 Mar 2026 19:00:50 -0500 Subject: [PATCH 0861/1854] chore: bump --- CHANGELOG.md | 5 ++--- backend/open_webui/routers/audio.py | 4 +--- backend/open_webui/utils/misc.py | 4 +++- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 722ed67172..250d70cc06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,10 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- ⚡ **API call optimization.** Reduced excessive API calls when hovering over the model selector or scrolling through chat history by adding a 30-second cooldown to model list fetches and a 200ms debounce to chat loading. [#22457](https://github.com/open-webui/open-webui/pull/22457) -- 🗄️ **MariaDB Vector support.** Added MariaDB Vector as a new vector database backend, enabling deployments with VECTOR_DB=mariadb-vector; supports cosine and euclidean distance strategies with configurable HNSW indexing. [#21931](https://github.com/open-webui/open-webui/pull/21931) -- 📝 **Task message truncation.** Chat messages sent to task models for title and tag generation can now be truncated using a filter in the prompt template, reducing token usage and processing time for long conversations. [#21499](https://github.com/open-webui/open-webui/issues/21499) - 🔐 **Custom OIDC logout endpoint.** Administrators can now configure a custom OpenID Connect logout URL via OPENID_END_SESSION_ENDPOINT, enabling logout functionality for OIDC providers that require custom endpoints like AWS Cognito. [Commit](https://github.com/open-webui/open-webui/commit/3f350f865920daf2844769a758b2d2e6a7ee3efa) +- 🗄️ **MariaDB Vector community support.** Added MariaDB Vector as a new vector database backend, enabling deployments with VECTOR_DB=mariadb-vector; supports cosine and euclidean distance strategies with configurable HNSW indexing. [#21931](https://github.com/open-webui/open-webui/pull/21931) +- 📝 **Task message truncation.** Chat messages sent to task models for title and tag generation can now be truncated using a filter in the prompt template, reducing token usage and processing time for long conversations. [#21499](https://github.com/open-webui/open-webui/issues/21499) - 🔄 **General improvements.** Various improvements were implemented across the application to enhance performance, stability, and security. - 🌐 Translations for Portuguese (Brazil), Spanish, and Malay were enhanced and expanded. diff --git a/backend/open_webui/routers/audio.py b/backend/open_webui/routers/audio.py index 41b6a07c1c..a1f3ac523f 100644 --- a/backend/open_webui/routers/audio.py +++ b/backend/open_webui/routers/audio.py @@ -859,9 +859,7 @@ def transcription_handler(request, file_path, metadata, user=None): res = r.json() # Azure returns {"code": "...", "message": "...", "innerError": {...}} if "code" in res and "message" in res: - azure_code = res.get("innerError", {}).get( - "code", res["code"] - ) + azure_code = res.get("innerError", {}).get("code", res["code"]) user_facing_codes = { "EmptyAudioFile", "AudioLengthLimitExceeded", diff --git a/backend/open_webui/utils/misc.py b/backend/open_webui/utils/misc.py index bab1bb4bbf..643648862b 100644 --- a/backend/open_webui/utils/misc.py +++ b/backend/open_webui/utils/misc.py @@ -588,7 +588,9 @@ def sanitize_metadata(metadata: dict) -> dict: if not callable(v) and _is_serializable(v) } if isinstance(obj, list): - return [_sanitize(v) for v in obj if not callable(v) and _is_serializable(v)] + return [ + _sanitize(v) for v in obj if not callable(v) and _is_serializable(v) + ] if callable(obj): return None # Last resort: try to see if it's serializable diff --git a/package-lock.json b/package-lock.json index 5a359dd054..04f3973311 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "open-webui", - "version": "0.8.9", + "version": "0.8.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "open-webui", - "version": "0.8.9", + "version": "0.8.10", "dependencies": { "@azure/msal-browser": "^4.5.0", "@codemirror/lang-javascript": "^6.2.2", diff --git a/package.json b/package.json index 49a72efa37..1eb043de5b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "open-webui", - "version": "0.8.9", + "version": "0.8.10", "private": true, "scripts": { "dev": "npm run pyodide:fetch && vite dev --host", From c6a1469fada032ec92e3c40f296cce12dde901fb Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sun, 8 Mar 2026 19:05:15 -0500 Subject: [PATCH 0862/1854] refac --- backend/open_webui/retrieval/vector/dbs/elasticsearch.py | 4 ++++ backend/open_webui/retrieval/vector/dbs/mariadb_vector.py | 4 ++++ backend/open_webui/retrieval/vector/dbs/milvus.py | 4 ++++ .../open_webui/retrieval/vector/dbs/milvus_multitenancy.py | 4 ++++ backend/open_webui/retrieval/vector/dbs/opengauss.py | 4 ++++ backend/open_webui/retrieval/vector/dbs/opensearch.py | 4 ++++ backend/open_webui/retrieval/vector/dbs/oracle23ai.py | 2 ++ backend/open_webui/retrieval/vector/dbs/pinecone.py | 4 ++++ backend/open_webui/retrieval/vector/dbs/qdrant.py | 4 ++++ .../open_webui/retrieval/vector/dbs/qdrant_multitenancy.py | 4 ++++ backend/open_webui/retrieval/vector/dbs/s3vector.py | 4 ++++ backend/open_webui/retrieval/vector/dbs/weaviate.py | 4 ++++ 12 files changed, 46 insertions(+) diff --git a/backend/open_webui/retrieval/vector/dbs/elasticsearch.py b/backend/open_webui/retrieval/vector/dbs/elasticsearch.py index e209453f5c..dfb02ec029 100644 --- a/backend/open_webui/retrieval/vector/dbs/elasticsearch.py +++ b/backend/open_webui/retrieval/vector/dbs/elasticsearch.py @@ -1,3 +1,7 @@ +""" +NOTE: This vector database integration is community-supported and maintained on a best-effort basis. +""" + from elasticsearch import Elasticsearch, BadRequestError from typing import Optional import ssl diff --git a/backend/open_webui/retrieval/vector/dbs/mariadb_vector.py b/backend/open_webui/retrieval/vector/dbs/mariadb_vector.py index b1b8996263..dfcfb3da59 100644 --- a/backend/open_webui/retrieval/vector/dbs/mariadb_vector.py +++ b/backend/open_webui/retrieval/vector/dbs/mariadb_vector.py @@ -1,3 +1,7 @@ +""" +NOTE: This vector database integration is community-supported and maintained on a best-effort basis. +""" + from __future__ import annotations import array diff --git a/backend/open_webui/retrieval/vector/dbs/milvus.py b/backend/open_webui/retrieval/vector/dbs/milvus.py index 35cf6b3829..4dcf76c64d 100644 --- a/backend/open_webui/retrieval/vector/dbs/milvus.py +++ b/backend/open_webui/retrieval/vector/dbs/milvus.py @@ -1,3 +1,7 @@ +""" +NOTE: This vector database integration is community-supported and maintained on a best-effort basis. +""" + from pymilvus import MilvusClient as Client from pymilvus import FieldSchema, DataType from pymilvus import connections, Collection diff --git a/backend/open_webui/retrieval/vector/dbs/milvus_multitenancy.py b/backend/open_webui/retrieval/vector/dbs/milvus_multitenancy.py index c58189b2a3..0ecbac15d2 100644 --- a/backend/open_webui/retrieval/vector/dbs/milvus_multitenancy.py +++ b/backend/open_webui/retrieval/vector/dbs/milvus_multitenancy.py @@ -1,3 +1,7 @@ +""" +NOTE: This vector database integration is community-supported and maintained on a best-effort basis. +""" + import logging from typing import Optional, Tuple, List, Dict, Any diff --git a/backend/open_webui/retrieval/vector/dbs/opengauss.py b/backend/open_webui/retrieval/vector/dbs/opengauss.py index 7d4f9ea092..679847a1d4 100644 --- a/backend/open_webui/retrieval/vector/dbs/opengauss.py +++ b/backend/open_webui/retrieval/vector/dbs/opengauss.py @@ -1,3 +1,7 @@ +""" +NOTE: This vector database integration is community-supported and maintained on a best-effort basis. +""" + from typing import Optional, List, Dict, Any import logging import re diff --git a/backend/open_webui/retrieval/vector/dbs/opensearch.py b/backend/open_webui/retrieval/vector/dbs/opensearch.py index ed5a931c68..3ad82d7442 100644 --- a/backend/open_webui/retrieval/vector/dbs/opensearch.py +++ b/backend/open_webui/retrieval/vector/dbs/opensearch.py @@ -1,3 +1,7 @@ +""" +NOTE: This vector database integration is community-supported and maintained on a best-effort basis. +""" + from opensearchpy import OpenSearch from opensearchpy.helpers import bulk from typing import Optional diff --git a/backend/open_webui/retrieval/vector/dbs/oracle23ai.py b/backend/open_webui/retrieval/vector/dbs/oracle23ai.py index f4258c9eff..10428de384 100644 --- a/backend/open_webui/retrieval/vector/dbs/oracle23ai.py +++ b/backend/open_webui/retrieval/vector/dbs/oracle23ai.py @@ -1,4 +1,6 @@ """ +NOTE: This vector database integration is community-supported and maintained on a best-effort basis. + Oracle 23ai Vector Database Client - Fixed Version # .env diff --git a/backend/open_webui/retrieval/vector/dbs/pinecone.py b/backend/open_webui/retrieval/vector/dbs/pinecone.py index 156894bc9e..27bc50b70e 100644 --- a/backend/open_webui/retrieval/vector/dbs/pinecone.py +++ b/backend/open_webui/retrieval/vector/dbs/pinecone.py @@ -1,3 +1,7 @@ +""" +NOTE: This vector database integration is community-supported and maintained on a best-effort basis. +""" + from typing import Optional, List, Dict, Any, Union import logging import time # for measuring elapsed time diff --git a/backend/open_webui/retrieval/vector/dbs/qdrant.py b/backend/open_webui/retrieval/vector/dbs/qdrant.py index d42984e1d6..e774bb875f 100644 --- a/backend/open_webui/retrieval/vector/dbs/qdrant.py +++ b/backend/open_webui/retrieval/vector/dbs/qdrant.py @@ -1,3 +1,7 @@ +""" +NOTE: This vector database integration is community-supported and maintained on a best-effort basis. +""" + from typing import Optional import logging from urllib.parse import urlparse diff --git a/backend/open_webui/retrieval/vector/dbs/qdrant_multitenancy.py b/backend/open_webui/retrieval/vector/dbs/qdrant_multitenancy.py index f87f85a23b..5ad2ac6929 100644 --- a/backend/open_webui/retrieval/vector/dbs/qdrant_multitenancy.py +++ b/backend/open_webui/retrieval/vector/dbs/qdrant_multitenancy.py @@ -1,3 +1,7 @@ +""" +NOTE: This vector database integration is community-supported and maintained on a best-effort basis. +""" + import logging from typing import Optional, Tuple, List, Dict, Any from urllib.parse import urlparse diff --git a/backend/open_webui/retrieval/vector/dbs/s3vector.py b/backend/open_webui/retrieval/vector/dbs/s3vector.py index 4a1e70cdc4..1a30e04e55 100644 --- a/backend/open_webui/retrieval/vector/dbs/s3vector.py +++ b/backend/open_webui/retrieval/vector/dbs/s3vector.py @@ -1,3 +1,7 @@ +""" +NOTE: This vector database integration is community-supported and maintained on a best-effort basis. +""" + from open_webui.retrieval.vector.utils import process_metadata from open_webui.retrieval.vector.main import ( VectorDBBase, diff --git a/backend/open_webui/retrieval/vector/dbs/weaviate.py b/backend/open_webui/retrieval/vector/dbs/weaviate.py index dcc648c788..c9b09ad638 100644 --- a/backend/open_webui/retrieval/vector/dbs/weaviate.py +++ b/backend/open_webui/retrieval/vector/dbs/weaviate.py @@ -1,3 +1,7 @@ +""" +NOTE: This vector database integration is community-supported and maintained on a best-effort basis. +""" + import weaviate import re import uuid From 83fad5e9f7e83aab396193e48ccb202b01f062bc Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Mon, 9 Mar 2026 18:45:33 -0500 Subject: [PATCH 0863/1854] refac --- src/lib/components/chat/FileNav.svelte | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lib/components/chat/FileNav.svelte b/src/lib/components/chat/FileNav.svelte index 81ee750a22..34da5272d7 100644 --- a/src/lib/components/chat/FileNav.svelte +++ b/src/lib/components/chat/FileNav.svelte @@ -172,6 +172,9 @@ if (terminal && terminal.url !== prevTerminalUrl) { prevTerminalUrl = terminal.url; + loading = true; + error = null; + entries = []; (async () => { // Discover server features (terminal enabled/disabled) const config = await getTerminalConfig(terminal.url, terminal.key); @@ -531,6 +534,7 @@ }); if (!handledDisplayFile) { + loading = true; if (savedPath === '/') { const rawCwd = await getCwd(terminal.url, terminal.key); const cwd = rawCwd ? normalizePath(rawCwd) : null; From 8970923940745a5912967ac490db7ef3242ba3ad Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Mon, 9 Mar 2026 19:08:32 -0500 Subject: [PATCH 0864/1854] refac --- src/lib/components/chat/MessageInput.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index 4664940d3a..9bd8f13d94 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -82,7 +82,7 @@ import InputVariablesModal from './MessageInput/InputVariablesModal.svelte'; import Voice from '../icons/Voice.svelte'; - import Cloud from '../icons/Cloud.svelte'; + import Terminal from '../icons/Terminal.svelte'; import IntegrationsMenu from './MessageInput/IntegrationsMenu.svelte'; import TerminalMenu from './MessageInput/TerminalMenu.svelte'; import Component from '../icons/Component.svelte'; @@ -1756,7 +1756,7 @@ ? 'm-1' : 'focus:outline-hidden rounded-full'}" > - +
+ + + +
From 8da29566a1f81c38e80009bdea3ce4d9be860605 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Wed, 11 Mar 2026 15:22:51 -0500 Subject: [PATCH 0874/1854] refac: safer tool server handling --- backend/open_webui/routers/tools.py | 12 +++++++++--- backend/open_webui/utils/tools.py | 13 ++++++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/backend/open_webui/routers/tools.py b/backend/open_webui/routers/tools.py index 351c491bdc..0569414d4d 100644 --- a/backend/open_webui/routers/tools.py +++ b/backend/open_webui/routers/tools.py @@ -88,9 +88,15 @@ async def get_tools( # OpenAPI Tool Servers server_access_grants = {} for server in await get_tool_servers(request): - connection = request.app.state.config.TOOL_SERVER_CONNECTIONS[ - server.get("idx", 0) - ] + server_idx = server.get("idx", 0) + connections = request.app.state.config.TOOL_SERVER_CONNECTIONS + if server_idx >= len(connections): + log.warning( + f"Tool server index {server_idx} out of range " + f"(have {len(connections)} connections), skipping server {server.get('id')}" + ) + continue + connection = connections[server_idx] server_config = connection.get("config", {}) server_id = f"server:{server.get('id')}" diff --git a/backend/open_webui/utils/tools.py b/backend/open_webui/utils/tools.py index e525a8284c..e605442612 100644 --- a/backend/open_webui/utils/tools.py +++ b/backend/open_webui/utils/tools.py @@ -275,11 +275,14 @@ async def get_tools( continue tool_server_idx = tool_server_data.get("idx", 0) - tool_server_connection = ( - request.app.state.config.TOOL_SERVER_CONNECTIONS[ - tool_server_idx - ] - ) + connections = request.app.state.config.TOOL_SERVER_CONNECTIONS + if tool_server_idx >= len(connections): + log.warning( + f"Tool server index {tool_server_idx} out of range " + f"(have {len(connections)} connections), skipping server {server_id}" + ) + continue + tool_server_connection = connections[tool_server_idx] # Check access control for tool server if not has_connection_access( From 035b981e11a549c6226ac0346f3747f454767ae2 Mon Sep 17 00:00:00 2001 From: Lorenzo Maffioli <63981558+lorenzophys@users.noreply.github.com> Date: Wed, 11 Mar 2026 21:27:06 +0100 Subject: [PATCH 0875/1854] feat(otel): introduce an environment variable to control the export interval of otel metrics (#22529) --- backend/open_webui/env.py | 3 +++ backend/open_webui/utils/telemetry/metrics.py | 7 +++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/backend/open_webui/env.py b/backend/open_webui/env.py index 30334d9c08..7cd3898eaf 100644 --- a/backend/open_webui/env.py +++ b/backend/open_webui/env.py @@ -1007,6 +1007,9 @@ OTEL_TRACES_SAMPLER = os.environ.get( ).lower() OTEL_BASIC_AUTH_USERNAME = os.environ.get("OTEL_BASIC_AUTH_USERNAME", "") OTEL_BASIC_AUTH_PASSWORD = os.environ.get("OTEL_BASIC_AUTH_PASSWORD", "") +OTEL_METRICS_EXPORT_INTERVAL_MILLIS = int( + os.environ.get("OTEL_METRICS_EXPORT_INTERVAL_MILLIS", "10000") +) OTEL_METRICS_BASIC_AUTH_USERNAME = os.environ.get( "OTEL_METRICS_BASIC_AUTH_USERNAME", OTEL_BASIC_AUTH_USERNAME diff --git a/backend/open_webui/utils/telemetry/metrics.py b/backend/open_webui/utils/telemetry/metrics.py index cafe779d80..5ff1129b02 100644 --- a/backend/open_webui/utils/telemetry/metrics.py +++ b/backend/open_webui/utils/telemetry/metrics.py @@ -44,11 +44,10 @@ from open_webui.env import ( OTEL_METRICS_BASIC_AUTH_PASSWORD, OTEL_METRICS_OTLP_SPAN_EXPORTER, OTEL_METRICS_EXPORTER_OTLP_INSECURE, + OTEL_METRICS_EXPORT_INTERVAL_MILLIS, ) from open_webui.models.users import Users -_EXPORT_INTERVAL_MILLIS = 10_000 # 10 seconds - def _build_meter_provider(resource: Resource) -> MeterProvider: """Return a configured MeterProvider.""" @@ -67,7 +66,7 @@ def _build_meter_provider(resource: Resource) -> MeterProvider: OTLPHttpMetricExporter( endpoint=OTEL_METRICS_EXPORTER_OTLP_ENDPOINT, headers=headers ), - export_interval_millis=_EXPORT_INTERVAL_MILLIS, + export_interval_millis=OTEL_METRICS_EXPORT_INTERVAL_MILLIS, ) ] else: @@ -78,7 +77,7 @@ def _build_meter_provider(resource: Resource) -> MeterProvider: insecure=OTEL_METRICS_EXPORTER_OTLP_INSECURE, headers=headers, ), - export_interval_millis=_EXPORT_INTERVAL_MILLIS, + export_interval_millis=OTEL_METRICS_EXPORT_INTERVAL_MILLIS, ) ] From cee645017dbbee005e41aa67133e74f2aaa48b3d Mon Sep 17 00:00:00 2001 From: alifurkanstahl <180474740+alifurkanstahl@users.noreply.github.com> Date: Wed, 11 Mar 2026 21:27:24 +0100 Subject: [PATCH 0876/1854] i18n(tr-TR): improve Turkish translations - increase coverage and fix typos/terminology errors (#22544) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * i18n: complete Turkish translations for {{}} placeholder strings * i18n(tr-TR): fix multiple translation errors * i18n(tr-TR): add missing translations for Y section * i18n(tr-TR): add missing translations for Model section * i18n(tr-TR): add missing Turkish translations for Image section * i18n(tr-TR): translate Knowledge section strings in Turkish * i18n(tr-TR): translate upload-related strings in Turkish * 18n: translate Invalid error messages to Turkish. * i18n(tr-TR):add Turkish translations for Enter input fields * i18n(tr-TR): add missing translations for "No" strings * i18n(tr-TR): replace "istem" with "prompt" for consistency * i18n(tr-TR): standardize "ID" terminology in Turkish translations * i18n(tr-TR): add missing translations for "S" strings * i18n(tr-TR): add missing translations for basic UI and navigation element * i18n(tr-TR): add missing translations for C-D sections * i18n(tr-TR): add missing translations for E-F sections * i18n(tr-TR): standardize "Chunk" terminology to "Parça" --------- Co-authored-by: MSI I9 12900KS RTX --- src/lib/i18n/locales/tr-TR/translation.json | 762 ++++++++++---------- 1 file changed, 381 insertions(+), 381 deletions(-) diff --git a/src/lib/i18n/locales/tr-TR/translation.json b/src/lib/i18n/locales/tr-TR/translation.json index c442363e68..6dd6a88393 100644 --- a/src/lib/i18n/locales/tr-TR/translation.json +++ b/src/lib/i18n/locales/tr-TR/translation.json @@ -19,18 +19,18 @@ "{{COUNT}} Rows": "{{COUNT}} satır", "{{COUNT}} Sources": "{{COUNT}} kaynak", "{{COUNT}} words": "{{COUNT}} kelime", - "{{COUNT}}d_time_ago": "", - "{{COUNT}}h_time_ago": "", - "{{COUNT}}m_time_ago": "", - "{{COUNT}}w_time_ago": "", - "{{COUNT}}y_time_ago": "", - "{{LOCALIZED_DATE}} at {{LOCALIZED_TIME}}": "", + "{{COUNT}}d_time_ago": "{{COUNT}} gün önce", + "{{COUNT}}h_time_ago": "{{COUNT}} saat önce", + "{{COUNT}}m_time_ago": "{{COUNT}} dakika önce", + "{{COUNT}}w_time_ago": "{{COUNT}} hafta önce", + "{{COUNT}}y_time_ago": "{{COUNT}} yıl önce", + "{{LOCALIZED_DATE}} at {{LOCALIZED_TIME}}": "{{LOCALIZED_DATE}} tarihinde saat {{LOCALIZED_TIME}}", "{{model}} download has been canceled": "{{model}} indirme işlemi iptal edildi", "{{modelName}} profile image": "{{modelName}} profil resmi", "{{NAMES}} reacted with {{REACTION}}": "{{NAMES}}, {{REACTION}} ile tepki verdi", "{{user}}'s Chats": "{{user}}'ın Sohbetleri", "{{webUIName}} Backend Required": "{{webUIName}} Arka-uç Gerekli", - "*Prompt node ID(s) are required for image generation": "*Görüntü oluşturma için düğüm kimlikleri gereklidir", + "*Prompt node ID(s) are required for image generation": "*Görüntü oluşturma için düğüm ID'leri gereklidir", "1 Source": "1 Kaynak", "1m_time_ago": "1 dk önce", "A collaboration channel where people join as members": "İnsanların üye olarak katıldığı bir iş birliği kanalı", @@ -254,8 +254,8 @@ "by {{name}}": "{{name}} tarafından", "By {{name}}": "{{name}} Tarafından", "Bypass Embedding and Retrieval": "", - "Bypass Web Loader": "", - "Cache Base Model List": "", + "Bypass Web Loader": "Web Yükleyicisini Atla", + "Cache Base Model List": "Temel Model Listesini Önbelleğe Al", "Calendar": "Takvim", "Call": "Arama", "Call feature is not supported when using Web STT engine": "Web STT motoru kullanılırken arama özelliği desteklenmiyor", @@ -281,9 +281,9 @@ "Channels": "Kanallar", "Character": "Karakter", "Character limit for autocomplete generation input": "Otomatik tamamlama üretimi girişi için karakter sınırı", - "Chart new frontiers": "", + "Chart new frontiers": "Yeni ufuklar çiz", "Chat": "Sohbet", - "Chat archived.": "", + "Chat archived.": "Sohbet arşivlendi.", "Chat Background Image": "Sohbet Arka Plan Resmi", "Chat Bubble UI": "Sohbet Balonu Arayüzü", "Chat Completions": "Sohbet Tamamlamaları", @@ -302,10 +302,10 @@ "Check for updates": "Güncellemeleri kontrol et", "Checking for updates...": "Güncellemeler kontrol ediliyor...", "Choose a model before saving...": "Kaydetmeden önce bir model seçin...", - "Chunk Min Size Target": "", - "Chunk Overlap": "Chunk Çakışması", - "Chunk Size": "Chunk Boyutu", - "Chunks smaller than this threshold will be merged with neighboring chunks when possible. Set to 0 to disable merging.": "", + "Chunk Min Size Target": "Parça Minimum Boyut Hedefi", + "Chunk Overlap": "Parça Çakışması", + "Chunk Size": "Parça Boyutu", + "Chunks smaller than this threshold will be merged with neighboring chunks when possible. Set to 0 to disable merging.": "Bu eşiğin altındaki parçalar mümkün olduğunda komşu parçalarla birleştirilir. Birleştirmeyi devre dışı bırakmak için 0 yapın.", "Ciphers": "Şifreler", "Citation": "Alıntı", "Citations": "Alıntılar", @@ -319,7 +319,7 @@ "Click here to": "Şunu yapmak için buraya tıklayın:", "Click here to download user import template file.": "Kullanıcı içe aktarma şablon dosyasını indirmek için buraya tıklayın.", "Click here to learn more about faster-whisper and see the available models.": "faster-whisper hakkında daha fazla bilgi edinmek ve mevcut modelleri görmek için buraya tıklayın.", - "Click here to see available models.": "Erişilebilir Modelleri Görmek İçin Buraya Tıklayın", + "Click here to see available models.": "Erişilebilir modelleri görmek için buraya tıklayın", "Click here to select": "Seçmek için buraya tıklayın", "Click here to select a csv file.": "Bir CSV dosyası seçmek için buraya tıklayın.", "Click here to select a py file.": "Bir py dosyası seçmek için buraya tıklayın.", @@ -341,18 +341,18 @@ "Close Modal": "Pencereyi kapat", "Close settings modal": "Ayarlar penceresini kapat", "Close Sidebar": "Kenar çubuğunu kapat", - "cloud": "", + "cloud": "bulut", "CMU ARCTIC speaker embedding name": "", - "Code Block": "", - "Code Editor": "", + "Code Block": "Kod Bloğu", + "Code Editor": "Kod Düzenleyici", "Code execution": "Kod yürütme", - "Code Execution": "", - "Code Execution Engine": "", - "Code Execution Timeout": "", + "Code Execution": "Kod Yürütme", + "Code Execution Engine": "Kod Yürütme Motoru", + "Code Execution Timeout": "Kod Yürütme Zaman Aşımı", "Code formatted successfully": "Kod başarıyla biçimlendirildi", "Code Interpreter": "Kod Yorumlayıcısı", "Code Interpreter Engine": "Kod Yorumlama Motoru", - "Code Interpreter Prompt Template": "Kod Yorumlama İstem Şablonu", + "Code Interpreter Prompt Template": "Kod Yorumlama Prompt Şablonu", "Collaboration channel where people join as members": "İnsanların üye olarak katıldığı bir iş birliği kanalı", "Collapse": "Daralt", "Collection": "Koleksiyon", @@ -364,17 +364,17 @@ "ComfyUI Base URL is required.": "ComfyUI Temel URL gerekli.", "ComfyUI Workflow": "ComfyUI İş Akışı", "ComfyUI Workflow Nodes": "ComfyUI İş Akışı Düğümleri", - "Comma separated Node Ids (e.g. 1 or 1,2)": "", + "Comma separated Node Ids (e.g. 1 or 1,2)": "Virgülle ayrılmış Node ID'leri (örn. 1 veya 1,2)", "command": "komut", "Command": "Komut", "Comment": "Yorum", - "Commit Message": "", + "Commit Message": "Commit Mesajı", "Community Reviews": "Topluluk İncelemeleri", "Completions": "Tamamlamalar", "Compress Images in Channels": "Kanallarda Görselleri Sıkıştır", "Concurrent Requests": "Eşzamanlı İstekler", - "Config": "", - "Config imported successfully": "", + "Config": "Yapılandırma", + "Config imported successfully": "Yapılandırma başarıyla içe aktarıldı", "Configure": "Yapılandırma", "Confirm": "Onayla", "Confirm Password": "Parolayı Onayla", @@ -384,7 +384,7 @@ "Connect to an AI provider to start chatting": "Sohbete başlamak için bir AI sağlayıcısına bağlanın", "Connect to Open Terminal instances to browse files and use them as always-on tools. Only one can be active at a time.": "Dosyalara göz atmak ve bunları her zaman açık araçlar olarak kullanmak için Open Terminal örneklerine bağlanın. Aynı anda yalnızca biri etkin olabilir.", "Connect to Open Terminal instances. All users will have access to file browsing and terminal tools through these servers.": "Open Terminal örneklerine bağlanın. Tüm kullanıcılar bu sunucular üzerinden dosya gezintisine ve terminal araçlarına erişebilecek.", - "Connect to your own OpenAI compatible API endpoints.": "", + "Connect to your own OpenAI compatible API endpoints.": "Kendi OpenAI uyumlu API uç noktalarınıza bağlanın.", "Connect to your own OpenAPI compatible external tool servers.": "Kendi OpenAPI uyumlu harici araç sunucularınıza bağlanın.", "Connection failed": "Bağlantı başarısız", "Connection successful": "Bağlantı başarılı", @@ -396,7 +396,7 @@ "Contact Admin for WebUI Access": "WebUI Erişimi için Yöneticiyle İletişime Geçin", "Content": "İçerik", "Content Extraction Engine": "İçerik Çıkarma Motoru", - "Content lengths (character counts only)": "", + "Content lengths (character counts only)": "İçerik uzunlukları (sadece karakter sayısı)", "Continue Response": "Yanıta Devam Et", "Continue with {{provider}}": "{{provider}} ile devam et", "Continue with Email": "E-posta ile devam edin", @@ -414,15 +414,15 @@ "Copy API Key": "API Anahtarını Kopyala", "Copy content": "İçeriği kopyala", "Copy Formatted Text": "Biçimlenirilmiş Metni Kopyala", - "Copy Last Code Block": "", - "Copy Last Response": "", + "Copy Last Code Block": "Son Kod Bloğunu Kopyala", + "Copy Last Response": "Son Yanıtı Kopyala", "Copy link": "Bağlantıyı kopyala", "Copy Link": "Bağlantıyı Kopyala", - "Copy Prompt": "", + "Copy Prompt": "Prompt'u Kopyala", "Copy Share Link": "", "Copy to clipboard": "Panoya kopyala", - "Copy Token": "", - "Copy URL": "", + "Copy Token": "Token'ı Kopyala", + "Copy URL": "URL'yi Kopyala", "Copying to clipboard was successful!": "Panoya kopyalama başarılı!", "CORS must be properly configured by the provider to allow requests from Open WebUI.": "Open WebUI’dan gelen isteklerin kabul edilebilmesi için sağlayıcının CORS yapılandırmasının doğru şekilde yapılmış olması gerekir.", "Could not read file.": "Dosya okunamadı.", @@ -454,19 +454,19 @@ "Custom": "Özel", "Custom description enabled": "Özel açıklama etkin", "Custom Gender": "Özel Cinsiyet", - "Custom Parameter Name": "", - "Custom Parameter Value": "", + "Custom Parameter Name": "Özel Parametre Adı", + "Custom Parameter Value": "Özel Parametre Değeri", "Daily Messages": "Günlük Mesajlar", "Danger Zone": "Tehlikeli Bölge", "Dark": "Koyu", "Data Controls": "Veri Kontrolleri", "Database": "Veritabanı", - "Datalab Marker API": "", + "Datalab Marker API": "Datalab Marker API", "DD/MM/YYYY": "GG/AA/YYYY", - "DDGS Backend": "", + "DDGS Backend": "DDGS Backend", "December": "Aralık", "Decrease UI Scale": "Arayüz Ölçeğini Küçült", - "Deepgram": "", + "Deepgram": "Deepgram", "Default": "Varsayılan", "Default (Open AI)": "Varsayılan (Open AI)", "Default (SentenceTransformers)": "Varsayılan (SentenceTransformers)", @@ -483,11 +483,11 @@ "Default Prompt Suggestions": "Varsayılan Prompt Önerileri", "Default to 389 or 636 if TLS is enabled": "TLS etkinse 389 veya 636'ya varsayılan olarak", "Default to ALL": "TÜMÜ'nü varsayılan olarak", - "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "", + "Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.": "Odaklanmış ve ilgili içerik çıkarımı için varsayılan olarak bölümlenmiş alma kullanılır, çoğu durum için bu önerilir.", "Default User Role": "Varsayılan Kullanıcı Rolü", "Defaults": "Varsayılanlar", "Delete": "Sil", - "Delete {{name}}": "", + "Delete {{name}}": "{{name}} öğesini sil", "Delete a model": "Bir modeli sil", "Delete All": "Tümünü Sil", "Delete All Chats": "Tüm Sohbetleri Sil", @@ -511,7 +511,7 @@ "Deleted {{deleteModelTag}}": "{{deleteModelTag}} silindi", "Deleted {{name}}": "{{name}} silindi", "Deleted User": "Kullanıcı Silindi", - "Deployment names are required for Azure OpenAI": "", + "Deployment names are required for Azure OpenAI": "Azure OpenAI için dağıtım adları gereklidir", "Desc": "Azalan", "Describe the edit...": "Düzenlemeyi açıklayın...", "Describe the image...": "Görseli açıklayın...", @@ -519,7 +519,7 @@ "Describe your knowledge base and objectives": "Bilgi tabanınızı ve hedeflerinizi açıklayın", "Description": "Açıklama", "Detect Artifacts Automatically": "Eserleri Otomatik Algıla", - "Dictate": "", + "Dictate": "Dikte Et", "Didn't fully follow instructions": "Talimatları tam olarak takip etmedi", "Direct": "Doğrudan", "Direct Connections": "Doğrudan Bağlantılar", @@ -529,8 +529,8 @@ "Directory selection was cancelled": "Dizin seçimi iptal edildi", "Disable All": "Tümünü Devre Dışı Bırak", "Disable Code Interpreter": "Kod Yorumlayıcıyı Devre Dışı Bırak", - "Disable Image Extraction": "", - "Disable image extraction from the PDF. If Use LLM is enabled, images will be automatically captioned. Defaults to False.": "", + "Disable Image Extraction": "Görsel Çıkarmayı Devre Dışı Bırak", + "Disable image extraction from the PDF. If Use LLM is enabled, images will be automatically captioned. Defaults to False.": "PDF'den görsel çıkarmayı devre dışı bırakır. LLM Kullan etkinse görseller otomatik olarak altyazılanır. Varsayılan olarak False.", "Disabled": "Devre Dışı", "Discover a function": "Bir fonksiyon keşfedin", "Discover a model": "Bir model keşfedin", @@ -555,12 +555,12 @@ "Do not install tools from sources you do not fully trust.": "Tamamen güvenmediğiniz kaynaklardan araçlar yüklemeyin.", "Do you want to sync your usage stats with Open WebUI Community?": "Kullanım istatistiklerinizi Open WebUI Community ile senkronize etmek istiyor musunuz?", "Docling": "Docling", - "Docling Parameters": "", - "Docling Server URL required.": "", + "Docling Parameters": "Docling Parametreleri", + "Docling Server URL required.": "Docling Sunucu URL'si gereklidir.", "Document": "Belge", - "Document Intelligence": "", - "Document Intelligence endpoint required.": "", - "Document Intelligence Model": "", + "Document Intelligence": "Document Intelligence", + "Document Intelligence endpoint required.": "Document Intelligence uç noktası gereklidir.", + "Document Intelligence Model": "Document Intelligence Modeli", "Documentation": "Dökümantasyon", "Documents": "Belgeler", "does not make any external connections, and your data stays securely on your locally hosted server.": "herhangi bir harici bağlantı yapmaz ve verileriniz güvenli bir şekilde yerel olarak barındırılan sunucunuzda kalır.", @@ -580,18 +580,18 @@ "Downloading stats...": "İstatistikler indiriliyor...", "Draw": "Çiz", "Drop any files here to upload": "Yüklemek için dosyaları buraya bırakın", - "Drop files here": "", + "Drop files here": "Dosyaları buraya bırakın", "Drop files here to upload": "Yüklemek için dosyaları buraya bırakın", - "DuckDuckGo": "", + "DuckDuckGo": "DuckDuckGo", "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "örn. '30s', '10m'. Geçerli zaman birimleri 's', 'm', 'h'.", "e.g. 'low', 'medium', 'high'": "örn. 'low', 'medium', 'high'", "e.g. \"json\" or a JSON schema": "örn. \"json\" veya JSON şablonu", "e.g. 60": "örn. 60", "e.g. A filter to remove profanity from text": "örn. Metinden küfürleri kaldırmak için bir filtre", "e.g. about the Roman Empire": "örn. Roma İmparatorluğu hakkında", - "e.g. alloy, echo, shimmer": "", - "e.g. Code Review Guidelines": "", - "e.g. code-review-guidelines": "", + "e.g. alloy, echo, shimmer": "örn. alloy, echo, shimmer", + "e.g. Code Review Guidelines": "örn. Kod İnceleme Yönergeleri", + "e.g. code-review-guidelines": "örn. kod-inceleme-yönergeleri", "e.g. en": "örn. en", "e.g. My Filter": "örn. Benim Filtrem", "e.g. My Tools": "örn. Benim Araçlarım", @@ -601,11 +601,11 @@ "e.g. Step-by-step instructions for code reviews": "örn. Kod incelemeleri için adım adım talimatlar", "e.g. Tell me a fun fact": "örn. Bana eğlenceli bir bilgi söyle", "e.g. Tell me a fun fact about the Roman Empire": "örn. Bana Roma İmparatorluğu hakkında eğlenceli bir bilgi söyle", - "e.g. Tools for performing various operations": " örn.Çeşitli işlemleri gerçekleştirmek için araçlar", + "e.g. Tools for performing various operations": "örn. Çeşitli işlemleri gerçekleştirmek için araçlar", "e.g., 3, 4, 5 (leave blank for default)": "örn. 3, 4, 5 (öntanımlı değer için boş bırakın)", - "e.g., audio/wav,audio/mpeg,video/* (leave blank for defaults)": "", + "e.g., audio/wav,audio/mpeg,video/* (leave blank for defaults)": "örn. audio/wav,audio/mpeg,video/* (varsayılan için boş bırakın)", "e.g., en-US,ja-JP (leave blank for auto-detect)": "örn. en-US, ja-JP (otomatik tanıma için boş bırakın)", - "e.g., westus (leave blank for eastus)": "ö", + "e.g., westus (leave blank for eastus)": "örn. westus (öntanımlı değer için eastus)", "Edit": "Düzenle", "Edit Arena Model": "Arena Modelini Düzenle", "Edit Channel": "Kanalı Düzenle", @@ -615,16 +615,16 @@ "Edit Image": "Görseli Düzenle", "Edit Last Message": "Son Mesajı Düzenle", "Edit Memory": "Belleği Düzenle", - "Edit Prompt": "", + "Edit Prompt": "Prompt'u Düzenle", "Edit Terminal Connection": "Terminal Bağlantısını Düzenle", "Edit User": "Kullanıcıyı Düzenle", "Edit User Group": "Kullanıcı Grubunu Düzenle", - "Edit workflow.json content": "", + "Edit workflow.json content": "workflow.json içeriğini düzenle", "edited": "düzenlendi", "Edited": "Düzenlendi", "Editing": "Düzenleniyor", - "Eject": "", - "Eject model": "", + "Eject": "Çıkar", + "Eject model": "Modeli çıkar", "ElevenLabs": "ElevenLabs", "Email": "E-posta", "Embark on adventures": "Maceralara atıl", @@ -633,9 +633,9 @@ "Embedding Concurrent Requests": "", "Embedding Model": "Gömme Modeli", "Embedding Model Engine": "Gömme Modeli Motoru", - "Empty message": "", + "Empty message": "Boş mesaj", "Enable All": "Tümünü Etkinleştir", - "Enable API Keys": "", + "Enable API Keys": "API Anahtarlarını Etkinleştir", "Enable autocomplete generation for chat messages": "Sohbet mesajları için otomatik tamamlama üretimini etkinleştir", "Enable Code Execution": "Kod Çalıştırmayı Etkinleştir", "Enable Code Interpreter": "Kod Yorumlayıcıyı Etkinleştir", @@ -648,7 +648,7 @@ "Enable New Sign Ups": "Yeni Kayıtları Etkinleştir", "Enable, disable, or customize the reasoning tags used by the model. \"Enabled\" uses default tags, \"Disabled\" turns off reasoning tags, and \"Custom\" lets you specify your own start and end tags.": "", "Enabled": "Etkin", - "End Tag": "", + "End Tag": "Bitiş Etiketi", "Endpoint URL": "Uçnokta URL", "Enforce Temporary Chat": "Geçici Sohbete Zorla", "Enhance": "İyileştir", @@ -656,11 +656,11 @@ "Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "CSV dosyanızın şu sırayla 4 sütun içerdiğinden emin olun: İsim, E-posta, Şifre, Rol.", "Enter {{role}} message here": "Buraya {{role}} mesajını girin", "Enter a detail about yourself for your LLMs to recall": "LLM'lerinizin hatırlaması için kendiniz hakkında bir bilgi girin", - "Enter a title for the pending user info overlay. Leave empty for default.": "", - "Enter a watermark for the response. Leave empty for none.": "", - "Enter additional headers in JSON format": "", - "Enter additional headers in JSON format (e.g. {\"X-Custom-Header\": \"value\"}": "", - "Enter additional parameters in JSON format": "", + "Enter a title for the pending user info overlay. Leave empty for default.": "Bekleyen kullanıcı bilgi katmanı için bir başlık girin. Varsayılan için boş bırakın.", + "Enter a watermark for the response. Leave empty for none.": "Yanıt için bir filigran girin. Yoksa boş bırakın.", + "Enter additional headers in JSON format": "JSON formatında ek başlıklar girin", + "Enter additional headers in JSON format (e.g. {\"X-Custom-Header\": \"value\"}": "JSON formatında ek başlıklar girin (örn. {\"X-Custom-Header\": \"value\"})", + "Enter additional parameters in JSON format": "JSON formatında ek parametreler girin", "Enter api auth string (e.g. username:password)": "Api auth dizesini girin (örn. kullanıcı adı:parola)", "Enter Application DN": "Uygulama DN'sini Girin", "Enter Application DN Password": "Uygulama DN Parolasını Girin", @@ -669,50 +669,50 @@ "Enter Bocha Search API Key": "Bocha Search API Anahtarını Girin", "Enter Brave Search API Key": "Brave Search API Anahtarını Girin", "Enter certificate path": "Sertifika yolunu girin", - "Enter Chunk Min Size Target": "", - "Enter Chunk Overlap": "Chunk Örtüşmesini Girin", - "Enter Chunk Size": "Chunk Boyutunu Girin", - "Enter comma-separated \"token:bias_value\" pairs (example: 5432:100, 413:-100)": "", - "Enter content for the pending user info overlay. Leave empty for default.": "", - "Enter coordinates (e.g. 51.505, -0.09)": "", - "Enter Datalab Marker API Base URL": "", - "Enter Datalab Marker API Key": "", + "Enter Chunk Min Size Target": "Parça Minimum Boyut Hedefini Girin", + "Enter Chunk Overlap": "Parça Çakışmasını Girin", + "Enter Chunk Size": "Parça Boyutunu Girin", + "Enter comma-separated \"token:bias_value\" pairs (example: 5432:100, 413:-100)": "Virgülle ayrılmış \"token:bias_value\" çiftlerini girin (örnek: 5432:100, 413:-100)", + "Enter content for the pending user info overlay. Leave empty for default.": "Bekleyen kullanıcı bilgi katmanı için içerik girin. Varsayılan için boş bırakın.", + "Enter coordinates (e.g. 51.505, -0.09)": "Koordinatları girin (örn. 51.505, -0.09)", + "Enter Datalab Marker API Base URL": "Datalab Marker API Taban URL'sini Girin", + "Enter Datalab Marker API Key": "Datalab Marker API Anahtarını Girin", "Enter description": "Açıklama girin", - "Enter Docling API Key": "", - "Enter Docling Server URL": "", - "Enter Document Intelligence Endpoint": "", - "Enter Document Intelligence Key": "", - "Enter Document Intelligence Model": "", - "Enter domains separated by commas (e.g., example.com,site.org,!excludedsite.com)": "", - "Enter Exa API Key": "", - "Enter External Document Loader API Key": "", - "Enter External Document Loader URL": "", + "Enter Docling API Key": "Docling API Anahtarını Girin", + "Enter Docling Server URL": "Docling Sunucu URL'sini Girin", + "Enter Document Intelligence Endpoint": "Document Intelligence Endpoint'ini Girin", + "Enter Document Intelligence Key": "Document Intelligence Anahtarını Girin", + "Enter Document Intelligence Model": "Document Intelligence Modelini Girin", + "Enter domains separated by commas (e.g., example.com,site.org,!excludedsite.com)": "Virgülle ayrılmış alan adlarını girin (örn., example.com,site.org,!excludedsite.com)", + "Enter Exa API Key": "Exa API Anahtarını Girin", + "Enter External Document Loader API Key": "Harici Belge Yükleyici API Anahtarını Girin", + "Enter External Document Loader URL": "Harici Belge Yükleyici URL'sini Girin", "Enter External Web Loader API Key": "Harici Web Yükleyici API Anahtarını Girin", "Enter External Web Loader URL": "Harici Web Yükleyici URL'sini Girin", "Enter External Web Search API Key": "Harici Web Arama API Anahtarını Girin", "Enter External Web Search URL": "Harici Web Arama URL'sini Girin", - "Enter Firecrawl API Base URL": "", - "Enter Firecrawl API Key": "", - "Enter Firecrawl Timeout": "", - "Enter folder name": "", - "Enter function name filter list (e.g. func1, !func2)": "", + "Enter Firecrawl API Base URL": "Firecrawl API Taban URL'sini Girin", + "Enter Firecrawl API Key": "Firecrawl API Anahtarını Girin", + "Enter Firecrawl Timeout": "Firecrawl Zaman Aşımını Girin", + "Enter folder name": "Klasör adını girin", + "Enter function name filter list (e.g. func1, !func2)": "Fonksiyon adı filtre listesini girin (örn. func1, !func2)", "Enter Github Raw URL": "Github Raw URL'sini girin", "Enter Google PSE API Key": "Google PSE API Anahtarını Girin", "Enter Google PSE Engine Id": "Google PSE Engine Id'sini Girin", "Enter hex color (e.g. #FF0000)": "", "Enter Image Size (e.g. 512x512)": "Görüntü Boyutunu Girin (örn. 512x512)", - "Enter Jina API Base URL": "", + "Enter Jina API Base URL": "Jina API Taban URL'sini Girin", "Enter Jina API Key": "Jina API Anahtarını Girin", - "Enter JSON config (e.g., {\"disable_links\": true})": "", - "Enter Jupyter Password": "", - "Enter Jupyter Token": "", - "Enter Jupyter URL": "", + "Enter JSON config (e.g., {\"disable_links\": true})": "JSON yapılandırması girin (örn., {\"disable_links\": true})", + "Enter Jupyter Password": "Jupyter Parolasını Girin", + "Enter Jupyter Token": "Jupyter Token'ını Girin", + "Enter Jupyter URL": "Jupyter URL'sini Girin", "Enter Kagi Search API Key": "Kagi Search API Anahtarını Girin", "Enter Key Behavior": "Enter Tuşu Davranışı", "Enter language codes": "Dil kodlarını girin", - "Enter MinerU API Key": "", - "Enter Mistral API Base URL": "", - "Enter Mistral API Key": "", + "Enter MinerU API Key": "MinerU API Anahtarını Girin", + "Enter Mistral API Base URL": "Mistral API Taban URL'sini Girin", + "Enter Mistral API Key": "Mistral API Anahtarını Girin", "Enter Model ID": "Model ID'sini Girin", "Enter model tag (e.g. {{modelTag}})": "Model etiketini girin (örn. {{modelTag}})", "Enter Mojeek Search API Key": "Mojeek Search API Anahtarını Girin", @@ -723,17 +723,17 @@ "Enter Perplexity API Key": "Perplexity API Anahtarını Girin", "Enter Perplexity Search API URL": "Perplexity Search API URL'sini Girin", "Enter Playwright Timeout": "Playwright Zaman Aşımını Girin", - "Enter Playwright WebSocket URL": "", - "Enter proxy URL (e.g. https://user:password@host:port)": "", - "Enter reasoning effort": "", + "Enter Playwright WebSocket URL": "Playwright WebSocket URL'sini Girin", + "Enter proxy URL (e.g. https://user:password@host:port)": "Vekil sunucu URL'sini girin (örn. https://user:password@host:port)", + "Enter reasoning effort": "Muhakeme çabasını girin", "Enter Score": "Skoru Girin", "Enter SearchApi API Key": "Arama-API Anahtarını Girin", "Enter SearchApi Engine": "Arama-API Motorunu Girin", "Enter Searxng Query URL": "Searxng Sorgu URL'sini girin", "Enter Searxng search language": "Searxng arama dilini girin", - "Enter Seed": " Tohum(seed) Girin", - "Enter SerpApi API Key": "", - "Enter SerpApi Engine": "", + "Enter Seed": "Tohum(seed) Girin", + "Enter SerpApi API Key": "SerpApi API Anahtarını Girin", + "Enter SerpApi Engine": "SerpApi Motorunu Girin", "Enter Serper API Key": "Serper API Anahtarını Girin", "Enter Serply API Key": "Serply API Anahtarını Girin", "Enter Serpstack API Key": "Serpstack API Anahtarını Girin", @@ -747,17 +747,17 @@ "Enter system prompt": "Sistem promptunu girin", "Enter system prompt here": "Sistem promptunu buraya girin.", "Enter Tavily API Key": "Tavily API Anahtarını Girin", - "Enter Tavily Extract Depth": "", - "Enter the public URL of your WebUI. This URL will be used to generate links in the notifications.": "", + "Enter Tavily Extract Depth": "Tavily Çıkarma Derinliğini Girin", + "Enter the public URL of your WebUI. This URL will be used to generate links in the notifications.": "WebUI'nizin herkese açık URL'sini girin. Bu URL, bildirimlerdeki bağlantıları oluşturmak için kullanılacaktır.", "Enter the URL of the function to import": "İçe aktarılacak fonksiyonun URL'sini girin", "Enter the URL to import": "İçe aktarılacak URL'yi girin", "Enter Tika Server URL": "Tika Sunucu URL'sini Girin", "Enter timeout in seconds": "Zaman aşımını saniye cinsinden girin", "Enter to Send": "Göndermek için Enter", "Enter Top K": "Top K'yı girin", - "Enter Top K Reranker": "", + "Enter Top K Reranker": "Top K Yeniden Sıralayıcıyı Girin", "Enter URL (e.g. http://127.0.0.1:7860/)": "URL'yi Girin (örn. http://127.0.0.1:7860/)", - "Enter URL (e.g. http://localhost:11434)": "URL'yi Girin (e.g. http://localhost:11434)", + "Enter URL (e.g. http://localhost:11434)": "URL'yi Girin (örn. http://localhost:11434)", "Enter value": "Bir değer girin", "Enter value (true/false)": "Bir değer girin (true/false)", "Enter Yacy Password": "Yacy Parolasını Girin", @@ -779,17 +779,17 @@ "Enter Your Role": "Rolünüzü Girin", "Enter Your Username": "Kullanıcı Adınızı Girin", "Enter your webhook URL": "Webhook URL'nizi girin", - "Entra ID": "", + "Entra ID": "Entra ID", "Error": "Hata", "ERROR": "HATA", "Error accessing directory": "Dizine erişilirken hata oluştu", "Error accessing Google Drive: {{error}}": "Google Drive'a erişim hatası: {{error}}", "Error accessing media devices.": "Medya cihazlarına erişirken hata oluştu.", "Error starting recording.": "Kayıt başlatılırken hata oluştu.", - "Error unloading model: {{error}}": "", + "Error unloading model: {{error}}": "Model bellekten boşaltılırken hata: {{error}}", "Error uploading file: {{error}}": "Dosya yüklenirken hata oluştu: {{error}}", - "Error: A model with the ID '{{modelId}}' already exists. Please select a different ID to proceed.": "Hata: '{{modelId}}' kimliğine sahip bir model zaten mevcut. Devam etmek için lütfen farklı bir kimlik seçin.", - "Error: Model ID cannot be empty. Please enter a valid ID to proceed.": "Hata: Model kimliği boş olamaz. Devam etmek için lütfen geçerli bir kimlik girin.", + "Error: A model with the ID '{{modelId}}' already exists. Please select a different ID to proceed.": "Hata: '{{modelId}}' ID'sine sahip bir model zaten mevcut. Devam etmek için lütfen farklı bir ID seçin.", + "Error: Model ID cannot be empty. Please enter a valid ID to proceed.": "Hata: Model ID'si boş olamaz. Devam etmek için lütfen geçerli bir ID girin.", "Evaluations": "Değerlendirmeler", "Exa API Key": "Exa API Anahtarı", "Example: (&(objectClass=inetOrgPerson)(uid=%s))": "Örnek: (&(objectClass=inetOrgPerson)(uid=%s))", @@ -799,9 +799,9 @@ "Example: sAMAccountName or uid or userPrincipalName": "Örnek: sAMAccountName or uid or userPrincipalName", "Exceeded the number of seats in your license. Please contact support to increase the number of seats.": "", "Exclude": "Hariç tut", - "Execute code": "", - "Execute code for analysis": "", - "Executing **{{NAME}}**...": "", + "Execute code": "Kodu çalıştır", + "Execute code for analysis": "Kodu analiz için çalıştır", + "Executing **{{NAME}}**...": "**{{NAME}}** yürütülüyor...", "Expand": "Genişlet", "Experimental": "Deneysel", "Explain": "Açıkla", @@ -813,7 +813,7 @@ "Export Chats": "Sohbetleri Dışa Aktar", "Export Config": "Yapılandırmayı Dışa Aktar", "Export Models": "Modelleri Dışa Aktar", - "Export Prompts": "", + "Export Prompts": "Promptları Dışa Aktar", "Export to CSV": "CSV'ye Aktar", "Export Tools": "Araçları Dışa Aktar", "Export Users": "Kullanıcıları Dışa Aktar", @@ -827,10 +827,10 @@ "Fade Effect for Streaming Text": "Akış Metni için Solma Efekti", "Failed to add file.": "Dosya eklenemedi.", "Failed to add members": "Üyeler eklenemedi", - "Failed to archive chat.": "", + "Failed to archive chat.": "Sohbet arşivlenemedi.", "Failed to attach file": "Dosya eklenemedi", "Failed to clear status": "Durum temizlenemedi", - "Failed to connect to {{URL}} OpenAPI tool server": "", + "Failed to connect to {{URL}} OpenAPI tool server": "{{URL}} OpenAPI araç sunucusuna bağlanılamadı", "Failed to connect to {{URL}} terminal server": "{{URL}} terminal sunucusuna bağlanılamadı", "Failed to copy link": "Bağlantı kopyalanamadı", "Failed to create API Key.": "API Anahtarı oluşturulamadı.", @@ -842,17 +842,17 @@ "Failed to generate title": "Başlık oluşturulamadı", "Failed to import models": "Modeller içe aktarılamadı", "Failed to load chat preview": "Sohbet ön izlemesi yüklenemedi", - "Failed to load DOCX file. Please try downloading it instead.": "", + "Failed to load DOCX file. Please try downloading it instead.": "DOCX dosyası yüklenemedi. Lütfen bunun yerine indirmeyi deneyin.", "Failed to load Excel/CSV file. Please try downloading it instead.": "Excel/CSV dosyası yüklenemedi. Lütfen bunun yerine indirmeyi deneyin.", "Failed to load file content.": "Dosya içeriği yüklenemedi.", "Failed to load Interface settings": "Arayüz ayarları yüklenemedi", - "Failed to load PPTX file. Please try downloading it instead.": "", + "Failed to load PPTX file. Please try downloading it instead.": "PPTX dosyası yüklenemedi. Lütfen bunun yerine indirmeyi deneyin.", "Failed to move chat": "Sohbet taşınamadı", - "Failed to process URL: {{url}}": "", + "Failed to process URL: {{url}}": "URL işlenemedi: {{url}}", "Failed to read clipboard contents": "Pano içeriği okunamadı", "Failed to remove member": "Üye kaldırılamadı", - "Failed to render diagram": "", - "Failed to render visualization": "", + "Failed to render diagram": "Diyagram oluşturulamadı", + "Failed to render visualization": "Görselleştirme oluşturulamadı", "Failed to save connections": "Bağlantılar kaydedilemedi", "Failed to save conversation": "Sohbet kaydedilemedi", "Failed to save models configuration": "Modeller yapılandırması kaydedilemedi", @@ -889,7 +889,7 @@ "File uploaded!": "Dosya yüklendi!", "Filename": "Dosya adı", "Files": "Dosyalar", - "Filter": "", + "Filter": "Filtre", "Filter is now globally disabled": "Filtre artık global olarak devre dışı", "Filter is now globally enabled": "Filtre artık global olarak devrede", "Filters": "Filtreler", @@ -898,47 +898,47 @@ "Firecrawl API Key": "Firecrawl API Anahtarı", "Firecrawl Timeout (s)": "Firecrawl Zaman Aşımı (s)", "Floating Quick Actions": "Yüzen Hızlı Eylemler", - "Focus Chat Input": "", + "Focus Chat Input": "Sohbet Girişine Odaklan", "Folder": "Klasör", "Folder Background Image": "Klasör Arka Plan Resmi", - "Folder created successfully": "", + "Folder created successfully": "Klasör başarıyla oluşturuldu", "Folder deleted successfully": "Klasör başarıyla silindi", - "Folder Max File Count": "", - "Folder name": "", + "Folder Max File Count": "Klasör Maksimum Dosya Sayısı", + "Folder name": "Klasör adı", "Folder Name": "Klasör Adı", "Folder name cannot be empty.": "Klasör adı boş olamaz.", "Folder name updated successfully": "Klasör adı başarıyla güncellendi", - "Folder options": "", + "Folder options": "Klasör seçenekleri", "Folder updated successfully": "Klasör başarıyla güncellendi", "Folders": "Klasörler", - "Follow up": "", - "Follow Up Generation": "", - "Follow Up Generation Prompt": "", - "Follow up: {{question}}": "", - "Follow-Up Auto-Generation": "Devam İstemlerini Otomatik Oluşturma", + "Follow up": "Takip", + "Follow Up Generation": "Takip Oluşturma", + "Follow Up Generation Prompt": "Takip Oluşturma Prompt'u", + "Follow up: {{question}}": "Takip sorusu: {{question}}", + "Follow-Up Auto-Generation": "Devam Prompt'larını Otomatik Oluşturma", "Followed instructions perfectly": "Talimatları mükemmel şekilde takip etti", "for placeholders": "", - "Force OCR": "", - "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "", + "Force OCR": "OCR Zorla", + "Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.": "PDF'nin tüm sayfalarında OCR zorla. PDF'lerinizde iyi metin varsa bu daha kötü sonuçlara yol açabilir. Varsayılan olarak False.", "Forge new paths": "Yeni yollar açın", "Form": "Form", - "Format Lines": "", - "Format the lines in the output. Defaults to False. If set to True, the lines will be formatted to detect inline math and styles.": "", - "Formatting may be inconsistent from source.": "", - "Forwards system user OAuth access token to authenticate": "", - "Forwards system user session credentials to authenticate": "", - "Full Context Mode": "", + "Format Lines": "Satırları Biçimlendir", + "Format the lines in the output. Defaults to False. If set to True, the lines will be formatted to detect inline math and styles.": "Çıktıdaki satırları biçimlendir. Varsayılan olarak False. True olarak ayarlanırsa, satırlar satır içi matematik ve stilleri algılamak için biçimlendirilecektir.", + "Formatting may be inconsistent from source.": "Biçimlendirme kaynaktan tutarsız olabilir.", + "Forwards system user OAuth access token to authenticate": "Kimlik doğrulamak için sistem kullanıcı OAuth erişim belirtecini iletir", + "Forwards system user session credentials to authenticate": "Kimlik doğrulamak için sistem kullanıcı oturum kimlik bilgilerini iletir", + "Full Context Mode": "Tam Bağlam Modu", "Function": "Fonksiyon", "Function Calling": "Fonksiyon Çağırma", "Function created successfully": "Fonksiyon başarıyla oluşturuldu", "Function deleted successfully": "Fonksiyon başarıyla silindi", "Function Description": "Fonksiyon Açıklaması", - "Function ID": "", - "Function imported successfully": "", + "Function ID": "Fonksiyon ID'si", + "Function imported successfully": "Fonksiyon başarıyla içe aktarıldı", "Function is now globally disabled": "Fonksiyon artık global olarak devre dışı", "Function is now globally enabled": "Fonksiyon artık global olarak aktif", "Function Name": "Fonksiyon Adı", - "Function Name Filter List": "", + "Function Name Filter List": "Fonksiyon Adı Filtre Listesi", "Function updated successfully": "Fonksiyon başarıyla güncellendi", "Functions": "Fonksiyonlar", "Functions allow arbitrary code execution.": "Fonksiyonlar keyfi kod yürütülmesine izin verir.", @@ -959,7 +959,7 @@ "Generating search query": "Arama sorgusu oluşturma", "Generating...": "Oluşturuluyor...", "Get current time and perform date/time calculations": "", - "Get information on {{name}} in the UI": "", + "Get information on {{name}} in the UI": "{{name}} hakkında arayüzde bilgi alın", "Get started": "Başlayın", "Get started with {{WEBUI_NAME}}": "{{WEBUI_NAME}} ile başlayın", "Global": "Evrensel", @@ -991,7 +991,7 @@ "Help the community discover great models": "", "Hex Color": "", "Hex Color - Leave empty for default color": "", - "Hidden": "", + "Hidden": "Gizli", "Hide": "Gizle", "Hide All": "", "Hide from Sidebar": "", @@ -999,7 +999,7 @@ "High": "", "High Contrast Mode": "Yüksek Kontrast Modu", "History": "", - "Home": "", + "Home": "Ana Sayfa", "Host": "Ana bilgisayar", "Hourly Messages": "", "How can I help you today?": "Bugün size nasıl yardımcı olabilirim?", @@ -1019,17 +1019,17 @@ "Image Compression": "Görüntü Sıkıştırma", "Image Compression Height": "Görüntü Sıkıştırma Yüksekliği", "Image Compression Width": "Görüntü Sıkıştırma Genişliği", - "Image Edit": "", - "Image Edit Engine": "", + "Image Edit": "Görüntü Düzenleme", + "Image Edit Engine": "Görüntü Düzenleme Motoru", "Image Generation": "Görüntü Oluşturma", "Image Generation Engine": "Görüntü Oluşturma Motoru", "Image Max Compression Size": "Görüntü Maksimum Sıkıştırma Boyutu", - "Image Max Compression Size height": "", - "Image Max Compression Size width": "", - "Image Prompt Generation": "", - "Image Prompt Generation Prompt": "", - "Image Size": "", - "Images": "", + "Image Max Compression Size height": "Görüntü Maksimum Sıkıştırma Boyutu yüksekliği", + "Image Max Compression Size width": "Görüntü Maksimum Sıkıştırma Boyutu genişliği", + "Image Prompt Generation": "Görüntü Prompt Oluşturma", + "Image Prompt Generation Prompt": "Görüntü Prompt Oluşturma Promptu", + "Image Size": "Görüntü Boyutu", + "Images": "Görüntüler", "Import": "İçe Aktar", "Import Chats": "Sohbetleri İçe Aktar", "Import Config": "", @@ -1054,24 +1054,24 @@ "Input Key (e.g. text, unet_name, steps)": "", "Input Variables": "", "Insert": "", - "Insert Follow-Up Prompt to Input": "Devam İstemini Girdiye Ekle", - "Insert Prompt as Rich Text": "İstemi Zengin Metin Olarak Ekle", - "Insert Suggestion Prompt to Input": "Öneri İstemini Girdiye Ekle", + "Insert Follow-Up Prompt to Input": "Devam Prompt'unu Girdiye Ekle", + "Insert Prompt as Rich Text": "Prompt'u Zengin Metin Olarak Ekle", + "Insert Suggestion Prompt to Input": "Öneri Prompt'unu Girdiye Ekle", "Install from Github URL": "Github URL'sinden yükleyin", "Instant Auto-Send After Voice Transcription": "Ses Transkripsiyonundan Sonra Anında Otomatik Gönder", "Integration": "", "Integrations": "", "Interface": "Arayüz", "Interface Settings Access": "", - "Invalid file content": "", + "Invalid file content": "Geçersiz dosya içeriği", "Invalid file format.": "Geçersiz dosya biçimi.", - "Invalid JSON file": "", - "Invalid JSON format for ComfyUI Edit Workflow.": "", - "Invalid JSON format for ComfyUI Workflow.": "", - "Invalid JSON format for Parameters": "", - "Invalid JSON format in {{NAME}}": "", - "Invalid JSON format in Additional Config": "", - "Invalid JSON format in MinerU Parameters": "", + "Invalid JSON file": "Geçersiz JSON dosyası", + "Invalid JSON format for ComfyUI Edit Workflow.": "ComfyUI Düzenleme İş Akışı için geçersiz JSON formatı.", + "Invalid JSON format for ComfyUI Workflow.": "ComfyUI İş Akışı için geçersiz JSON formatı.", + "Invalid JSON format for Parameters": "Parametreler için geçersiz JSON formatı", + "Invalid JSON format in {{NAME}}": "{{NAME}} içinde geçersiz JSON formatı", + "Invalid JSON format in Additional Config": "Ek Yapılandırma içinde geçersiz JSON formatı", + "Invalid JSON format in MinerU Parameters": "MinerU Parametreleri içinde geçersiz JSON formatı", "is typing...": "yazıyor...", "Italic": "", "January": "Ocak", @@ -1088,7 +1088,7 @@ "JWT Expiration": "JWT Bitişi", "JWT Token": "JWT Token", "Kagi Search API Key": "Kagi Arama API Anahtarı", - "Keep Follow-Up Prompts in Chat": "Devam İstemlerini Sohbette Tut", + "Keep Follow-Up Prompts in Chat": "Devam Prompt'larını Sohbette Tut", "Keep in Sidebar": "", "Key": "Anahtar", "Key is required": "Anahtar gerekli", @@ -1096,15 +1096,15 @@ "Keyboard Shortcuts": "", "Knowledge": "Bilgi", "Knowledge Access": "Bilgi Erişimi", - "Knowledge Base": "", + "Knowledge Base": "Bilgi Tabanı", "Knowledge created successfully.": "Bilgi başarıyla oluşturuldu.", "Knowledge deleted successfully.": "Bilgi başarıyla silindi.", - "Knowledge Description": "", - "Knowledge exported successfully": "", - "Knowledge Name": "", - "Knowledge Public Sharing": "", + "Knowledge Description": "Bilgi Açıklaması", + "Knowledge exported successfully": "Bilgi başarıyla dışa aktarıldı", + "Knowledge Name": "Bilgi Adı", + "Knowledge Public Sharing": "Bilginin Herkese Açık Paylaşımı", "Knowledge reset successfully.": "Bilgi başarıyla sıfırlandı.", - "Knowledge Sharing": "", + "Knowledge Sharing": "Bilgi Paylaşımı", "Knowledge updated successfully": "Bilgi başarıyla güncellendi", "Kokoro.js (Browser)": "", "Kokoro.js Dtype": "", @@ -1127,7 +1127,7 @@ "Learn more about Open Terminal": "Open Terminal hakkında daha fazla bilgi edinin", "Learn more about OpenAPI tool servers.": "OpenAPI araç sunucuları hakkında daha fazla bilgi edinin.", "Learn more about Voxtral transcription.": "", - "Leave a public review for {{modelName}}": "", + "Leave a public review for {{modelName}}": "{{modelName}} için herkese açık değerlendirme yapın", "Leave empty for no compression": "", "Leave empty for unlimited": "Sınırsız için boş bırakınız", "Leave empty to include all models from \"{{url}}\" endpoint": "", @@ -1183,7 +1183,7 @@ "Max Upload Count": "Maksimum Yükleme Sayısı", "Max Upload Size": "Maksimum Yükleme Boyutu", "Maximum number of files allowed per folder.": "", - "Maximum number of files per folder is {{max}}.": "", + "Maximum number of files per folder is {{max}}.": "Klasör başına maksimum dosya sayısı {{max}}.", "Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Aynı anda en fazla 3 model indirilebilir. Lütfen daha sonra tekrar deneyin.", "May": "Mayıs", "MBR": "", @@ -1198,7 +1198,7 @@ "Memories accessible by LLMs will be shown here.": "LLM'ler tarafından erişilebilen bellekler burada gösterilecektir.", "Memory": "Bellek", "Memory added successfully": "Bellek başarıyla eklendi", - "Memory cleared successfully": "Bellek başarıyle temizlendi", + "Memory cleared successfully": "Bellek başarıyla temizlendi", "Memory deleted successfully": "Bellek başarıyla silindi", "Memory updated successfully": "Bellek başarıyla güncellendi", "Merge Responses": "Yanıtları Birleştir", @@ -1229,61 +1229,61 @@ "Model accepts file inputs": "Model dosya girdilerini kabul eder", "Model accepts image inputs": "Model görüntü girdilerini kabul eder", "Model can execute code and perform calculations": "Model kod çalıştırabilir ve hesaplamalar yapabilir", - "Model can generate images based on text prompts": "", + "Model can generate images based on text prompts": "Model, metin promptlarına göre görsel oluşturabilir", "Model can search the web for information": "Model bilgileri aramak için web'de arama yapabilir", "Model Capabilities": "Model Yetenekleri", "Model created successfully!": "Model başarıyla oluşturuldu!", "Model filesystem path detected. Model shortname is required for update, cannot continue.": "Model dosya sistemi yolu algılandı. Güncelleme için model kısa adı gerekli, devam edilemiyor.", "Model Filtering": "Model Filtreleme", "Model ID": "Model ID", - "Model ID is required.": "", - "Model IDs": "Model Kimlikleri", + "Model ID is required.": "Model ID'si gereklidir.", + "Model IDs": "Model ID'leri", "Model Name": "Model Adı", - "Model name already exists, please choose a different one": "", - "Model Name is required.": "", - "Model names and usage frequency": "", - "Model not found": "", + "Model name already exists, please choose a different one": "Model adı zaten mevcut, lütfen farklı bir ad seçin", + "Model Name is required.": "Model adı gereklidir.", + "Model names and usage frequency": "Model adları ve kullanım sıklığı", + "Model not found": "Model bulunamadı", "Model not selected": "Model seçilmedi", - "Model Parameters": "", + "Model Parameters": "Model Parametreleri", "Model Params": "Model Parametreleri", "Model Permissions": "Model İzinleri", - "Model responses or outputs": "", - "Model unloaded successfully": "", + "Model responses or outputs": "Model yanıtları veya çıktıları", + "Model unloaded successfully": "Model bellekten başarıyla boşaltıldı", "Model updated successfully": "Model başarıyla güncellendi", - "Model Usage": "", - "Model(s) do not support file upload": "", + "Model Usage": "Model Kullanımı", + "Model(s) do not support file upload": "Model(ler) dosya yüklemeyi desteklemiyor", "Modelfile Content": "Model Dosyası İçeriği", "Models": "Modeller", "Models Access": "Modellere Erişim", "Models configuration saved successfully": "Modellerin yapılandırması başarıyla kaydedildi", - "Models imported successfully": "", - "Models Public Sharing": "", - "Models Sharing": "", + "Models imported successfully": "Modeller başarıyla içe aktarıldı", + "Models Public Sharing": "Modellerin Herkese Açık Paylaşımı", + "Models Sharing": "Model Paylaşımı", "Mojeek": "", "Mojeek Search API Key": "Mojeek Search API Anahtarı", "More": "Daha Fazla", "More Concise": "", "More options": "", "More Options": "", - "Move": "", - "Moved {{name}}": "", + "Move": "Taşı", + "Moved {{name}}": "{{name}} taşındı", "My Terminal": "Terminalim", "Name": "Ad", "Name and ID are required, please fill them out": "", "Name your knowledge base": "Bilgi tabanınıza bir ad verin", "Native": "", - "New": "", + "New": "Yeni", "New Button": "", "New Chat": "Yeni Sohbet", "New File": "", "New Folder": "Yeni Klasör", - "New Function": "", + "New Function": "Yeni Fonksiyon", "New Group": "", "New Knowledge": "", - "New Model": "", + "New Model": "Yeni Model", "New Note": "", "New Password": "Yeni Parola", - "New Prompt": "", + "New Prompt": "Yeni Prompt", "New Skill": "Yeni Yetenek", "New Temporary Chat": "", "New Terminal": "Yeni Terminal", @@ -1291,59 +1291,59 @@ "New Webhook": "", "new-channel": "yeni-kanal", "Next message": "", - "No access grants. Private to you.": "", - "No activity data": "", - "No authentication": "", - "No chats found": "", - "No chats found for this user.": "", - "No chats found.": "", + "No access grants. Private to you.": "Erişim izni yok. Size özel.", + "No activity data": "Aktivite verisi yok", + "No authentication": "Kimlik doğrulama yok", + "No chats found": "Sohbet bulunamadı", + "No chats found for this user.": "Bu kullanıcı için sohbet bulunamadı.", + "No chats found.": "Sohbet bulunamadı.", "No content": "İçerik yok", "No content found": "İçerik bulunamadı", "No content to speak": "Konuşacak içerik yok", - "No conversation to save": "", - "No data": "", - "No data found": "", + "No conversation to save": "Kaydedilecek sohbet yok", + "No data": "Veri yok", + "No data found": "Veri bulunamadı", "No distance available": "Mesafe mevcut değil", - "No expiration can pose security risks.": "", - "No feedback found": "", + "No expiration can pose security risks.": "Son kullanma tarihi olmaması güvenlik riskleri oluşturabilir.", + "No feedback found": "Geri bildirim bulunamadı", "No file selected": "Hiçbir dosya seçilmedi", - "No files found": "", - "No files in this knowledge base.": "", - "No files yet. Upload files or run Python code to create them.": "", - "No functions found": "", - "No groups found": "", - "No history available": "", + "No files found": "Dosya bulunamadı", + "No files in this knowledge base.": "Bu bilgi tabanında dosya yok.", + "No files yet. Upload files or run Python code to create them.": "Henüz dosya yok. Dosya yükleyin veya oluşturmak için Python kodu çalıştırın.", + "No functions found": "Fonksiyon bulunamadı", + "No groups found": "Grup bulunamadı", + "No history available": "Geçmiş mevcut değil", "No HTML, CSS, or JavaScript content found.": "HTML, CSS veya JavaScript içeriği bulunamadı.", - "No inference engine with management support found": "", - "No kernel": "", - "No knowledge bases found.": "", + "No inference engine with management support found": "Yönetim desteği olan çıkarım motoru bulunamadı", + "No kernel": "Kernel yok", + "No knowledge bases found.": "Bilgi tabanı bulunamadı.", "No knowledge found": "Bilgi bulunamadı", "No memories to clear": "Temizlenecek bellek yok", "No model IDs": "Model ID yok", - "No models available": "", + "No models available": "Kullanılabilir model yok", "No models found": "Model bulunamadı", "No models selected": "Model seçilmedi", "No Notes": "Not Yok", - "No notes found": "", - "No one": "", - "No pinned messages": "", - "No prompts found": "", + "No notes found": "Not bulunamadı", + "No one": "Hiç kimse", + "No pinned messages": "Sabitlenmiş mesaj yok", + "No prompts found": "Prompt bulunamadı", "No results": "Sonuç bulunamadı", "No results found": "Sonuç bulunamadı", "No search query generated": "Hiç arama sorgusu oluşturulmadı", - "No servers detected": "", + "No servers detected": "Sunucu algılanmadı", "No skills found": "Yetenek bulunamadı", "No source available": "Kaynak mevcut değil", - "No sources found": "", - "No suggestion prompts": "Önerilen istem yok", + "No sources found": "Kaynak bulunamadı", + "No suggestion prompts": "Önerilen prompt yok", "No Terminal connection configured.": "Yapılandırılmış Terminal bağlantısı yok.", "No terminal connections configured.": "Yapılandırılmış terminal bağlantısı yok.", - "No tool server connections configured.": "", - "No tools found": "", + "No tool server connections configured.": "Yapılandırılmış araç sunucusu bağlantısı yok.", + "No tools found": "Araç bulunamadı", "No users were found.": "Kullanıcı bulunamadı.", "No valves": "", - "No valves to update": "Güncellenecek valvler yok", - "No webhooks yet": "", + "No valves to update": "Güncellenecek valfler yok", + "No webhooks yet": "Henüz webhook yok", "Node Ids": "", "None": "Yok", "Not factually correct": "Gerçeklere göre doğru değil", @@ -1384,10 +1384,10 @@ "Only markdown files are allowed": "Yalnızca markdown biçimli dosyalar kullanılabilir", "Only select users and groups with permission can access": "İzinli kullanıcılar ve gruplar yalnızca erişebilir", "Only sync new/updated chats": "", - "Oops! Looks like the URL is invalid. Please double-check and try again.": "Hop! URL geçersiz gibi görünüyor. Lütfen tekrar kontrol edin ve yeniden deneyin.", - "Oops! There are files still uploading. Please wait for the upload to complete.": "Hop! Hala yüklenen dosyalar var. Yüklemenin tamamlanmasını bekleyin.", - "Oops! There was an error in the previous response.": "Hop! Önceki yanıtta bir hata oluştu.", - "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Hop! Desteklenmeyen bir yöntem kullanıyorsunuz (yalnızca önyüz). Lütfen WebUI'yi arkayüzden sunun.", + "Oops! Looks like the URL is invalid. Please double-check and try again.": "Hay aksi! URL geçersiz gibi görünüyor. Lütfen tekrar kontrol edin ve yeniden deneyin.", + "Oops! There are files still uploading. Please wait for the upload to complete.": "Hay aksi! Hala yüklenen dosyalar var. Yüklemenin tamamlanmasını bekleyin.", + "Oops! There was an error in the previous response.": "Hay aksi! Önceki yanıtta bir hata oluştu.", + "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Hay aksi! Desteklenmeyen bir yöntem kullanıyorsunuz (yalnızca önyüz). Lütfen WebUI'yi arka uçtan sunun.", "Open file": "Dosyayı aç", "Open in full screen": "Tam ekranda aç", "Open link": "", @@ -1395,12 +1395,12 @@ "Open Modal To Manage Floating Quick Actions": "Yüzen hızlı eylemleri yönetmek için pencereyi aç", "Open Modal To Manage Image Compression": "Görüntü sıkıştırmayı yönetmek için pencereyi aç", "Open Model Selector": "", - "Open Settings": "", - "Open Sidebar": "", + "Open Settings": "Ayarları Aç", + "Open Sidebar": "Kenar Çubuğunu Aç", "Open Terminal": "Terminali Aç", "Open User Profile Menu": "", "Open WebUI can use tools provided by any OpenAPI server.": "Open WebUI OpenAPI tarafından sağlanan araçları kullanabilir", - "Open WebUI uses faster-whisper internally.": "Open WebUI, dahili olarak daha hızlı-fısıltı kullanır.", + "Open WebUI uses faster-whisper internally.": "Open WebUI, dahili olarak faster-whisper kullanır.", "Open WebUI uses SpeechT5 and CMU Arctic speaker embeddings.": "Open WebUI, SpeechT5 ve CMU Arctic konuşmacı gömme kullanır.", "Open WebUI version": "", "Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "Open-WebUI sürümü (v{{OPEN_WEBUI_VERSION}}) gerekli sürümden (v{{REQUIRED_VERSION}}) düşük", @@ -1416,7 +1416,7 @@ "OpenAPI Spec": "", "openapi.json URL or Path": "", "optional": "", - "Optional": "", + "Optional": "İsteğe Bağlı", "or": "veya", "Ordered List": "", "Other": "Diğer", @@ -1462,14 +1462,14 @@ "Pipelines": "", "Pipelines are a plugin system with arbitrary code execution —": "Pipelines, keyfi kod çalıştırmaya izin veren bir eklenti sistemidir —", "Pipelines Not Detected": "Pipeline Tespit Edilmedi", - "Pipelines Valves": "Pipeline Valvleri", + "Pipelines Valves": "Pipeline Valfleri", "Plain text (.md)": "Düz Metin (.md)", "Plain text (.txt)": "Düz metin (.txt)", "Playground": "Oyun Alanı", "Playwright Timeout (ms)": "Playwright Zamanaşımı (ms)", "Playwright WebSocket URL": "Playwright WebSocket URL", "Please carefully review the following warnings:": "Lütfen aşağıdaki uyarıları dikkatlice inceleyin:", - "Please do not close the settings page while loading the model.": "Lütfen model yüklenirken ayarlar sayfasını kapatmayınız", + "Please do not close the settings page while loading the model.": "Lütfen model yüklenirken ayarlar sayfasını kapatmayınız.", "Please enter a message or attach a file.": "", "Please enter a prompt": "Lütfen bir prompt girin", "Please enter a valid ID": "Lütfen geçerli bir ID girin", @@ -1493,7 +1493,7 @@ "Prefix ID": "", "Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "", "Prevent File Creation": "", - "Preview": "", + "Preview": "Önizleme", "Previous 30 days": "Önceki 30 gün", "Previous 7 days": "Önceki 7 gün", "Previous message": "", @@ -1501,19 +1501,19 @@ "Private conversation between selected users": "", "Production version updated": "", "Profile": "Profil", - "Prompt": "İstem", + "Prompt": "Prompt", "Prompt Autocompletion": "", - "Prompt Content": "İstem İçeriği", + "Prompt Content": "Prompt İçeriği", "Prompt created successfully": "Prompt başarıyla oluşturuldu", "Prompt Name": "", "Prompt Suggestions": "", "Prompt updated successfully": "Prompt başarıyla güncellendi", - "Prompts": "İstemler", - "Prompts Access": "İstemlere Erişim", + "Prompts": "Prompt'lar", + "Prompts Access": "Prompt'lara Erişim", "Prompts Public Sharing": "", "Prompts Sharing": "", "Provider Type": "", - "Public": "", + "Public": "Herkese Açık", "Pull \"{{searchValue}}\" from Ollama.com": "Ollama.com'dan \"{{searchValue}}\" çekin", "Pull a model from Ollama.com": "Ollama.com'dan bir model çekin", "Pull Model": "", @@ -1522,7 +1522,7 @@ "Querying": "", "Quick Actions": "Hızlı Eylemler", "RAG Template": "RAG Şablonu", - "Rate {{rating}} out of 10": "", + "Rate {{rating}} out of 10": "{{rating}}/10 puan", "Rating": "Derecelendirme", "Re-rank models by topic similarity": "Konu benzerliğine göre modelleri yeniden sırala", "Read": "Oku", @@ -1539,7 +1539,7 @@ "Reduces the probability of generating nonsense. A higher value (e.g. 100) will give more diverse answers, while a lower value (e.g. 10) will be more conservative.": "", "Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Kendinizden \"User\" olarak bahsedin (örneğin, \"User İspanyolca öğreniyor\")", "Reference Chats": "", - "Refresh": "", + "Refresh": "Yenile", "Refused when it shouldn't have": "Reddedilmemesi gerekirken reddedildi", "Regenerate": "Tekrar Oluştur", "Regenerate Menu": "Yeniden Oluşturma Menüsü", @@ -1557,7 +1557,7 @@ "Relevance Threshold": "İlgi Eşiği", "Remember Dismissal": "", "Remove": "Kaldır", - "Remove {{MODELID}} from list.": "", + "Remove {{MODELID}} from list.": "{{MODELID}} modelini listeden kaldır.", "Remove action": "", "Remove file": "", "Remove File": "", @@ -1590,9 +1590,9 @@ "RESULT": "Sonuç", "Retrieval": "", "Retrieval Query Generation": "Alıntı Sorgu Oluşturma", - "Retrieved {{count}} sources": "", - "Retrieved {{count}} sources_one": "", - "Retrieved {{count}} sources_other": "", + "Retrieved {{count}} sources": "{{count}} kaynak alındı", + "Retrieved {{count}} sources_one": "{{count}} kaynak alındı", + "Retrieved {{count}} sources_other": "{{count}} kaynak alındı", "Retrieved 1 source": "", "Rich Text Input for Chat": "Sohbet için Zengin Metin Girişi", "Role": "Rol", @@ -1606,7 +1606,7 @@ "Save & Create": "Kaydet ve Oluştur", "Save & Update": "Kaydet ve Güncelle", "Save As Copy": "Kopya Olarak Kaydet", - "Save Chat": "", + "Save Chat": "Sohbeti Kaydet", "Saved": "Kaydedildi", "Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Sohbet kayıtlarının doğrudan tarayıcınızın depolama alanına kaydedilmesi artık desteklenmemektedir. Lütfen aşağıdaki butona tıklayarak sohbet kayıtlarınızı indirmek ve silmek için bir dakikanızı ayırın. Endişelenmeyin, sohbet günlüklerinizi arkayüze kolayca yeniden aktarabilirsiniz:", "Scroll On Branch Change": "Dal Değişiminde Kaydır", @@ -1636,7 +1636,7 @@ "Search Prompts": "Prompt Ara", "Search Result Count": "Arama Sonucu Sayısı", "Search Skills": "Yetenekleri Ara", - "Search the internet": "İNternette Ara", + "Search the internet": "İnternette Ara", "Search the web and fetch URLs": "Web'de ara ve URL'leri getir", "Search Tools": "Arama Araçları", "Search, view, and manage user notes": "Kullanıcı notlarını ara, görüntüle ve yönet", @@ -1653,9 +1653,9 @@ "See what's new": "Yeniliklere göz atın", "Seed": "Seed", "Select": "Seç", - "Select {{modelName}} model": "", + "Select {{modelName}} model": "{{modelName}} modelini seç", "Select a base model": "Bir temel model seç", - "Select a base model (e.g. llama3, gpt-4o)": "", + "Select a base model (e.g. llama3, gpt-4o)": "Bir temel model seçin (örn. llama3, gpt-4o)", "Select a conversation to preview": "Bir sohbeti önizlemek için seç", "Select a engine": "Bir motor seç", "Select a function": "Bir fonksiyon seç", @@ -1663,35 +1663,35 @@ "Select a language": "Bir dil seç", "Select a mode": "Bir mod seç", "Select a model": "Bir model seç", - "Select a model (optional)": "", + "Select a model (optional)": "Bir model seçin (isteğe bağlı)", "Select a pipeline": "Bir pipeline seç", "Select a pipeline url": "Bir pipeline URL'si seç", - "Select a reranking model engine": "", - "Select a role": "", - "Select a theme": "", + "Select a reranking model engine": "Bir yeniden sıralama modeli motoru seçin", + "Select a role": "Bir rol seçin", + "Select a theme": "Bir tema seçin", "Select a tool": "Bir araç seç", - "Select a voice": "", + "Select a voice": "Bir ses seçin", "Select an auth method": "Yetkilendirme yöntemi seç", - "Select an embedding model engine": "", - "Select an engine": "", - "Select an Ollama instance": "", - "Select an option": "", - "Select an output format": "", - "Select dtype": "", + "Select an embedding model engine": "Bir gömme modeli motoru seçin", + "Select an engine": "Bir motor seçin", + "Select an Ollama instance": "Bir Ollama sunucusu seçin", + "Select an option": "Bir seçenek seçin", + "Select an output format": "Bir çıktı formatı seçin", + "Select dtype": "dtype seçin", "Select Engine": "Motor Seç", - "Select how to split message text for TTS requests": "", + "Select how to split message text for TTS requests": "TTS istekleri için mesaj metninin nasıl bölüneceğini seçin", "Select Knowledge": "Bilgi Seç", - "Select Method": "", + "Select Method": "Yöntem Seçin", "Select only one model to call": "Arama için sadece bir model seç", - "Select view": "", - "Selected model: {{modelName}}": "", + "Select view": "Görünüm seçin", + "Selected model: {{modelName}}": "Seçilen model: {{modelName}}", "Selected model(s) do not support image inputs": "Seçilen model(ler) görüntü girişlerini desteklemiyor", - "Selected Models": "", - "semantic": "", + "Selected Models": "Seçilen Modeller", + "semantic": "semantik", "Send": "Gönder", "Send a Message": "Bir Mesaj Gönder", "Send message": "Mesaj gönder", - "Send now": "", + "Send now": "Şimdi gönder", "Sends `stream_options: { include_usage: true }` in the request.\nSupported providers will return token usage information in the response when set.": "İsteğe `stream_options: { include_usage: true }` gönderir.\nDesteklenen sağlayıcılar, ayarlandığında yanıtta token kullanım bilgilerini döndürecektir.", "September": "Eylül", "SerpApi API Key": "SerpApi API Anahtarı", @@ -1700,60 +1700,60 @@ "Serply API Key": "Serply API Anahtarı", "Serpstack API Key": "Serpstack API Anahtarı", "Server connection verified": "Sunucu bağlantısı doğrulandı", - "Session": "", + "Session": "Oturum", "Set as default": "Varsayılan olarak ayarla", - "Set as Production": "", + "Set as Production": "Prodüksiyon Olarak Ayarla", "Set embedding model": "Gömme modelini ayarla", "Set embedding model (e.g. {{model}})": "Gömme modelini ayarlayın (örn. {{model}})", "Set reranking model (e.g. {{model}})": "Yeniden sıralama modelini ayarlayın (örn. {{model}})", - "Set the default models that are automatically selected for all users when a new chat is created.": "", - "Set the models that are automatically pinned to the sidebar for all users.": "", - "Set the number of layers, which will be off-loaded to GPU. Increasing this value can significantly improve performance for models that are optimized for GPU acceleration but may also consume more power and GPU resources.": "", - "Set the number of worker threads used for computation. This option controls how many threads are used to process incoming requests concurrently. Increasing this value can improve performance under high concurrency workloads but may also consume more CPU resources.": "", + "Set the default models that are automatically selected for all users when a new chat is created.": "Yeni bir sohbet oluşturulduğunda tüm kullanıcılar için otomatik olarak seçilen varsayılan modelleri ayarlayın.", + "Set the models that are automatically pinned to the sidebar for all users.": "Tüm kullanıcılar için kenar çubuğuna otomatik olarak sabitlenen modelleri ayarlayın.", + "Set the number of layers, which will be off-loaded to GPU. Increasing this value can significantly improve performance for models that are optimized for GPU acceleration but may also consume more power and GPU resources.": "GPU'ya boşaltılacak katman sayısını ayarlayın. Bu değerin artırılması, GPU hızlandırması için optimize edilmiş modeller için performansı önemli ölçüde iyileştirebilir, ancak aynı zamanda daha fazla güç ve GPU kaynağı tüketebilir.", + "Set the number of worker threads used for computation. This option controls how many threads are used to process incoming requests concurrently. Increasing this value can improve performance under high concurrency workloads but may also consume more CPU resources.": "Hesaplama için kullanılan işçi iş parçacığı sayısını ayarlayın. Bu seçenek, gelen istekleri eşzamanlı olarak işlemek için kaç iş parçacığı kullanılacağını kontrol eder. Bu değerin artırılması yüksek eşzamanlılık iş yüklerinde performansı iyileştirebilir, ancak aynı zamanda daha fazla CPU kaynağı tüketebilir.", "Set Voice": "Ses Ayarla", - "Set whisper model": "Fısıltı modelini ayarla", - "Set your status": "", - "Sets a flat bias against tokens that have appeared at least once. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 0.9) will be more lenient. At 0, it is disabled.": "", - "Sets a scaling bias against tokens to penalize repetitions, based on how many times they have appeared. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 0.9) will be more lenient. At 0, it is disabled.": "", - "Sets how far back for the model to look back to prevent repetition.": "", - "Sets the random number seed to use for generation. Setting this to a specific number will make the model generate the same text for the same prompt.": "", - "Sets the size of the context window used to generate the next token.": "", + "Set whisper model": "Whisper modelini ayarla", + "Set your status": "Durumunuzu ayarlayın", + "Sets a flat bias against tokens that have appeared at least once. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 0.9) will be more lenient. At 0, it is disabled.": "En az bir kez ortaya çıkan tokenlere karşı düz bir sapma ayarlar. Daha yüksek bir değer (örneğin, 1.5) tekrarları daha güçlü cezalandırırken, daha düşük bir değer (örneğin, 0.9) daha hoşgörülü olacaktır. 0 olduğunda devre dışıdır.", + "Sets a scaling bias against tokens to penalize repetitions, based on how many times they have appeared. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 0.9) will be more lenient. At 0, it is disabled.": "Tekrarları cezalandırmak için tokenlere karşı ölçeklenebilir bir sapma ayarlar, kaç kez ortaya çıktıklarına dayanarak. Daha yüksek bir değer (örneğin, 1.5) tekrarları daha güçlü cezalandırırken, daha düşük bir değer (örneğin, 0.9) daha hoşgörülü olacaktır. 0 olduğunda devre dışıdır.", + "Sets how far back for the model to look back to prevent repetition.": "Modelin tekrarı önlemek için ne kadar geriye bakması gerektiğini ayarlar.", + "Sets the random number seed to use for generation. Setting this to a specific number will make the model generate the same text for the same prompt.": "Oluşturma için kullanılacak rastgele sayı tohumunu ayarlar. Bunun belirli bir sayıya ayarlanması, modelin aynı prompt için aynı metni oluşturmasını sağlar.", + "Sets the size of the context window used to generate the next token.": "Sonraki tokeni oluşturmak için kullanılan bağlam penceresinin boyutunu ayarlar.", "Sets the stop sequences to use. When this pattern is encountered, the LLM will stop generating text and return. Multiple stop patterns may be set by specifying multiple separate stop parameters in a modelfile.": "Kullanılacak durma dizilerini ayarlar. Bu desenle karşılaşıldığında, LLM metin oluşturmayı durduracak ve geri dönecektir. Birden çok durma deseni, bir modelfile'da birden çok ayrı durma parametresi belirterek ayarlanabilir.", - "Setting": "", + "Setting": "Ayar", "Settings": "Ayarlar", - "Settings Permissions": "", + "Settings Permissions": "Ayarlar İzinleri", "Settings saved successfully!": "Ayarlar başarıyla kaydedildi!", "Share": "Paylaş", "Share Chat": "Sohbeti Paylaş", - "Share link copied to clipboard.": "", + "Share link copied to clipboard.": "Bağlantı panoya kopyalandı.", "Share to Open WebUI Community": "OpenWebUI Topluluğu ile Paylaş", - "Share your background and interests": "", - "Shared Chats": "", - "Shared with you": "", - "Sharing Permissions": "", + "Share your background and interests": "Arka planınızı ve ilgi alanlarınızı paylaşın", + "Shared Chats": "Paylaşılan Sohbetler", + "Shared with you": "Sizinle paylaşılan", + "Sharing Permissions": "Paylaşım İzinleri", "Show": "Göster", "Show \"What's New\" modal on login": "Girişte \"Yenilikler\" modalını göster", "Show Admin Details in Account Pending Overlay": "Yönetici Ayrıntılarını Hesap Bekliyor Ekranında Göster", - "Show All": "", - "Show all ({{COUNT}} characters)": "", - "Show Files": "", + "Show All": "Tümünü Göster", + "Show all ({{COUNT}} characters)": "Tümünü göster ({{COUNT}} karakter)", + "Show Files": "Dosyaları Göster", "Show Formatting Toolbar": "Biçimlendirme Araç Çubuğunu Göster", - "Show image preview": "", + "Show image preview": "Görsel önizlemesini göster", "Show Model": "Modeli Göster", - "Show Shortcuts": "", + "Show Shortcuts": "Kısayolları Göster", "Show your support!": "Desteğinizi gösterin!", "Showcased creativity": "Sergilenen yaratıcılık", - "Showing all messages (user + assistant) per user.": "", + "Showing all messages (user + assistant) per user.": "Kullanıcı başına tüm mesajları (kullanıcı + asistan) gösteriliyor.", "Sign in": "Oturum aç", "Sign in to {{WEBUI_NAME}}": "{{WEBUI_NAME}}'e giriş yap", "Sign in to {{WEBUI_NAME}} with LDAP": "LDAP ile {{WEBUI_NAME}}'e giriş yap", "Sign Out": "Çıkış Yap", "Sign up": "Kaydol", "Sign up to {{WEBUI_NAME}}": "{{WEBUI_NAME}}'e kaydol", - "Significantly improves accuracy by using an LLM to enhance tables, forms, inline math, and layout detection. Will increase latency. Defaults to False.": "", + "Significantly improves accuracy by using an LLM to enhance tables, forms, inline math, and layout detection. Will increase latency. Defaults to False.": "LLM kullanarak tabloları, formları, satır içi matematiği ve düzen algılamasını iyileştirerek doğruluğu önemli ölçüde artırır. Gecikmeyi artırır. Varsayılan olarak False.", "Signing in to {{WEBUI_NAME}}": "{{WEBUI_NAME}}'e giriş yapılıyor", - "Single": "", - "Sink List": "", + "Single": "Tekil", + "Sink List": "Listeyi Aşağı Taşı", "sk-1234": "sk-1234", "Skill created successfully": "Yetenek başarıyla oluşturuldu", "Skill deleted successfully": "Yetenek başarıyla silindi", @@ -1767,14 +1767,14 @@ "Skills Access": "Yeteneklere Erişim", "Skills Public Sharing": "Yeteneklerin Herkese Açık Paylaşımı", "Skills Sharing": "Yeteneklerin Paylaşımı", - "Skip Cache": "", - "Skip the cache and re-run the inference. Defaults to False.": "", - "Something went wrong :/": "", - "Sonar": "", - "Sonar Deep Research": "", - "Sonar Pro": "", - "Sonar Reasoning": "", - "Sonar Reasoning Pro": "", + "Skip Cache": "Önbelleği Atla", + "Skip the cache and re-run the inference. Defaults to False.": "Önbelleği atlayın ve çıkarımı yeniden çalıştırın. Varsayılan olarak False.", + "Something went wrong :/": "Bir şeyler yanlış gitti :/", + "Sonar": "Sonar", + "Sonar Deep Research": "Sonar Deep Research", + "Sonar Pro": "Sonar Pro", + "Sonar Reasoning": "Sonar Reasoning", + "Sonar Reasoning Pro": "Sonar Reasoning Pro", "Sort": "Sırala", "Sort by": "Şuna göre sırala", "Sougou Search API sID": "Sougou Search API sID'si", @@ -1782,52 +1782,52 @@ "Source": "Kaynak", "Speech Playback Speed": "Konuşma Oynatma Hızı", "Speech recognition error: {{error}}": "Konuşma tanıma hatası: {{error}}", - "Speech-to-Text": "", + "Speech-to-Text": "Konuşmadan Metne", "Speech-to-Text Engine": "Konuşmadan Metne Motoru", - "Speech-to-Text Language": "", - "Split documents by markdown headers before applying character/token splitting.": "", - "Start a new conversation": "", + "Speech-to-Text Language": "Konuşmadan Metne Dili", + "Split documents by markdown headers before applying character/token splitting.": "Karakter/token bölme işlemi uygulamadan önce belgeleri markdown başlıklarına göre bölün.", + "Start a new conversation": "Yeni bir konuşma başlat", "Start of the channel": "Kanalın başlangıcı", - "Start Tag": "", - "Starting kernel...": "", - "Status": "", - "Status cleared successfully": "", - "Status updated successfully": "", - "Status Updates": "", + "Start Tag": "Başlangıç Etiketi", + "Starting kernel...": "Kernel başlatılıyor...", + "Status": "Durum", + "Status cleared successfully": "Durum başarıyla temizlendi", + "Status updated successfully": "Durum başarıyla güncellendi", + "Status Updates": "Durum Güncellemeleri", "STDOUT/STDERR": "STDOUT/STDERR", - "Steps": "", + "Steps": "Adımlar", "Stop": "Durdur", - "Stop Download": "", - "Stop Generating": "", + "Stop Download": "İndirmeyi Durdur", + "Stop Generating": "Oluşturmayı Durdur", "Stop Sequence": "Diziyi Durdur", "Stream Chat Response": "Akış Sohbet Yanıtı", - "Stream Delta Chunk Size": "", - "Streamable HTTP": "", - "Strikethrough": "", - "Strip Existing OCR": "", - "Strip existing OCR text from the PDF and re-run OCR. Ignored if Force OCR is enabled. Defaults to False.": "", + "Stream Delta Chunk Size": "Akış Delta Parça Boyutu", + "Streamable HTTP": "Akışlanabilir HTTP", + "Strikethrough": "Üstü Çizili", + "Strip Existing OCR": "Mevcut OCR'ı Kaldır", + "Strip existing OCR text from the PDF and re-run OCR. Ignored if Force OCR is enabled. Defaults to False.": "PDF'den mevcut OCR metnini çıkarın ve OCR'ı yeniden çalıştırın. OCR Zorla etkinleştirilirse yok sayılır. Varsayılan olarak False.", "STT Model": "STT Modeli", "STT Settings": "STT Ayarları", "Stylized PDF Export": "Biçimlendirilmiş PDF Dışa Aktarımı", - "Submit question": "", - "Submit suggestion": "", - "Subtitle": "", + "Submit question": "Soru gönder", + "Submit suggestion": "Öneri gönder", + "Subtitle": "Altyazı", "Success": "Başarılı", - "Successfully imported {{userCount}} users.": "", + "Successfully imported {{userCount}} users.": "{{userCount}} kullanıcı başarıyla içe aktarıldı.", "Successfully updated.": "Başarıyla güncellendi.", - "Suggest a change": "", + "Suggest a change": "Bir değişiklik öner", "Suggested": "Önerilen", "Support": "Destek", "Support this plugin:": "Bu eklentiyi destekleyin:", - "Supported MIME Types": "", - "Sync": "", - "Sync Complete!": "", + "Supported MIME Types": "Desteklenen MIME Türleri", + "Sync": "Eşitle", + "Sync Complete!": "Eşitleme Tamamlandı!", "Sync directory": "Dizini senkronize et", - "Sync Failed": "", - "Sync Usage Stats": "", - "Syncing stats...": "", - "Syncing...": "", - "Syncs only chats with updates after your last sync timestamp. Disable to re-sync all chats.": "", + "Sync Failed": "Eşitleme Başarısız", + "Sync Usage Stats": "Kullanım İstatistiklerini Eşitle", + "Syncing stats...": "İstatistikler eşitleniyor...", + "Syncing...": "Eşitleniyor...", + "Syncs only chats with updates after your last sync timestamp. Disable to re-sync all chats.": "Sadece son eşitleme zaman damganızdan sonraki güncellemelere sahip sohbetleri eşitler. Tüm sohbetleri yeniden eşitlemek için devre dışı bırakın.", "System": "Sistem", "System Instructions": "Sistem Talimatları", "System Prompt": "Sistem Promptu", @@ -1877,7 +1877,7 @@ "There was an error syncing your stats. Please try again.": "", "Thinking...": "Düşünüyor...", "This action cannot be undone. Do you wish to continue?": "Bu eylem geri alınamaz. Devam etmek istiyor musunuz?", - "This channel was created on {{createdAt}}. This is the very beginning of the {{channelName}} channel.": "", + "This channel was created on {{createdAt}}. This is the very beginning of the {{channelName}} channel.": "Bu kanal {{createdAt}} tarihinde oluşturuldu. Bu, {{channelName}} kanalının en başıdır.", "This chat won't appear in history and your messages will not be saved.": "", "This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Bu, önemli konuşmalarınızın güvenli bir şekilde arkayüz veritabanınıza kaydedildiğini garantiler. Teşekkür ederiz!", "This feature is currently experimental and may not work as expected.": "", @@ -1912,7 +1912,7 @@ "Title Auto-Generation": "Otomatik Başlık Oluşturma", "Title cannot be an empty string.": "Başlık boş bir dize olamaz.", "Title Generation": "Başlık Oluşturma", - "Title Generation Prompt": "Başlık Oluşturma İstemi", + "Title Generation Prompt": "Başlık Oluşturma Prompt'u", "TLS": "TLS", "To access the available model names for downloading,": "İndirilebilir mevcut model adlarına erişmek için,", "To access the GGUF models available for downloading,": "İndirilebilir mevcut GGUF modellerine erişmek için,", @@ -1923,8 +1923,8 @@ "To select toolkits here, add them to the \"Tools\" workspace first.": "Araçları burada seçmek için öncelikle bunları \"Araçlar\" çalışma alanına ekleyin.", "Toast notifications for new updates": "", "Today": "Bugün", - "Today at {{LOCALIZED_TIME}}": "", - "Toggle {{COUNT}} sources": "", + "Today at {{LOCALIZED_TIME}}": "Bugün saat {{LOCALIZED_TIME}}", + "Toggle {{COUNT}} sources": "{{COUNT}} kaynağı aç/kapat", "Toggle 1 source": "", "Toggle Dictation": "", "Toggle Sidebar": "", @@ -1973,7 +1973,7 @@ "Underline": "", "Unknown": "Bilinmeyen", "Unknown User": "", - "Unloads {{FROM_NOW}}": "", + "Unloads {{FROM_NOW}}": "{{FROM_NOW}} sonra modeli bellekten boşaltır", "Unlock mysteries": "", "Unpin": "Sabitlemeyi Kaldır", "Unravel secrets": "", @@ -1996,14 +1996,14 @@ "Upload directory": "Dizini yükle", "Upload files": "Dosyaları yükle", "Upload Files": "Dosyaları Yükle", - "Upload Model": "", + "Upload Model": "Model Yükle", "Upload Pipeline": "Pipeline Yükle", - "Upload profile image": "", + "Upload profile image": "Profil resmi yükle", "Upload Progress": "Yükleme İlerlemesi", - "Upload Progress: {{uploadedFiles}}/{{totalFiles}} ({{percentage}}%)": "", - "Uploaded files or images": "", - "Uploading file...": "", - "Uploading...": "", + "Upload Progress: {{uploadedFiles}}/{{totalFiles}} ({{percentage}}%)": "Yükleme İlerlemesi: {{uploadedFiles}}/{{totalFiles}} ({{percentage}}%)", + "Uploaded files or images": "Yüklenen dosyalar veya görüntüler", + "Uploading file...": "Dosya yükleniyor...", + "Uploading...": "Yükleniyor...", "URL": "URL", "URL is required": "URL gerekli", "URL Mode": "URL Modu", @@ -2035,9 +2035,9 @@ "Using the default arena model with all models. Click the plus button to add custom models.": "Tüm modellerle varsayılan arena modelini kullanıyor. Özel modeller eklemek için artı düğmesine tıklayın.", "Valid time units:": "Geçerli zaman birimleri:", "Validate certificate": "", - "Valves": "Valvler", - "Valves updated": "Valvler güncellendi", - "Valves updated successfully": "Valvler başarıyla güncellendi", + "Valves": "Valfler", + "Valves updated": "Valfler güncellendi", + "Valves updated successfully": "Valfler başarıyla güncellendi", "variable": "değişken", "Verify Connection": "Bağlantıyı Doğrula", "Verify SSL Certificate": "SSL Sertifikasını Doğrula", @@ -2045,11 +2045,11 @@ "Version {{selectedVersion}} of {{totalVersions}}": "Sürüm {{selectedVersion}} / {{totalVersions}}", "Version deleted": "", "View Replies": "Yanıtları Görüntüle", - "View Result from **{{NAME}}**": "", - "View source: {{name}}": "", - "View source: {{title}}": "", + "View Result from **{{NAME}}**": "**{{NAME}}** sonucunu görüntüle", + "View source: {{name}}": "Kaynağı görüntüle: {{name}}", + "View source: {{title}}": "Kaynağı görüntüle: {{title}}", "Visibility": "Görünürlük", - "Visible": "", + "Visible": "Görünür", "Visible to all users": "", "Vision": "", "Voice": "Ses", @@ -2098,10 +2098,10 @@ "Workspace": "Çalışma Alanı", "Workspace Permissions": "Çalışma Alanı İzinleri", "Write": "Yaz", - "Write a summary in 50 words that summarizes {{topic}}.": "[Konuyu veya anahtar kelimeyi] özetleyen 50 kelimelik bir özet yazın.", + "Write a summary in 50 words that summarizes {{topic}}.": "{{topic}} konusunu özetleyen 50 kelimelik bir özet yazın.", "Write something...": "Bir şeyler yazın...", - "Write your model system prompt content here\ne.g.) You are Mario from Super Mario Bros, acting as an assistant.": "Modelinizin sistem istemi (system prompt) içeriğini buraya yazın\nörn.: Super Mario Bros’tan Mario’sunuz ve bir asistan olarak hareket ediyorsunuz.", - "Yacy Instance URL": "", + "Write your model system prompt content here\ne.g.) You are Mario from Super Mario Bros, acting as an assistant.": "Modelinizin sistem promptu içeriğini buraya yazın\nörn.: Super Mario Bros’tan Mario’sunuz ve bir asistan olarak hareket ediyorsunuz.", + "Yacy Instance URL": "Yacy Instance URL", "Yacy Password": "Yacy Parolası", "Yacy Username": "Yacy Kullanıcı Adı", "Yahoo": "Yahoo", @@ -2110,35 +2110,35 @@ "Yandex Web Search config": "Yandex Web Arama Yapılandırması", "Yandex Web Search URL": "Yandex Web Arama URL'si", "Yesterday": "Dün", - "Yesterday at {{LOCALIZED_TIME}}": "", + "Yesterday at {{LOCALIZED_TIME}}": "Dün saat {{LOCALIZED_TIME}}", "You": "Sen", - "You are currently using a trial license. Please contact support to upgrade your license.": "", + "You are currently using a trial license. Please contact support to upgrade your license.": "Şu anda deneme lisansı kullanıyorsunuz. Lisansınızı yükseltmek için lütfen destek ile iletişime geçin.", "You can only chat with a maximum of {{maxCount}} file(s) at a time.": "Aynı anda en fazla {{maxCount}} dosya ile sohbet edebilirsiniz.", "You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "Aşağıdaki 'Yönet' düğmesi aracılığıyla bellekler ekleyerek LLM'lerle etkileşimlerinizi kişiselleştirebilir, onları daha yararlı ve size özel hale getirebilirsiniz.", "You cannot upload an empty file.": "Boş bir dosya yükleyemezsiniz.", - "You do not have permission to edit this model": "", - "You do not have permission to edit this prompt.": "", + "You do not have permission to edit this model": "Bu modeli düzenleme izniniz yok.", + "You do not have permission to edit this prompt.": "Bu promptu düzenleme izniniz yok.", "You do not have permission to edit this skill.": "Bu yeteneği düzenleme izniniz yok.", - "You do not have permission to edit this tool": "", - "You do not have permission to make this public": "", - "You do not have permission to send messages in this channel.": "", - "You do not have permission to send messages in this thread.": "", - "You do not have permission to upload files to this knowledge base.": "", + "You do not have permission to edit this tool": "Bu aracı düzenleme izniniz yok.", + "You do not have permission to make this public": "Bunu herkese açma izniniz yok.", + "You do not have permission to send messages in this channel.": "Bu kanalda mesaj gönderme izniniz yok.", + "You do not have permission to send messages in this thread.": "Bu konuda mesaj gönderme izniniz yok.", + "You do not have permission to upload files to this knowledge base.": "Bu bilgi tabanına dosya yükleme izniniz yok.", "You do not have permission to upload files.": "Dosya yüklemek için izniniz yok.", - "You do not have permission to upload web content.": "", + "You do not have permission to upload web content.": "Web içeriği yükleme izniniz yok.", "You have no archived conversations.": "Arşivlenmiş sohbetleriniz yok.", - "You have no shared conversations.": "", + "You have no shared conversations.": "Paylaştığınız sohbet yok.", "You have shared this chat": "Bu sohbeti paylaştınız", - "You.com API Key": "", + "You.com API Key": "You.com API Anahtarı", "You're a helpful assistant.": "Sen yardımsever bir asistansın.", "You're now logged in.": "Şimdi giriş yaptınız.", "Your Account": "Hesabınız", "Your account status is currently pending activation.": "Hesap durumunuz şu anda etkinleştirilmeyi bekliyor.", - "Your browser does not support the audio tag.": "", - "Your browser does not support the video tag.": "", + "Your browser does not support the audio tag.": "Tarayıcınız ses etiketini desteklemiyor.", + "Your browser does not support the video tag.": "Tarayıcınız video etiketini desteklemiyor.", "Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Tüm katkınız doğrudan eklenti geliştiricisine gidecektir; Open WebUI herhangi bir yüzde almaz. Ancak seçilen finansman platformunun kendi ücretleri olabilir.", - "Your message text or inputs": "", - "Your usage stats have been successfully synced.": "", + "Your message text or inputs": "Mesaj metniniz veya girdileriniz", + "Your usage stats have been successfully synced.": "Kullanım istatistikleriniz başarıyla eşitlendi.", "YouTube": "Youtube", "Youtube Language": "Youtube Dili", "Youtube Proxy URL": "Youtube Vekil URL'si" From 3a6b5ebb5f3920309aa0edbdeca8765c05855efc Mon Sep 17 00:00:00 2001 From: Shamil Date: Wed, 11 Mar 2026 23:28:39 +0300 Subject: [PATCH 0877/1854] refac: modernize type hints and imports in access_control module (#22594) --- .../utils/access_control/__init__.py | 59 +++++++++---------- .../open_webui/utils/access_control/files.py | 7 ++- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/backend/open_webui/utils/access_control/__init__.py b/backend/open_webui/utils/access_control/__init__.py index a228bbd6a8..b2fb9ece17 100644 --- a/backend/open_webui/utils/access_control/__init__.py +++ b/backend/open_webui/utils/access_control/__init__.py @@ -1,15 +1,21 @@ -from typing import Optional, Set, Union, List, Dict, Any -from open_webui.models.users import Users, UserModel -from open_webui.models.groups import Groups - - -from open_webui.config import DEFAULT_USER_PERMISSIONS import json +from typing import Any + +from open_webui.models.users import UserModel +from open_webui.models.groups import Groups +from open_webui.models.access_grants import ( + has_public_read_access_grant, + has_user_access_grant, + strip_user_access_grants, +) +from open_webui.config import DEFAULT_USER_PERMISSIONS + +from sqlalchemy.orm import Session def fill_missing_permissions( - permissions: Dict[str, Any], default_permissions: Dict[str, Any] -) -> Dict[str, Any]: + permissions: dict[str, Any], default_permissions: dict[str, Any] +) -> dict[str, Any]: """ Recursively fills in missing properties in the permissions dictionary using the default permissions as a template. @@ -27,9 +33,9 @@ def fill_missing_permissions( def get_permissions( user_id: str, - default_permissions: Dict[str, Any], - db: Optional[Any] = None, -) -> Dict[str, Any]: + default_permissions: dict[str, Any], + db: Session | None = None, +) -> dict[str, Any]: """ Get all permissions for a user by combining the permissions of all groups the user is a member of. If a permission is defined in multiple groups, the most permissive value is used (True > False). @@ -37,8 +43,8 @@ def get_permissions( """ def combine_permissions( - permissions: Dict[str, Any], group_permissions: Dict[str, Any] - ) -> Dict[str, Any]: + permissions: dict[str, Any], group_permissions: dict[str, Any] + ) -> dict[str, Any]: """Combine permissions from multiple groups by taking the most permissive value.""" for key, value in group_permissions.items(): if isinstance(value, dict): @@ -72,8 +78,8 @@ def get_permissions( def has_permission( user_id: str, permission_key: str, - default_permissions: Dict[str, Any] = {}, - db: Optional[Any] = None, + default_permissions: dict[str, Any] = {}, + db: Session | None = None, ) -> bool: """ Check if a user has a specific permission by checking the group permissions @@ -82,7 +88,7 @@ def has_permission( Permission keys can be hierarchical and separated by dots ('.'). """ - def get_permission(permissions: Dict[str, Any], keys: List[str]) -> bool: + def get_permission(permissions: dict[str, Any], keys: list[str]) -> bool: """Traverse permissions dict using a list of keys (from dot-split permission_key).""" for key in keys: if key not in permissions: @@ -110,9 +116,9 @@ def has_permission( def has_access( user_id: str, permission: str = "read", - access_grants: Optional[list] = None, - user_group_ids: Optional[Set[str]] = None, - db: Optional[Any] = None, + access_grants: list | None = None, + user_group_ids: set[str] | None = None, + db: Session | None = None, ) -> bool: """ Check if a user has the specified permission using an in-memory access_grants list. @@ -156,7 +162,7 @@ def has_access( def has_connection_access( user: UserModel, connection: dict, - user_group_ids: Optional[Set[str]] = None, + user_group_ids: set[str] | None = None, ) -> bool: """ Check if a user can access a server connection (tool server, terminal, etc.) @@ -194,7 +200,7 @@ def migrate_access_control( if access_control is None and ac_key not in data: return - grants: List[Dict[str, str]] = [] + grants: list[dict[str, str]] = [] if access_control and isinstance(access_control, dict): for perm in ["read", "write"]: perm_data = access_control.get(perm, {}) @@ -221,20 +227,13 @@ def migrate_access_control( data.pop(ac_key, None) -from open_webui.models.access_grants import ( - has_public_read_access_grant, - has_user_access_grant, - strip_user_access_grants, -) - - def filter_allowed_access_grants( - default_permissions: Dict[str, Any], + default_permissions: dict[str, Any], user_id: str, user_role: str, access_grants: list, public_permission_key: str, - db: Optional[Any] = None, + db: Session | None = None, ) -> list: """ Checks if the user has the required permissions to grant access to a resource. diff --git a/backend/open_webui/utils/access_control/files.py b/backend/open_webui/utils/access_control/files.py index e3d52b0f55..c69f3dfa9d 100644 --- a/backend/open_webui/utils/access_control/files.py +++ b/backend/open_webui/utils/access_control/files.py @@ -1,5 +1,4 @@ import logging -from typing import Optional, Any from open_webui.models.users import UserModel from open_webui.models.files import Files @@ -10,14 +9,16 @@ from open_webui.models.groups import Groups from open_webui.models.models import Models from open_webui.models.access_grants import AccessGrants +from sqlalchemy.orm import Session + log = logging.getLogger(__name__) def has_access_to_file( - file_id: Optional[str], + file_id: str | None, access_type: str, user: UserModel, - db: Optional[Any] = None, + db: Session | None = None, ) -> bool: """ Check if a user has the specified access to a file through any of: From 865880a0b172a44c160f40772f0665bd4d0ea219 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Wed, 11 Mar 2026 15:30:57 -0500 Subject: [PATCH 0878/1854] refac: allow emoji unselect from folder --- .../components/chat/Placeholder/FolderTitle.svelte | 5 +++-- src/lib/components/common/EmojiPicker.svelte | 11 +++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/lib/components/chat/Placeholder/FolderTitle.svelte b/src/lib/components/chat/Placeholder/FolderTitle.svelte index 24e2895219..d2546f595a 100644 --- a/src/lib/components/chat/Placeholder/FolderTitle.svelte +++ b/src/lib/components/chat/Placeholder/FolderTitle.svelte @@ -76,7 +76,7 @@ const updateIconHandler = async (iconName) => { const res = await updateFolderById(localStorage.token, folder.id, { meta: { - icon: iconName + icon: iconName ?? '' } }).catch((error) => { toast.error(`${error}`); @@ -84,7 +84,7 @@ }); if (res) { - folder.meta = { ...folder.meta, icon: iconName }; + folder.meta = { ...folder.meta, icon: iconName ?? '' }; toast.success($i18n.t('Folder updated successfully')); @@ -167,6 +167,7 @@
{}} + selected={folder?.meta?.icon ?? null} onSubmit={(name) => { console.log(name); updateIconHandler(name); diff --git a/src/lib/components/common/EmojiPicker.svelte b/src/lib/components/common/EmojiPicker.svelte index 624bb7be1b..84233845cf 100644 --- a/src/lib/components/common/EmojiPicker.svelte +++ b/src/lib/components/common/EmojiPicker.svelte @@ -19,6 +19,7 @@ export let side = 'top'; export let align = 'start'; export let user = null; + export let selected = null; let show = false; let emojis = emojiShortCodes; @@ -97,7 +98,11 @@ // Handle emoji selection function selectEmoji(emoji) { const selectedCode = emoji.shortCodes[0]; - onSubmit(selectedCode); + if (selected === selectedCode) { + onSubmit(null); + } else { + onSubmit(selectedCode); + } show = false; } @@ -131,6 +136,8 @@ bind:value={search} />
+ +
{#if emojiRows.length === 0} @@ -155,7 +162,7 @@ placement="top" >
diff --git a/src/lib/components/workspace/common/MemberSelector.svelte b/src/lib/components/workspace/common/MemberSelector.svelte index 2ec541352d..f4acad13f7 100644 --- a/src/lib/components/workspace/common/MemberSelector.svelte +++ b/src/lib/components/workspace/common/MemberSelector.svelte @@ -21,6 +21,7 @@ export let includeGroups = true; export let includeUsers = true; export let pagination = false; + export let includeSessionUser = false; export let groupIds = []; export let userIds = []; @@ -245,7 +246,7 @@
{#each users as user, userIdx (user.id)} - {#if user?.id !== $_user?.id} + {#if includeSessionUser || user?.id !== $_user?.id} {/if} @@ -667,7 +668,7 @@ on:click={() => filePreviewRef?.resetPdfView()} aria-label={$i18n.t('Reset view')} > - + {/if} diff --git a/src/lib/components/icons/ZoomReset.svelte b/src/lib/components/icons/ZoomReset.svelte new file mode 100644 index 0000000000..3b132ee05e --- /dev/null +++ b/src/lib/components/icons/ZoomReset.svelte @@ -0,0 +1,22 @@ + + + From ee0d9b791523399951b22b7765c19e5034fb36a2 Mon Sep 17 00:00:00 2001 From: Athanasios Oikonomou Date: Thu, 12 Mar 2026 23:58:02 +0200 Subject: [PATCH 0886/1854] feat: knowledge - clickable file icon opens content (#22629) Replaces the static document icon with an interactive button that opens the file content in a new tab via the files API endpoint. --- .../Knowledge/KnowledgeBase/Files.svelte | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/lib/components/workspace/Knowledge/KnowledgeBase/Files.svelte b/src/lib/components/workspace/Knowledge/KnowledgeBase/Files.svelte index 9d42130234..56646f57d4 100644 --- a/src/lib/components/workspace/Knowledge/KnowledgeBase/Files.svelte +++ b/src/lib/components/workspace/Knowledge/KnowledgeBase/Files.svelte @@ -11,6 +11,8 @@ import { capitalizeFirstLetter, formatFileSize } from '$lib/utils'; + import { WEBUI_BASE_URL } from '$lib/constants'; + import Tooltip from '$lib/components/common/Tooltip.svelte'; import DocumentPage from '$lib/components/icons/DocumentPage.svelte'; import XMark from '$lib/components/icons/XMark.svelte'; @@ -31,6 +33,25 @@ ? '' : 'hover:bg-gray-100 dark:hover:bg-gray-850'}" > +
+ {#if file?.status !== 'uploading'} + + + + {:else} + + {/if} +
+