Quellcode durchsuchen

feat: added Ukrainian language support (#2473)

Koen Farell vor 1 Jahr
Ursprung
Commit
61e4bbabaf

Datei-Diff unterdrückt, da er zu groß ist
+ 141 - 4
api/constants/languages.py


+ 44 - 0
web/i18n/i18next-config.ts

@@ -3,64 +3,84 @@ import i18n from 'i18next'
 import { initReactI18next } from 'react-i18next'
 import commonEn from './lang/common.en'
 import commonZh from './lang/common.zh'
+import commonUk from './lang/common.uk' // Ukrainian import
 import commonPt from './lang/common.pt' // Portuguese import
 import loginEn from './lang/login.en'
 import loginZh from './lang/login.zh'
 import loginPt from './lang/login.pt' // Portuguese import
+import loginUk from './lang/login.uk' // Ukrainian import
 import registerEn from './lang/register.en'
 import registerZh from './lang/register.zh'
 import registerPt from './lang/register.pt' // Portuguese import
+import registerUk from './lang/register.uk' // Ukrainian import
 import layoutEn from './lang/layout.en'
 import layoutZh from './lang/layout.zh'
 import layoutPt from './lang/layout.pt' // Portuguese import
+import layoutUk from './lang/layout.uk' // Ukrainian import
 import appEn from './lang/app.en'
 import appZh from './lang/app.zh'
 import appPt from './lang/app.pt' // Portuguese import
+import appUk from './lang/app.uk' // Ukrainian import
 import appOverviewEn from './lang/app-overview.en'
 import appOverviewZh from './lang/app-overview.zh'
 import appOverviewPt from './lang/app-overview.pt' // Portuguese import
+import appOverviewUk from './lang/app-overview.uk' // Ukrainian import
 import appDebugEn from './lang/app-debug.en'
 import appDebugZh from './lang/app-debug.zh'
 import appDebugPt from './lang/app-debug.pt' // Portuguese import
+import appDebugUk from './lang/app-debug.uk' // Ukrainian import
 import appApiEn from './lang/app-api.en'
 import appApiZh from './lang/app-api.zh'
 import appApiPt from './lang/app-api.pt' // Portuguese import
+import appApiUk from './lang/app-api.uk' // Ukrainian import
 import appLogEn from './lang/app-log.en'
 import appLogZh from './lang/app-log.zh'
 import appLogPt from './lang/app-log.pt' // Portuguese import
+import appLogUk from './lang/app-log.uk' // Ukrainian import
 import appAnnotationEn from './lang/app-annotation.en'
 import appAnnotationZh from './lang/app-annotation.zh'
 import appAnnotationPt from './lang/app-annotation.pt' // Portuguese import
+import appAnnotationUk from './lang/app-annotation.uk' // Ukrainian import
 import shareEn from './lang/share-app.en'
 import shareZh from './lang/share-app.zh'
 import sharePt from './lang/share-app.pt' // Portuguese import
+import shareUk from './lang/share-app.uk' // Ukrainian import
 import datasetEn from './lang/dataset.en'
 import datasetZh from './lang/dataset.zh'
 import datasetPt from './lang/dataset.pt' // Portuguese import
+import datasetUk from './lang/dataset.uk' // Ukrainian import
 import datasetDocumentsEn from './lang/dataset-documents.en'
 import datasetDocumentsZh from './lang/dataset-documents.zh'
 import datasetDocumentsPt from './lang/dataset-documents.pt' // Portuguese import
+import datasetDocumentsUk from './lang/dataset-documents.uk' // Ukrainian import
 import datasetHitTestingEn from './lang/dataset-hit-testing.en'
 import datasetHitTestingZh from './lang/dataset-hit-testing.zh'
 import datasetHitTestingPt from './lang/dataset-hit-testing.pt' // Portuguese import
+import datasetHitTestingUk from './lang/dataset-hit-testing.uk' // Ukrainian import
 import datasetSettingsEn from './lang/dataset-settings.en'
 import datasetSettingsZh from './lang/dataset-settings.zh'
 import datasetSettingsPt from './lang/dataset-settings.pt' // Portuguese import
+import datasetSettingsUk from './lang/dataset-settings.uk' // Ukrainian import
 import datasetCreationEn from './lang/dataset-creation.en'
 import datasetCreationZh from './lang/dataset-creation.zh'
 import datasetCreationPt from './lang/dataset-creation.pt' // Portuguese import
+import datasetCreationUk from './lang/dataset-creation.uk' // Ukrainian import
 import exploreEn from './lang/explore.en'
 import exploreZh from './lang/explore.zh'
 import explorePt from './lang/explore.pt' // Portuguese import
+import exploreUk from './lang/explore.uk' // Ukrainian import
 import billingEn from './lang/billing.en'
 import billingZh from './lang/billing.zh'
 import billingPt from './lang/billing.pt' // Portuguese import
+import billingUk from './lang/billing.uk' // Ukrainian import
 import customEn from './lang/custom.en'
 import customZh from './lang/custom.zh'
 import customPt from './lang/custom.pt' // Portuguese import
+import customUk from './lang/custom.uk' // Ukrainian import
 import toolsEn from './lang/tools.en'
 import toolsZh from './lang/tools.zh'
 import toolsPt from './lang/tools.pt' // Portuguese import
+import toolsUk from './lang/tools.uk' // Ukrainian import
 
 const resources = {
   'en-US': {
@@ -144,6 +164,30 @@ const resources = {
       tools: toolsPt,
     },
   },
+  'uk-UA': {
+    translation: {
+      common: commonUk,
+      layout: layoutUk,
+      login: loginUk,
+      register: registerUk,
+      app: appUk,
+      appOverview: appOverviewUk,
+      appDebug: appDebugUk,
+      appApi: appApiUk,
+      appLog: appLogUk,
+      appAnnotation: appAnnotationUk,
+      share: shareUk,
+      dataset: datasetUk,
+      datasetDocuments: datasetDocumentsUk,
+      datasetHitTesting: datasetHitTestingUk,
+      datasetSettings: datasetSettingsUk,
+      datasetCreation: datasetCreationUk,
+      explore: exploreUk,
+      billing: billingUk,
+      custom: customUk,
+      tools: toolsUk,
+    },
+  },
 }
 
 i18n.use(initReactI18next)

+ 87 - 0
web/i18n/lang/app-annotation.uk.ts

@@ -0,0 +1,87 @@
+const translation = {
+  title: 'Анотації',
+  name: 'Відповідь на анотацію',
+  editBy: 'Відповідь відредагована {{author}}',
+  noData: {
+    title: 'Немає анотацій',
+    description: 'Ви можете редагувати анотації під час налагодження програми або імпортувати анотації гуртом тут для отримання високоякісної відповіді.',
+  },
+  table: {
+    header: {
+      question: 'запитання',
+      answer: 'відповідь',
+      createdAt: 'створено у',
+      hits: 'переглядів',
+      actions: 'дії',
+      addAnnotation: 'Додати анотацію',
+      bulkImport: 'Масовий імпорт',
+      bulkExport: 'Масовий експорт',
+      clearAll: 'Очистити всі анотації',
+    },
+  },
+  editModal: {
+    title: 'Редагувати відповідь на анотацію',
+    queryName: 'Запит користувача',
+    answerName: 'Бот-оповідач',
+    yourAnswer: 'Ваша відповідь',
+    answerPlaceholder: 'Введіть свою відповідь тут',
+    yourQuery: 'Ваш запит',
+    queryPlaceholder: 'Введіть свій запит тут',
+    removeThisCache: 'Видалити цю анотацію',
+    createdAt: 'Створено у',
+  },
+  addModal: {
+    title: 'Додати відповідь на анотацію',
+    queryName: 'Запитання',
+    answerName: 'Відповідь',
+    answerPlaceholder: 'Введіть відповідь тут',
+    queryPlaceholder: 'Введіть запит тут',
+    createNext: 'Додати ще одну анотовану відповідь',
+  },
+  batchModal: {
+    title: 'Масовий імпорт',
+    csvUploadTitle: 'Перетягніть файл CSV сюди або',
+    browse: 'огляд',
+    tip: 'Файл CSV повинен відповідати такій структурі:',
+    question: 'запитання',
+    answer: 'відповідь',
+    contentTitle: 'вміст частини',
+    content: 'вміст',
+    template: 'Завантажте шаблон тут',
+    cancel: 'Скасувати',
+    run: 'Запустити партію',
+    runError: 'Не вдалося запустити партію',
+    processing: 'У пакетній обробці',
+    completed: 'Імпорт завершено',
+    error: 'Помилка імпорту',
+    ok: 'ОК',
+  },
+  errorMessage: {
+    answerRequired: 'Відповідь обов’язкова',
+    queryRequired: 'Запитання обов’язкове',
+  },
+  viewModal: {
+    annotatedResponse: 'Відповідь на анотацію',
+    hitHistory: 'Історія переглядів',
+    hit: 'Перегляд',
+    hits: 'Переглядів',
+    noHitHistory: 'Історії переглядів немає',
+  },
+  hitHistoryTable: {
+    query: 'Запит',
+    match: 'Збіг',
+    response: 'Відповідь',
+    source: 'Джерело',
+    score: 'Бал',
+    time: 'Час',
+  },
+  initSetup: {
+    title: 'Початкова настройка відповіді на анотацію',
+    configTitle: 'Налаштування відповіді на анотацію',
+    confirmBtn: 'Зберегти та ввімкнути',
+    configConfirmBtn: 'Зберегти',
+  },
+  embeddingModelSwitchTip: 'Модель векторизації тексту анотації, перемикання моделей буде повторно вбудовано, що призведе до додаткових витрат.',
+}
+
+export default translation

+ 66 - 0
web/i18n/lang/app-api.uk.ts

@@ -0,0 +1,66 @@
+const translation = {
+  apiServer: 'API сервер',
+  apiKey: 'Ключ API',
+  status: 'Статус',
+  disabled: 'Вимкнено',
+  ok: 'Працює',
+  copy: 'Копіювати',
+  copied: 'Скопійовано',
+  play: 'Відтворити',
+  pause: 'Пауза',
+  playing: 'Відтворення',
+  merMaind: {
+    rerender: 'Повторити рендер',
+  },
+  never: 'Ніколи',
+  apiKeyModal: {
+    apiSecretKey: 'Секретний ключ API',
+    apiSecretKeyTips: 'Щоб запобігти зловживанням API, захистіть свій ключ API. Уникайте його використання як звичайного тексту у  front-end коді. :)',
+    createNewSecretKey: 'Створити новий секретний ключ',
+    secretKey: 'Секретний ключ',
+    created: 'СТВОРЕНО',
+    lastUsed: 'ОСТАННЄ ВИКОРИСТАННЯ',
+    generateTips: 'Зберігайте цей ключ у безпечному та доступному місці.',
+  },
+  actionMsg: {
+    deleteConfirmTitle: 'Видалити цей секретний ключ?',
+    deleteConfirmTips: 'Цю дію не можна скасувати.',
+    ok: 'Гаразд',
+  },
+  chatMode: {
+    title: 'API чат-додатку',
+    info: 'Для універсальних чат-ботів, що використовують формат запитання-відповіді, викличте API chat-messages, щоб розпочати діалог. Підтримуйте безперервні розмови, передаючи conversation_id, що повертається. Параметри відповідей і шаблони залежать від налаштувань Dify Prompt.',
+    createChatApi: 'Створити повідомлення чату',
+    createChatApiTip: 'Створіть нове повідомлення розмови або продовжте існуючий діалог.',
+    inputsTips: '(Необов’язково) Надайте поля введення користувача як пари ключ-значення, які відповідають змінним у Prompt. Ключ – це ім’я змінної, Значення – це значення параметра. Якщо тип поля Select, надіслане значення має бути одним із встановлених параметрів.',
+    queryTips: 'Вміст введення/запитання користувача',
+    blocking: 'Тип блокування, очікування завершення виконання та повернення результатів. (Запити можуть бути перервані, якщо процес тривалий)',
+    streaming: 'повернення потокового передавання. Реалізація повернення потокового передавання на основі SSE (Server-Sent Events).',
+    conversationIdTip: '(Опціонально) Ідентифікатор розмови: залиште порожнім для першої розмови; передайте conversation_id з контексту, щоб продовжити діалог.',
+    messageFeedbackApi: 'Фідбек із повідомленнями сеансу користувача, наприклад',
+    messageFeedbackApiTip: 'Оцінюйте отримані повідомлення від імені кінцевих користувачів за допомогою лайків або дизлайків. Ці дані відображаються на сторінці "Журнали та анотації" та використовуються для майбутнього точного налаштування моделі.',
+    messageIDTip: 'Ідентифікатор повідомлення',
+    ratingTip: 'подобається чи не подобається, null — скасувати',
+    chatMsgHistoryApi: 'Отримати повідомлення з історії чату',
+    chatMsgHistoryApiTip: 'Перша сторінка повертає останній `обмежений` рядок, який знаходиться у зворотному порядку',
+    chatMsgHistoryConversationIdTip: 'Ідентифікатор розмови',
+    chatMsgHistoryFirstId: 'Ідентифікатор першого запису чату на поточній сторінці. Типовим є відсутність.',
+    chatMsgHistoryLimit: 'Скільки чатів повертається в одному запиті',
+    conversationsListApi: 'Отримати список розмов',
+    conversationsListApiTip: 'Отримує список сеансів поточного користувача. За замовчуванням повертаються останні 20 сеансів.',
+    conversationsListFirstIdTip: 'Ідентифікатор останнього запису на поточній сторінці, значення за замовчуванням відсутнє.',
+    conversationsListLimitTip: 'Скільки чатів повертається в одному запиті',
+    conversationRenamingApi: 'Перейменування розмови',
+    conversationRenamingApiTip: 'Перейменуйте розмови; ім’я відображається в інтерфейсах клієнтів із кількома сеансами.',
+    conversationRenamingNameTip: 'Нове ім’я',
+    parametersApi: 'Отримання інформації про параметри програми',
+    parametersApiTip: 'Отримати налаштовані вхідні параметри, включаючи імена змінних, імена полів, типи та значення за замовчуванням. Зазвичай використовується для відображення цих полів у формі або заповнення значень за замовчуванням після завантаження клієнта.',
+  },
+  develop: {
+    requestBody: 'Тіло запиту',
+    pathParams: 'Параметри шляху',
+    query: 'Запит',
+  },
+}
+
+export default translation

Datei-Diff unterdrückt, da er zu groß ist
+ 400 - 0
web/i18n/lang/app-debug.uk.ts


Datei-Diff unterdrückt, da er zu groß ist
+ 69 - 0
web/i18n/lang/app-log.uk.ts


+ 139 - 0
web/i18n/lang/app-overview.uk.ts

@@ -0,0 +1,139 @@
+const translation = {
+  welcome: {
+    firstStepTip: 'Щоб розпочати,',
+    enterKeyTip: 'введіть свій ключ API OpenAI нижче',
+    getKeyTip: 'Отримайте свій ключ API з панелі керування OpenAI',
+    placeholder: 'Ваш ключ API OpenAI (наприклад, sk-xxxx)',
+  },
+  apiKeyInfo: {
+    cloud: {
+      trial: {
+        title: 'Ви використовуєте пробну квоту {{providerName}}.', // You are using...
+        description: 'Пробна квота надається для використання під час тестування. Перш ніж вичерпається пробна квота, будь ласка, налаштуйте свого постачальника моделі або придбайте додаткову квоту.',
+      },
+      exhausted: {
+        title: 'Ваша пробна квота використана, будь ласка, налаштуйте свій APIKey.',
+        description: 'Ваша пробна квота вичерпана. Будь ласка, налаштуйте свого постачальника моделі або придбайте додаткову квоту.',
+      },
+    },
+    selfHost: {
+      title: {
+        row1: 'Щоб розпочати,',
+        row2: 'спочатку налаштуйте свого постачальника моделі.',
+      },
+    },
+    callTimes: 'Кількість викликів', // Call times
+    usedToken: 'Використано токенів', // Used token
+    setAPIBtn: 'Перейти до налаштування постачальника моделі', // Go to setup model provider
+    tryCloud: 'Або спробуйте хмарну версію Dify з безкоштовною квотою', // Or try the cloud version ...
+  },
+  overview: {
+    title: 'Огляд', // Overview
+    appInfo: {
+      explanation: 'Готовий до використання AI WebApp',
+      accessibleAddress: 'Публічна URL-адреса', // Public URL
+      preview: 'Попередній перегляд', // Preview
+      regenerate: 'Регенерувати', // Regenerate
+      preUseReminder: 'Будь ласка, увімкніть WebApp, перш ніж продовжувати.', // Please enable WebApp...
+      settings: {
+        entry: 'Налаштування', // Settings
+        title: 'Налаштування веб-програми', // WebApp Settings
+        webName: 'Ім’я веб-програми', // WebApp Name
+        webDesc: 'Опис веб-програми', // WebApp Description
+        webDescTip: 'Цей текст відображатиметься на стороні клієнта, надаючи базові вказівки щодо використання програми',
+        webDescPlaceholder: 'Введіть опис WebApp',
+        language: 'Мова', // Language
+        more: {
+          entry: 'Показати більше налаштувань', // Show more settings
+          copyright: 'Авторські права', // Copyright
+          copyRightPlaceholder: 'Введіть ім’я автора або організації',
+          privacyPolicy: 'Політика конфіденційності', // Privacy Policy
+          privacyPolicyPlaceholder: 'Введіть посилання на політику конфіденційності',
+          privacyPolicyTip: 'Допомагає відвідувачам зрозуміти, які дані збирає програма. Дивіться <privacyPolicyLink>Політику конфіденційності</privacyPolicyLink> Dify.',
+        },
+      },
+      embedded: {
+        entry: 'Вбудований', // Embedded
+        title: 'Вбудувати на веб-сайт', // Embed on website
+        explanation: 'Виберіть спосіб вбудувати чат-програму на свій веб-сайт',
+        iframe: 'Щоб додати чат-програму будь-де на своєму веб-сайті, додайте цей iframe у свій код html.',
+        scripts: 'Щоб додати програму чату у правий нижній кут свого веб-сайту, додайте цей код до свого html.',
+        chromePlugin: 'Встановити розширення Dify Chatbot для Chrome',
+        copied: 'Скопійовано', // Copied
+        copy: 'Копіювати', // Copy
+      },
+      qrcode: {
+        title: 'QR-код для спільного доступу',
+        scan: 'Відсканувати програму спільного доступу',
+        download: 'Завантажити QR-код',
+      },
+      customize: {
+        way: 'спосіб', // way
+        entry: 'Налаштувати', // Customize
+        title: 'Налаштувати веб-додаток AI',
+        explanation: 'Ви можете налаштувати зовнішній вигляд WebApp відповідно до вашого сценарію та стилю.',
+        way1: {
+          name: 'Розгалужити код клієнта, змінити його та розгорнути у Vercel (рекомендовано)',
+          step1: 'Розгалужити код клієнта та модифікувати його',
+          step1Tip: 'Натисніть тут, щоб розгалужити вихідний код у свій обліковий запис GitHub і змінити код',
+          step1Operation: 'Dify-WebClient',
+          step2: 'Розгорнути у Vercel',
+          step2Tip: 'Натисніть тут, щоб імпортувати репозиторій до Vercel та виконати розгортання',
+          step2Operation: 'Імпортувати репозиторій',
+          step3: 'Налаштувати змінні середовища',
+          step3Tip: 'Додайте такі змінні середовища у Vercel',
+        },
+        way2: {
+          name: 'Напишіть код на клієнтській стороні, щоб викликати API та розгорнути його на сервері',
+          operation: 'Документація',
+        },
+      },
+    },
+    apiInfo: {
+      title: 'API бекенд-сервісу', // Backend service API
+      explanation: 'Легко інтегрується в вашу програму',
+      accessibleAddress: 'Кінцевий ресурс сервісу API', // Service API Endpoint
+      doc: 'API довідка', // API Reference
+    },
+    status: {
+      running: 'Працює', // In service
+      disable: 'Вимкнути', // Disable
+    },
+  },
+  analysis: {
+    title: 'Аналіз', // Analysis
+    ms: 'мс', // ms
+    tokenPS: 'Токен/с', // Token/s
+    totalMessages: {
+      title: 'Загалом повідомлень', // Total Messages
+      explanation: 'Щоденна кількість взаємодій зі ШІ; виключено проектування запитань або налагодження.',
+    },
+    activeUsers: {
+      title: 'Активні користувачі', // Active Users
+      explanation: 'Унікальні користувачі, які беруть участь у запитах/відповідях зі ШІ; виключено інженерію запитань або налагодження.',
+    },
+    tokenUsage: {
+      title: 'Використання токенів', // Token Usage
+      explanation: 'Відображає щоденне використання токенів мовної моделі для програми, корисно для контролю витрат.',
+      consumed: 'Спожито', // Consumed
+    },
+    avgSessionInteractions: {
+      title: 'Середня кількість взаємодій під час сеансу', // Avg. Session Interactions
+      explanation: 'Кількість безперервних комунікацій між користувачем і ШІ; для програм, що базуються на розмовах.',
+    },
+    userSatisfactionRate: {
+      title: 'Рівень задоволеності користувачів',
+      explanation: 'Кількість лайків на 1000 повідомлень. Це означає частку відповідей, якими користувачі дуже задоволені.',
+    },
+    avgResponseTime: {
+      title: 'Середній час відповіді',
+      explanation: 'Час (мс) для обробки/відповіді ШІ; для текстових програм.',
+    },
+    tps: {
+      title: 'Швидкість виведення токенів',
+      explanation: 'Виміряйте продуктивність LLM. Підрахуйте швидкість виведення токенів LLM від початку запиту до завершення виведення.',
+    },
+  },
+}
+
+export default translation

+ 54 - 0
web/i18n/lang/app.uk.ts

@@ -0,0 +1,54 @@
+const translation = { // Add the Ukrainian translation object
+  createApp: 'Створити новий додаток',
+  types: {
+    all: 'Всі',
+    assistant: 'Асистент',
+    completion: 'Автодоповнення',
+  },
+  modes: {
+    completion: 'Генератор тексту',
+    chat: 'Базовий асистент',
+  },
+  createFromConfigFile: 'Створити додаток з файла конфігурації',
+  deleteAppConfirmTitle: 'Видалити цей додаток?',
+  deleteAppConfirmContent:
+      'Видалення додатка є незворотнім. Користувачі більше не матимуть доступ до вашого додатка, всі конфігурації підказок та журнали будуть видалені назавжди.',
+  appDeleted: 'Додаток видалено',
+  appDeleteFailed: 'Не вдалося видалити додаток',
+  join: 'Приєднуйтесь до спільноти',
+  communityIntro:
+      'Обговорюйте різні питання з членами команди, учасниками та розробниками на різних каналах.',
+  roadmap: 'Ознайомтеся з нашою дорожньою картою',
+  appNamePlaceholder: 'Будь ласка, введіть назву додатка',
+  newApp: {
+    startToCreate: 'Давайте створимо Ваш новий додаток',
+    captionName: 'Значок та назва додатка',
+    captionAppType: 'Який тип додатка Ви бажаєте створити?',
+    previewDemo: 'Попередній перегляд демо',
+    chatApp: 'Асистент',
+    chatAppIntro:
+        'Я хочу створити чат-додаток. Цей додаток використовує формат запитань та відповідей, що дозволяє проводити кілька раундів безперервної розмови.',
+    agentAssistant: 'Новий агент-асистент',
+    completeApp: 'Генератор тексту',
+    completeAppIntro:
+        'Я хочу створити додаток, який генерує високоякісний текст на основі підказок, наприклад, створення статей, резюме, перекладів тощо.',
+    showTemplates: 'Я хочу вибрати з шаблону',
+    hideTemplates: 'Повернутися до вибору режиму',
+    Create: 'Створити',
+    Cancel: 'Скасувати',
+    nameNotEmpty: 'Назва не може бути пустою',
+    appTemplateNotSelected: 'Будь ласка, виберіть шаблон',
+    appTypeRequired: 'Будь ласка, виберіть тип додатка',
+    appCreated: 'Додаток створено',
+    appCreateFailed: 'Не вдалося створити додаток',
+  },
+  editApp: {
+    startToEdit: 'Редагувати додаток',
+  },
+  emoji: {
+    ok: 'OK',
+    cancel: 'Скасувати',
+  },
+}
+
+export default translation

+ 113 - 0
web/i18n/lang/billing.uk.ts

@@ -0,0 +1,113 @@
+const translation = {
+  currentPlan: 'Поточний план',
+  upgradeBtn: {
+    plain: 'Оновити план',
+    encourage: 'Оновити зараз',
+    encourageShort: 'Оновити',
+  },
+  viewBilling: 'Керувати рахунками та підписками',
+  buyPermissionDeniedTip: 'Зв\'яжіться з адміністратором вашого підприємства, щоб оформити підписку',
+  plansCommon: {
+    title: 'Виберіть план, який підходить саме вам',
+    yearlyTip: 'Отримайте 2 місяці безкоштовно, оформивши річну підписку!',
+    mostPopular: 'Найпопулярніший',
+    planRange: {
+      monthly: 'Щомісяця',
+      yearly: 'Щорічно',
+    },
+    month: 'місяць',
+    year: 'рік',
+    save: 'Зберегти ',
+    free: 'Безкоштовно',
+    currentPlan: 'Поточний план',
+    contractSales: 'Зв\'язатися з відділом продажів',
+    contractOwner: 'Зв\'язатися з керівником команди',
+    startForFree: 'Почніть безкоштовно',
+    getStartedWith: 'Почніть роботу з ',
+    contactSales: 'Зв\'язатися з відділом продажів',
+    talkToSales: 'Поговоріть зі службою продажів',
+    modelProviders: 'Постачальники моделей',
+    teamMembers: 'Члени команди',
+    buildApps: 'Створювати додатки',
+    vectorSpace: 'Векторний простір',
+    vectorSpaceBillingTooltip: 'Кожен 1 МБ може зберігати близько 1,2 мільйона символів векторизованих даних (оцінка з використанням OpenAI Embeddings, відрізняється в залежності від моделей).',
+    vectorSpaceTooltip: 'Векторний простір – це система довгострокової пам\'яті, необхідна LLM для розуміння ваших даних.',
+    documentProcessingPriority: 'Пріоритет обробки документів',
+    documentProcessingPriorityTip: 'Для вищого пріоритету обробки документів оновіть свій план.',
+    documentProcessingPriorityUpgrade: 'Обробляйте більше даних із вищою точністю та на більших швидкостях.',
+    priority: {
+      'standard': 'Стандартний',
+      'priority': 'Пріоритетний',
+      'top-priority': 'Найвищий пріоритет',
+    },
+    logsHistory: 'Історія журналів',
+    customTools: 'Користувальницькі інструменти',
+    unavailable: 'Недоступний',
+    days: 'днів',
+    unlimited: 'Безлімітний',
+    support: 'Підтримка',
+    supportItems: {
+      communityForums: 'Форуми спільноти',
+      emailSupport: 'Підтримка електронною поштою',
+      priorityEmail: 'Пріоритетна підтримка електронною поштою та в чаті',
+      logoChange: 'Зміна логотипу',
+      SSOAuthentication: 'Автентифікація SSO',
+      personalizedSupport: 'Персоналізована підтримка',
+      dedicatedAPISupport: 'Спеціальна підтримка API',
+      customIntegration: 'Вбудована інтеграція та підтримка',
+      ragAPIRequest: 'RAG API запити',
+      agentMode: 'Режим агента',
+      workflow: 'Робочий процес',
+    },
+    comingSoon: 'Скоро',
+    member: 'Учасник',
+    memberAfter: 'учасника',
+    messageRequest: {
+      title: 'Кредити повідомлень',
+      tooltip: 'Квоти на виклик повідомлень для різних планів з використанням моделей OpenAI (крім gpt4). Повідомлення понад ліміт використовуватимуть ваш ключ API OpenAI.',
+    },
+    annotatedResponse: {
+      title: 'Ліміти квоти відповідей з анотаціями',
+      tooltip: 'Ручне редагування та анотування відповідей забезпечує налаштовувані високоякісні можливості відповідей на запитання для програм. (Застосовується лише в чат-програмах)',
+    },
+    ragAPIRequestTooltip: 'Відноситься до кількості викликів API, що викликають лише можливості обробки бази знань Dify.',
+    receiptInfo: 'Лише власник команди та адміністратор команди можуть підписуватися та переглядати інформацію про виставлення рахунків',
+  },
+  plans: {
+    sandbox: {
+      name: 'Пісочниця',
+      description: '200 безкоштовних пробних версій GPT',
+      includesTitle: 'Включає в себе:',
+    },
+    professional: {
+      name: 'Професійний',
+      description: 'Щоб окремі особи та невеликі команди могли отримати більше можливостей за доступною ціною.',
+      includesTitle: 'Все у безкоштовному плані, плюс:',
+    },
+    team: {
+      name: 'Команда',
+      description: 'Співпрацюйте без обмежень і користуйтеся продуктивністю найвищого рівня.',
+      includesTitle: 'Все, що входить до плану Professional, плюс:',
+    },
+    enterprise: {
+      name: 'Ентерпрайз',
+      description: 'Отримайте повні можливості та підтримку для масштабних критично важливих систем.',
+      includesTitle: 'Все, що входить до плану Team, плюс:',
+    },
+  },
+  vectorSpace: {
+    fullTip: 'Векторний простір заповнений.',
+    fullSolution: 'Оновіть свій план, щоб отримати більше місця.',
+  },
+  apps: {
+    fullTipLine1: 'Оновіть свій план, щоб',
+    fullTipLine2: 'створити більше програм.',
+  },
+  annotatedResponse: {
+    fullTipLine1: 'Оновіть свій план, щоб',
+    fullTipLine2: 'анотувати більше розмов.',
+    quotaTitle: 'Квота на анотовані відповіді',
+  },
+}
+
+export default translation

Datei-Diff unterdrückt, da er zu groß ist
+ 505 - 0
web/i18n/lang/common.uk.ts


+ 30 - 0
web/i18n/lang/custom.uk.ts

@@ -0,0 +1,30 @@
+const translation = {
+  custom: 'Налаштування',
+  upgradeTip: {
+    prefix: 'Оновіть свій план до ',
+    suffix: ', щоб налаштувати свій бренд.',
+  },
+  webapp: {
+    title: 'Налаштувати бренд для WebApp',
+    removeBrand: 'Видалити Powered by Dify',
+    changeLogo: 'Змінити зображення бренду "Powered by"',
+    changeLogoTip: 'Формат SVG або PNG з мінімальним розміром 40x40 пікселів',
+  },
+  app: {
+    title: 'Налаштувати бренд заголовка програми app',
+    changeLogoTip: 'Формат SVG або PNG з мінімальним розміром 80x80 пікселів',
+  },
+  upload: 'Завантажити',
+  uploading: 'Завантаження',
+  uploadedFail: 'Помилка завантаження зображення, будь ласка, завантажте ще раз.',
+  change: 'Змінити',
+  apply: 'Застосувати',
+  restore: 'Відновити значення за замовчуванням',
+  customize: {
+    contactUs: 'зв\'яжіться з нами',
+    prefix: 'Щоб налаштувати логотип бренду в програмі, будь ласка,',
+    suffix: 'щоб перейти на корпоративне видання.',
+  },
+}
+
+export default translation

+ 129 - 0
web/i18n/lang/dataset-creation.uk.ts

@@ -0,0 +1,129 @@
+const translation = {
+  steps: {
+    header: {
+      creation: 'Створити Знання',
+      update: 'Додати дані',
+    },
+    one: 'Виберіть джерело даних',
+    two: 'Попередня обробка та очищення тексту',
+    three: 'Виконати та завершити',
+  },
+  error: {
+    unavailable: 'Ці Знання недоступні',
+  },
+  stepOne: {
+    filePreview: 'Попередній перегляд файлу',
+    pagePreview: 'Попередній перегляд сторінки',
+    dataSourceType: {
+      file: 'Імпортувати з текстового файла',
+      notion: 'Синхронізувати з Notion',
+      web: 'Синхронізувати з веб-сайту',
+    },
+    uploader: {
+      title: 'Завантажити текстовий файл',
+      button: 'Перетягніть файл або',
+      browse: 'Оберіть',
+      tip: 'Підтримуються {{supportTypes}}. Максимум {{size}} МБ кожен.',
+      validation: {
+        typeError: 'Тип файлу не підтримується',
+        size: 'Файл занадто великий. Максимум – {{size}} МБ',
+        count: 'Не підтримується завантаження кількох файлів',
+      },
+      cancel: 'Скасувати',
+      change: 'Змінити',
+      failed: 'Завантаження не вдалося',
+    },
+    notionSyncTitle: 'Notion не підключено',
+    notionSyncTip: 'Для синхронізації з Notion спочатку потрібно встановити зв’язок із Notion.',
+    connect: 'Перейти до підключення',
+    button: 'далі',
+    emptyDatasetCreation: 'Я хочу створити порожні Знання',
+    modal: {
+      title: 'Створити порожні Знання',
+      tip: 'Порожні Знання не будуть містити документів, ви зможете завантажити документи в будь-який час.',
+      input: 'Назва Знань',
+      placeholder: 'Введіть, будь ласка',
+      nameNotEmpty: 'Ім’я не може бути порожнім',
+      nameLengthInvaild: 'Ім’я має бути від 1 до 40 символів',
+      cancelButton: 'Скасувати',
+      confirmButton: 'Створити',
+      failed: 'Створення не вдалося',
+    },
+  },
+  stepTwo: {
+    segmentation: 'Налаштування фрагментації',
+    auto: 'Автоматично',
+    autoDescription: 'Автоматично встановлює правила  фрагментації та попередньої обробки. Незнайомим користувачам рекомендується обрати цей пункт.',
+    custom: 'Вручну',
+    customDescription: 'Налаштуйте власні правила фрагментації, довжину фрагментів, правила попередньої обробки тощо.',
+    separator: 'Ідентифікатор фрагмента',
+    separatorPlaceholder: 'Наприклад, новий рядок (\\\\n) або спеціальний роздільник (наприклад, "***")',
+    maxLength: 'Максимальна довжина фрагмента',
+    overlap: 'Перекриття фрагмента',
+    overlapTip: 'Налаштування перекриття фрагментів може підтримувати семантичний зв’язок між ними, покращуючи ефект отримання даних. Рекомендується встановити 10%-25% від максимального розміру фрагмента.',
+    overlapCheck: 'перекриття фрагмента не повинно бути більшим за максимальну довжину фрагмента',
+    rules: 'Правила попередньої обробки тексту',
+    removeExtraSpaces: 'Замінити послідовні пробіли, нові рядки й табуляції',
+    removeUrlEmails: 'Видалити всі URL-адреси та адреси електронної пошти',
+    removeStopwords: 'Видалити стоп-слова, наприклад, такі як "a", "an", "the"',
+    preview: 'Підтвердити та попередньо переглянути',
+    reset: 'Скинути',
+    indexMode: 'Режим індексації',
+    qualified: 'Високоякісний',
+    recommend: 'Рекомендовано',
+    qualifiedTip: 'Виклик стандартного інтерфейсу системного вбудовування для обробки, щоб забезпечити більш високу точність, коли користувачі подають запит.',
+    warning: 'Будь ласка, спочатку налаштуйте ключ API постачальника моделі.',
+    click: 'Перейти до налаштувань',
+    economical: 'Економний',
+    economicalTip: 'Використовуйте автономні векторизатори, індекси ключових слів тощо, щоб знизити точність без використання токенів',
+    QATitle: 'Сегментація у форматі "питання та відповідь"',
+    QATip: 'Увімкнення цієї опції споживатиме більше токенів',
+    QALanguage: 'Сегментація з використанням',
+    emstimateCost: 'Оцінка',
+    emstimateSegment: 'Орієнтовні фрагменти',
+    segmentCount: 'фрагментів',
+    calculating: 'Розраховується...',
+    fileSource: 'Попередня обробка документа',
+    notionSource: 'Попередня обробка сторінок',
+    other: ' та інші ',
+    fileUnit: ' файли',
+    notionUnit: ' сторінки',
+    lastStep: 'Попередній крок',
+    nextStep: 'Зберегти та обробити',
+    save: 'Зберегти та обробити',
+    cancel: 'Скасувати',
+    sideTipTitle: 'Навіщо розбивати на фрагменти та попередньо обробляти?',
+    sideTipP1: 'При роботі з текстовими даними фрагментація та очищення є двома важливими етапами попередньої обробки.',
+    sideTipP2: 'Сегментація розбиває довгий текст на абзаци для кращого сприйняття моделями. Це підвищує якість і релевантність результатів роботи моделей.',
+    sideTipP3: 'Очищення видаляє непотрібні символи та форматування, роблячи Знання чистішими та легшими для аналізу.',
+    sideTipP4: 'Правильна фрагментація та очищення покращують продуктивність моделі, забезпечуючи більш точні та цінні результати.',
+    previewTitle: 'Попередній перегляд',
+    previewTitleButton: 'Попередній перегляд',
+    previewButton: 'Зміна вмісту на формат Q&A',
+    previewSwitchTipStart: 'Поточний попередній перегляд має текстовий формат, зміна способу подання на формат запитань та відповідей ',
+    previewSwitchTipEnd: ' потребує додаткових токенів',
+    characters: 'символів',
+    indexSettedTip: 'Щоб змінити метод індексування, будь ласка, перейдіть до ',
+    retrivalSettedTip: 'Щоб змінити метод індексування, будь ласка, перейдіть до ',
+    datasetSettingLink: 'Налаштування знань.',
+  },
+  stepThree: {
+    creationTitle: '🎉 Знання створено',
+    creationContent: 'Ми автоматично назвали Знання, ви можете змінити його в будь-який час',
+    label: 'Назва знань',
+    additionTitle: '🎉 Документ завантажено',
+    additionP1: 'Документ було завантажено до Знання',
+    additionP2: ', ви можете знайти його в списку документів Знання.',
+    stop: 'Зупинити обробку',
+    resume: 'Відновити обробку',
+    navTo: 'Перейти до документа',
+    sideTipTitle: 'Що далі',
+    sideTipContent: 'Після завершення індексування документа Знання можна інтегрувати в додаток як контекст. Налаштування контексту можна знайти на сторінці оркестрації підказок. Ви також можете створити його як незалежний плагін індексування ChatGPT для релізу.',
+    modelTitle: 'Ви впевнені, що хочете зупинити вбудовування?',
+    modelContent: 'Якщо вам потрібно буде відновити обробку пізніше, ви продовжите з того місця, де зупинилися.',
+    modelButtonConfirm: 'Підтвердити',
+    modelButtonCancel: 'Скасувати',
+  },
+}
+
+export default translation

+ 349 - 0
web/i18n/lang/dataset-documents.uk.ts

@@ -0,0 +1,349 @@
+const translation = {
+  list: {
+    title: 'Документи',
+    desc: 'Тут відображаються всі файли Знання, і все Знання можна зв’язати з цитатами Dify або проіндексувати за допомогою плагіна Chat.',
+    addFile: 'додати файл',
+    addPages: 'Додати сторінки',
+    table: {
+      header: {
+        fileName: 'НАЗВА ФАЙЛУ',
+        words: 'КІЛЬКІСТЬ СЛІВ',
+        hitCount: 'КІЛЬКІСТЬ ВИЛУЧЕНЬ',
+        uploadTime: 'ЧАС ЗАВАНТАЖЕННЯ',
+        status: 'СТАТУС',
+        action: 'ДІЯ',
+      },
+    },
+    action: {
+      uploadFile: 'Завантажити новий файл',
+      settings: 'Налаштування сегмента',
+      addButton: 'Додати фрагмент',
+      add: 'Додати фрагмент',
+      batchAdd: 'Пакетне додавання',
+      archive: 'Архів',
+      unarchive: 'Розархівувати',
+      delete: 'Видалити',
+      enableWarning: 'Архівований файл неможливо активувати',
+      sync: 'Синхронізувати',
+    },
+    index: {
+      enable: 'Активувати',
+      disable: 'Деактивувати',
+      all: 'Усі',
+      enableTip: 'Файл можна індексувати',
+      disableTip: 'Файл не можна індексувати',
+    },
+    status: {
+      queuing: 'В черзі',
+      indexing: 'Індексування',
+      paused: 'Призупинено',
+      error: 'Помилка',
+      available: 'Доступно',
+      enabled: 'Активовано',
+      disabled: 'Деактивовано',
+      archived: 'Архівовано',
+    },
+    empty: {
+      title: 'Документації ще немає',
+      upload: {
+        tip: 'Ви можете завантажувати файли, синхронізувати з веб-сайту або з веб-програм, таких як Notion, GitHub тощо.',
+      },
+      sync: {
+        tip: 'Dify періодично завантажуватиме файли з вашого Notion і завершуватиме обробку.',
+      },
+    },
+    delete: {
+      title: 'Ви впевнені, що хочете видалити?',
+      content: 'Файл видалено успішно.',
+    },
+    batchModal: {
+      title: 'Пакетне додавання фрагментів',
+      csvUploadTitle: 'Перетягніть файл CSV сюди або натисніть, щоб',
+      browse: 'переглянути',
+      tip: 'CSV-файл повинен мати таку структуру:',
+      question: 'запитання',
+      answer: 'відповідь',
+      contentTitle: 'назва вмісту',
+      content: 'вміст',
+      template: 'Завантажити шаблон',
+      cancel: 'Скасувати',
+      run: 'Запуск пакетної обробки',
+      runError: 'Помилка запуску пакетної обробки',
+      processing: 'Триває пакетна обробка',
+      completed: 'Імпорт завершено',
+      error: 'Помилка імпорту',
+      ok: 'ОК',
+    },
+  },
+  metadata: {
+    title: 'Метадані',
+    desc: 'Маркування метаданих для документів дозволяє штучному інтелекту своєчасно отримувати до них доступ і викриває джерело посилань для користувачів.',
+    dateTimeFormat: 'MMMM D, YYYY hh:mm A',
+    docTypeSelectTitle: 'Будь ласка, виберіть тип документа',
+    docTypeChangeTitle: 'Змінити тип документа',
+    docTypeSelectWarning: 'Якщо тип документа буде змінено, наразі заповнені метадані більше не зберігатимуться',
+    firstMetaAction: 'Почнімо',
+    placeholder: {
+      add: 'Додати ',
+      select: 'Вибрати ',
+    },
+    source: {
+      upload_file: 'Завантажити файл',
+      notion: 'Синхронізувати з Notion',
+      github: 'Синхронізувати з Github',
+    },
+    type: {
+      book: 'Книга',
+      webPage: 'Веб-сторінка',
+      paper: 'Наукова праця',
+      socialMediaPost: 'Пост у соціальних медіа',
+      personalDocument: 'Особистий документ',
+      businessDocument: 'Діловий документ',
+      IMChat: 'Чат миттєвих повідомлень',
+      wikipediaEntry: 'Стаття у Вікіпедії',
+      notion: 'Синхронізувати з Notion',
+      github: 'Синхронізувати з Github',
+      technicalParameters: 'Технічні параметри',
+    },
+    field: {
+      processRule: {
+        processDoc: 'Обробка документа',
+        segmentRule: 'Правило сегментування',
+        segmentLength: 'Довжина фрагментів',
+        processClean: 'Очищення тексту',
+      },
+      book: {
+        title: 'Назва',
+        language: 'Мова',
+        author: 'Автор',
+        publisher: 'Видавець',
+        publicationDate: 'Дата публікації',
+        ISBN: 'ISBN',
+        category: 'Категорія',
+      },
+      webPage: {
+        title: 'Назва',
+        url: 'URL',
+        language: 'Мова',
+        authorPublisher: 'Автор/видавець',
+        publishDate: 'Дата публікації',
+        topicsKeywords: 'Теми/ключові слова',
+        description: 'Опис',
+      },
+      paper: {
+        title: 'Назва',
+        language: 'Мова',
+        author: 'Автор',
+        publishDate: 'Дата публікації',
+        journalConferenceName: 'Назва журналу/конференції',
+        volumeIssuePage: 'Випуск/номер/сторінка',
+        DOI: 'DOI',
+        topicsKeywords: 'Теми/ключові слова',
+        abstract: 'Анотація',
+      },
+      socialMediaPost: {
+        platform: 'Платформа',
+        authorUsername: 'Автор/ім’я користувача',
+        publishDate: 'Дата публікації',
+        postURL: 'URL-адреса посту',
+        topicsTags: 'Теми/теги',
+      },
+      personalDocument: {
+        title: 'Назва',
+        author: 'Автор',
+        creationDate: 'Дата створення',
+        lastModifiedDate: 'Дата останньої зміни',
+        documentType: 'Тип документа',
+        tagsCategory: 'Теги/категорії',
+      },
+      businessDocument: {
+        title: 'Назва',
+        author: 'Автор',
+        creationDate: 'Дата створення',
+        lastModifiedDate: 'Дата останньої зміни',
+        documentType: 'Тип документа',
+        departmentTeam: 'Відділ/команда',
+      },
+      IMChat: {
+        chatPlatform: 'Платформа чату',
+        chatPartiesGroupName: 'Сторони чату/назва групи',
+        participants: 'Учасники',
+        startDate: 'Дата початку',
+        endDate: 'Дата завершення',
+        topicsKeywords: 'Теми/ключові слова',
+        fileType: 'Тип файлу',
+      },
+      wikipediaEntry: {
+        title: 'Назва',
+        language: 'Мова',
+        webpageURL: 'URL-адреса вебсторінки',
+        editorContributor: 'Редактор/автор',
+        lastEditDate: 'Дата останнього редагування',
+        summaryIntroduction: 'Резюме/вступ',
+      },
+      notion: {
+        title: 'Назва',
+        language: 'Мова',
+        author: 'Автор',
+        createdTime: 'Час створення',
+        lastModifiedTime: 'Час останньої зміни',
+        url: 'URL',
+        tag: 'Тег',
+        description: 'Опис',
+      },
+      github: {
+        repoName: 'Назва репозиторію',
+        repoDesc: 'Опис репозиторію',
+        repoOwner: 'Власник репозиторію',
+        fileName: 'Назва файлу',
+        filePath: 'Шлях до файлу',
+        programmingLang: 'Мова програмування',
+        url: 'URL',
+        license: 'Ліцензія',
+        lastCommitTime: 'Час останнього коміту',
+        lastCommitAuthor: 'Автор останнього коміту',
+      },
+      originInfo: {
+        originalFilename: 'Оригінальна назва файлу',
+        originalFileSize: 'Оригінальний розмір файлу',
+        uploadDate: 'Дата завантаження',
+        lastUpdateDate: 'Дата останнього оновлення',
+        source: 'Джерело',
+      },
+      technicalParameters: {
+        segmentSpecification: 'Специфікація фрагментів',
+        segmentLength: 'Довжина фрагментів',
+        avgParagraphLength: 'Середня довжина абзаців',
+        paragraphs: 'Абзаци',
+        hitCount: 'Кількість вилучень',
+        embeddingTime: 'Час вбудовування',
+        embeddedSpend: 'Витрачено на вбудовування',
+      },
+    },
+    languageMap: {
+      zh: 'Китайська',
+      en: 'Англійська',
+      es: 'Іспанська',
+      fr: 'Французька',
+      de: 'Німецька',
+      ja: 'Японська',
+      ko: 'Корейська',
+      ru: 'Російська',
+      ar: 'Арабська',
+      pt: 'Португальська',
+      it: 'Італійська',
+      nl: 'Голландська',
+      pl: 'Польська',
+      sv: 'Шведська',
+      tr: 'Турецька',
+      he: 'Іврит',
+      hi: 'Гінді',
+      da: 'Данська',
+      fi: 'Фінська',
+      no: 'Норвезька',
+      hu: 'Угорська',
+      el: 'Грецька',
+      cs: 'Чеська',
+      th: 'Тайська',
+      id: 'Індонезійська',
+      uk: 'Українська',
+    },
+    categoryMap: {
+      book: {
+        fiction: 'Фантастика',
+        biography: 'Біографія',
+        history: 'Історія',
+        science: 'Наука',
+        technology: 'Технології',
+        education: 'Навчальна література',
+        philosophy: 'Філософія',
+        religion: 'Релігія',
+        socialSciences: 'Соціальні науки',
+        art: 'Мистецтво',
+        travel: 'Подорожі',
+        health: 'Здоровʼя',
+        selfHelp: 'Самодопомога',
+        businessEconomics: 'Бізнес-економіка',
+        cooking: 'Куховаріння',
+        childrenYoungAdults: 'Книги з виховання',
+        comicsGraphicNovels: 'Комікси',
+        poetry: 'Поезія',
+        drama: 'Драма',
+        other: 'Інше',
+      },
+      personalDoc: {
+        notes: 'Замітки', // General notes or memos
+        blogDraft: 'Чернетка блогу',
+        diary: 'Щоденник',
+        researchReport: 'Науковий звіт',
+        bookExcerpt: 'Уривок з книги',
+        schedule: 'Розклад',
+        list: 'Список',
+        projectOverview: 'Огляд проекту',
+        photoCollection: 'Колекція фотографій',
+        creativeWriting: 'Творче письмо',
+        codeSnippet: 'Фрагмент коду',
+        designDraft: 'Дизайн-проект',
+        personalResume: 'Особисте резюме',
+        other: 'Інше',
+      },
+      businessDoc: {
+        meetingMinutes: 'Протокол зустрічі',
+        researchReport: 'Науковий звіт',
+        proposal: 'Пропозиція',
+        employeeHandbook: 'Посібник для працівників',
+        trainingMaterials: 'Навчальні матеріали',
+        requirementsDocument: 'Документ з вимогами',
+        designDocument: 'Проєктний документ',
+        productSpecification: 'Специфікація продукту',
+        financialReport: 'Фінансовий звіт',
+        marketAnalysis: 'Аналіз ринку',
+        projectPlan: 'План проекту',
+        teamStructure: 'Структура команди',
+        policiesProcedures: 'Політики та процедури',
+        contractsAgreements: 'Контракти та угоди',
+        emailCorrespondence: 'Електронне листування',
+        other: 'Інше',
+      },
+    },
+  },
+  embedding: {
+    processing: 'Обробка векторного представлення слів...',
+    paused: 'Побудова векторів призупинена',
+    completed: 'Побудова векторів завершена',
+    error: 'Помилка побудови векторів',
+    docName: 'Попередня обробка документа',
+    mode: 'Правило сегментації',
+    segmentLength: 'Довжина фрагментів',
+    textCleaning: 'Попереднє визначення тексту та очищення',
+    segments: 'Параграфи',
+    highQuality: 'Режим високої якості',
+    economy: 'Економний режим',
+    estimate: 'Розрахунок',
+    stop: 'Зупинити обробку',
+    resume: 'Продовжити обробку',
+    automatic: 'Автоматичний',
+    custom: 'Користувацький',
+    previewTip: 'Попередній перегляд параграфа буде доступний після завершення побудови векторів',
+  },
+  segment: {
+    paragraphs: 'Параграфи',
+    keywords: 'Ключові слова',
+    addKeyWord: 'Додати ключове слово',
+    keywordError: 'Максимальна довжина ключового слова – 20 символів',
+    characters: 'символів',
+    hitCount: 'Кількість пошуку',
+    vectorHash: 'Векторний хеш: ',
+    questionPlaceholder: 'додайте запитання тут',
+    questionEmpty: 'Питання не може бути порожнім',
+    answerPlaceholder: 'додайте відповідь тут',
+    answerEmpty: 'Відповідь не може бути порожньою',
+    contentPlaceholder: 'додайте вміст тут',
+    contentEmpty: 'Вміст не може бути порожнім',
+    newTextSegment: 'Новий текстовий сегмент',
+    newQaSegment: 'Новий сегмент запитань та відповідей',
+    delete: 'Видалити цей фрагмент?',
+  },
+}
+
+export default translation

+ 28 - 0
web/i18n/lang/dataset-hit-testing.uk.ts

@@ -0,0 +1,28 @@
+const translation = {
+  title: 'Тестування вибірки',
+  desc: 'Тестування ефективності пошуку знань на основі наданого текстового запиту.',
+  dateTimeFormat: 'DD/MM/YYYY HH:mm A',
+  recents: 'Останні',
+  table: {
+    header: {
+      source: 'Джерело',
+      text: 'Текст',
+      time: 'Час',
+    },
+  },
+  input: {
+    title: 'Вихідний текст',
+    placeholder: 'Будь ласка, введіть текст, рекомендується коротке декларативне речення.',
+    countWarning: 'До 200 символів.',
+    indexWarning: 'Тільки високоякісні знання.',
+    testing: 'Тестування',
+  },
+  hit: {
+    title: 'ВИБРАНІ АБЗАЦИ',
+    emptyTip: 'Результати тестування вибірки відобразяться тут',
+  },
+  noRecentTip: 'Тут немає результатів останніх запитів',
+  viewChart: 'ПЕРЕГЛЯНУТИ ВЕКТОРНУ ДІАГРАМУ',
+}
+
+export default translation

+ 33 - 0
web/i18n/lang/dataset-settings.uk.ts

@@ -0,0 +1,33 @@
+const translation = {
+  title: 'Налаштування бази знань',
+  desc: 'Тут ви можете змінити властивості та методи роботи бази знань.',
+  form: {
+    name: 'Назва бази знань',
+    namePlaceholder: 'Введіть назву бази знань',
+    nameError: 'Назва не може бути порожньою',
+    desc: 'Опис бази знань',
+    descInfo: 'Напишіть зрозумілий текстовий опис, щоб окреслити вміст бази знань. Цей опис використовуватиметься як основа для узгодження під час вибору з кількох баз знань для висновку.',
+    descPlaceholder: 'Опишіть, що міститься в цій базі знань. Детальний опис дозволяє AI своєчасно отримати доступ до вмісту бази знань. Якщо значення порожнє, Dify використовуватиме стратегію влучань за умовчанням.',
+    descWrite: 'Дізнайтеся, як написати хороший опис бази знань.',
+    permissions: 'Дозволи',
+    permissionsOnlyMe: 'Тільки я',
+    permissionsAllMember: 'Усі члени команди',
+    indexMethod: 'Метод індексації',
+    indexMethodHighQuality: 'Висока якість',
+    indexMethodHighQualityTip: 'Використовуйте інтерфейс вбудовування OpenAI для обробки, щоб забезпечити вищу точність під час запитів користувачів.',
+    indexMethodEconomy: 'Економний',
+    indexMethodEconomyTip: 'Використовуйте автономні векторні двигуни, індекси ключових слів тощо, щоб зменшити точність без використання токенів.',
+    embeddingModel: 'Модель вбудовування',
+    embeddingModelTip: 'Змінити вбудовану модель, будь ласка, перейдіть до ',
+    embeddingModelTipLink: 'Налаштування',
+    retrievalSetting: {
+      title: 'Налаштування вибірки',
+      learnMore: 'Дізнатися більше',
+      description: ' про метод вибірки.',
+      longDescription: ' про метод вибірки, ви можете змінити це будь-коли в налаштуваннях бази знань.',
+    },
+    save: 'Зберегти',
+  },
+}
+
+export default translation

+ 47 - 0
web/i18n/lang/dataset.uk.ts

@@ -0,0 +1,47 @@
+const translation = {
+  knowledge: 'Знання',
+  documentCount: ' док.', // Скорочення від 'документів'
+  wordCount: ' тис. слів',
+  appCount: ' пов\'язаних додатків',
+  createDataset: 'Створити Знання',
+  createDatasetIntro: 'Імпортуйте власні текстові дані або записуйте дані в реальному часі через Webhook для покращення LLM-контексту.',
+  deleteDatasetConfirmTitle: 'Видалити це Знання?',
+  deleteDatasetConfirmContent:
+        'Видалення "Знання" є незворотнім. Користувачі більше не матимуть доступу до Знань, а всі конфігурації підказок і журнали будуть безповоротно видалені.',
+  datasetDeleted: 'Знання видалено',
+  datasetDeleteFailed: 'Не вдалося видалити Знання',
+  didYouKnow: 'Чи знаєте ви?',
+  intro1: 'Знання можна інтегрувати до програми Dify ',
+  intro2: 'як контекст',
+  intro3: ',',
+  intro4: 'або його ',
+  intro5: 'можна створити',
+  intro6: ' як автономний плагін індексу ChatGPT для публікації',
+  unavailable: 'Недоступно',
+  unavailableTip: 'Модель вбудовування недоступна, необхідно налаштувати модель вбудовування за замовчуванням',
+  datasets: 'ЗНАННЯ',
+  datasetsApi: 'API',
+  retrieval: {
+    semantic_search: {
+      title: 'Векторний пошук',
+      description: 'Генерує вбудовування запитів і шукає фрагмент тексту, найбільш схожий на його векторне представлення.',
+    },
+    full_text_search: {
+      title: 'Повнотекстовий пошук',
+      description: 'Індексує всі терміни в документі, дозволяючи користувачам шукати будь-який термін і отримувати відповідний фрагмент тексту, що містить цей термін.',
+    },
+    hybrid_search: {
+      title: 'Гібридний пошук',
+      description: 'Виконуйте повнотекстовий пошук і векторний пошук одночасно, повторно ранжуючи, щоб вибрати найкращу відповідність на запит користувача. Необхідна конфігурація Rerank model API.',
+      recommend: 'Рекомендовано',
+    },
+    invertedIndex: {
+      title: 'Інвертований індекс',
+      description: 'Інвертований індекс – це структура, яка використовується для ефективного пошуку. Організований за термінами, кожен термін вказує на документи або веб-сторінки, що його містять.',
+    },
+    change: 'Змінити',
+    changeRetrievalMethod: 'Змінити метод пошуку',
+  },
+}
+
+export default translation

+ 41 - 0
web/i18n/lang/explore.uk.ts

@@ -0,0 +1,41 @@
+const translation = {
+  title: 'Досліджувати',
+  sidebar: {
+    discovery: 'Відкриття',
+    chat: 'Чат',
+    workspace: 'Робочий простір',
+    action: {
+      pin: 'Закріпити',
+      unpin: 'Відкріпити',
+      rename: 'Перейменувати',
+      delete: 'Видалити',
+    },
+    delete: {
+      title: 'Видалити додаток',
+      content: 'Ви впевнені, що хочете видалити цю програму?',
+    },
+  },
+  apps: {
+    title: 'Вивчайте програми від Dify',
+    description: 'Використовуйте ці шаблони миттєво або налаштуйте власні програми на основі шаблонів.',
+    allCategories: 'Усі категорії',
+  },
+  appCard: {
+    addToWorkspace: 'Додати до робочого простору',
+    customize: 'Налаштувати',
+  },
+  appCustomize: {
+    title: 'Створити додаток з {{name}}',
+    subTitle: 'Значок програми та назва',
+    nameRequired: 'Назва програми обов’язкова',
+  },
+  category: {
+    Assistant: 'Помічник',
+    Writing: 'Написання',
+    Translate: 'Переклад',
+    Programming: 'Програмування',
+    HR: 'HR',
+  },
+}
+
+export default translation

+ 4 - 0
web/i18n/lang/layout.uk.ts

@@ -0,0 +1,4 @@
+const translation = {
+}
+
+export default translation

+ 59 - 0
web/i18n/lang/login.uk.ts

@@ -0,0 +1,59 @@
+const translation = {
+  pageTitle: 'Привіт, почнемо!👋',
+  welcome: 'Ласкаво просимо до Dify, будь ласка, увійдіть, щоб продовжити.',
+  email: 'Адреса електронної пошти',
+  emailPlaceholder: 'Ваша електронна пошта',
+  password: 'Пароль',
+  passwordPlaceholder: 'Ваш пароль',
+  name: 'Ім\'я користувача',
+  namePlaceholder: 'Ваше ім\'я користувача',
+  forget: 'Забули пароль?',
+  signBtn: 'Вхід',
+  installBtn: 'Налаштувати',
+  setAdminAccount: 'Налаштування облікового запису адміністратора',
+  setAdminAccountDesc: 'Максимальні привілеї для облікового запису адміністратора, які можна використовувати для створення програм, керування постачальниками LLM тощо.',
+  createAndSignIn: 'Створити та увійти',
+  oneMoreStep: 'Ще один крок',
+  createSample: 'На основі цієї інформації ми створимо для вас зразок програми',
+  invitationCode: 'Код запрошення',
+  invitationCodePlaceholder: 'Ваш код запрошення',
+  interfaceLanguage: 'Мова інтерфейсу',
+  timezone: 'Часовий пояс',
+  go: 'Перейти до Dify',
+  sendUsMail: 'Надішліть нам своє представлення, і ми обробимо запит на запрошення.',
+  acceptPP: 'Я прочитав і приймаю політику конфіденційності',
+  reset: 'Будь ласка, виконайте таку команду, щоб скинути пароль',
+  withGitHub: 'Продовжити з GitHub',
+  withGoogle: 'Продовжити з Google',
+  rightTitle: 'Розкрийте весь потенціал LLM',
+  rightDesc: 'З легкістю створюйте візуально привабливі, функціональні та вдосконалювані програми зі штучним інтелектом.',
+  tos: 'Умови обслуговування',
+  pp: 'Політика конфіденційності',
+  tosDesc: 'Реєструючись, ви приймаєте наші',
+  donthave: 'Не маєте?',
+  invalidInvitationCode: 'Недійсний код запрошення',
+  accountAlreadyInited: 'Обліковий запис уже ініціалізовано',
+  error: {
+    emailEmpty: 'Адреса електронної пошти обов\'язкова',
+    emailInValid: 'Введіть дійсну адресу електронної пошти',
+    nameEmpty: 'Ім\'я обов\'язкове',
+    passwordEmpty: 'Пароль є обов’язковим',
+    passwordInvalid: 'Пароль повинен містити літери та цифри, а довжина повинна бути більшою за 8',
+  },
+  license: {
+    tip: 'Перед запуском Dify Community Edition ознайомтеся з ліцензією з відкритим кодом на GitHub',
+    link: 'Ліцензія з відкритим кодом',
+  },
+  join: 'Приєднуйтесь',
+  joinTipStart: 'Запрошуємо вас приєднатися',
+  joinTipEnd: 'команда Dify',
+  invalid: 'Посилання застаріло',
+  explore: 'Досліджуйте Dify',
+  activatedTipStart: 'Ви приєдналися до',
+  activatedTipEnd: 'команда',
+  activated: 'Увійти зараз',
+  adminInitPassword: 'Пароль ініціалізації адміністратора',
+  validate: 'Перевірити',
+}
+
+export default translation

+ 4 - 0
web/i18n/lang/register.uk.ts

@@ -0,0 +1,4 @@
+const translation = {
+}
+
+export default translation

+ 72 - 0
web/i18n/lang/share-app.uk.ts

@@ -0,0 +1,72 @@
+const translation = {
+  common: {
+    welcome: 'Ласкаво просимо до використання',
+    appUnavailable: 'Додаток недоступний',
+    appUnkonwError: 'Додаток недоступний',
+  },
+  chat: {
+    newChat: 'Новий чат',
+    pinnedTitle: 'Закріплені',
+    unpinnedTitle: 'Чати',
+    newChatDefaultName: 'Нова розмова',
+    resetChat: 'Очистити розмову',
+    powerBy: 'Забезпечується',
+    prompt: 'Підказка',
+    privatePromptConfigTitle: 'Налаштування розмови',
+    publicPromptConfigTitle: 'Початкова підказка',
+    configStatusDes: 'Перед початком ви можете змінити налаштування розмови',
+    configDisabled: 'Для цього сеансу було використано налаштування попереднього сеансу.',
+    startChat: 'Почати чат',
+    privacyPolicyLeft: 'Будь ласка, ознайомтеся з ',
+    privacyPolicyMiddle: 'політикою конфіденційності',
+    privacyPolicyRight: ', наданою розробником програми.',
+    deleteConversation: {
+      title: 'Видалити розмову',
+      content: 'Ви впевнені, що хочете видалити цю розмову?',
+    },
+    tryToSolve: 'Спробувати вирішити',
+    temporarySystemIssue: 'Вибачте, тимчасова системна проблема.',
+  },
+
+  generation: {
+    tabs: {
+      create: 'Запустити один раз',
+      batch: 'Запустити пакет',
+      saved: 'Збережено',
+    },
+    savedNoData: {
+      title: 'Ви ще не зберегли результат!',
+      description: 'Почніть генерувати вміст і знайдіть збережені результати тут.',
+      startCreateContent: 'Почати створювати вміст',
+    },
+    title: 'Доповнення AI',
+    queryTitle: 'Вміст запиту',
+    completionResult: 'Результат завершення',
+    queryPlaceholder: 'Напишіть вміст свого запиту...',
+    run: 'Виконати',
+    copy: 'Копіювати',
+    resultTitle: 'Доповнення AI',
+    noData: 'AI дасть вам те, що ви хочете тут.',
+    csvUploadTitle: 'Перетягніть файл CSV сюди або',
+    browse: 'переглянути',
+    csvStructureTitle: 'Файл CSV повинен відповідати наступній структурі:',
+    downloadTemplate: 'Завантажити шаблон тут',
+    field: 'Поле',
+    batchFailed: {
+      info: '{{num}} виконань не вдалося',
+      retry: 'Повторити',
+      outputPlaceholder: 'Вміст відсутній',
+    },
+    errorMsg: {
+      empty: 'Будь ласка, введіть вміст у завантажений файл.',
+      fileStructNotMatch: 'Завантажений CSV-файл не відповідає структурі.',
+      emptyLine: 'Рядок {{rowIndex}} порожній',
+      invalidLine: 'Рядок {{rowIndex}}: значення {{varName}} не може бути пустим',
+      moreThanMaxLengthLine: 'Рядок {{rowIndex}}: значення {{varName}} не може містити більше {{maxLength}} символів',
+      atLeastOne: 'Будь ласка, введіть принаймні один рядок у завантажений файл.',
+    },
+
+  },
+}
+
+export default translation

+ 105 - 0
web/i18n/lang/tools.uk.ts

@@ -0,0 +1,105 @@
+const translation = {
+  title: 'Інструменти',
+  createCustomTool: 'Створити власний інструмент',
+  type: {
+    all: 'Усі',
+    builtIn: 'Вбудовані',
+    custom: 'Користувацькі',
+  },
+  contribute: {
+    line1: 'Мені цікаво зробити свій внесок',
+    line2: 'створення інструментів для Dify.',
+    viewGuide: 'Переглянути інструкцію',
+  },
+  author: 'Автор',
+  auth: {
+    unauthorized: 'Авторизуватися',
+    authorized: 'Авторизовано',
+    setup: 'Налаштувати авторизацію, щоб використовувати',
+    setupModalTitle: 'Налаштування авторизації',
+    setupModalTitleDescription: 'Після налаштування облікових даних усі члени робочого простору можуть використовувати цей інструмент під час оркестрування програм.',
+  },
+  includeToolNum: '{{num}} інструмент(ів) включено',
+  addTool: 'Додати інструмент ',
+  createTool: {
+    title: 'Створити власний інструмент',
+    editAction: 'Налаштування',
+    editTitle: 'Редагувати настроюваний інструмент',
+    name: 'Назва',
+    toolNamePlaceHolder: 'Введіть назву інструменту',
+    schema: 'Схема',
+    schemaPlaceHolder: 'Введіть свою схему OpenAPI тут',
+    viewSchemaSpec: 'Переглянути специфікацію OpenAPI-Swagger',
+    importFromUrl: 'Імпортувати з URL-адреси',
+    importFromUrlPlaceHolder: 'https://...',
+    urlError: 'Введіть дійсну URL-адресу',
+    examples: 'Приклади',
+    exampleOptions: {
+      json: 'Погода (JSON)',
+      yaml: 'Зоотоварів (YAML)',
+      blankTemplate: 'Чистий шаблон',
+    },
+    availableTools: {
+      title: 'Доступні інструменти',
+      name: 'Назва',
+      description: 'Опис',
+      method: 'Метод',
+      path: 'Шлях',
+      action: 'Дія',
+      test: 'Перевірка',
+    },
+    authMethod: {
+      title: 'Спосіб авторизації',
+      type: 'Тип авторизації',
+      types: {
+        none: 'Немає',
+        api_key: 'API ключі',
+      },
+      key: 'Ключ',
+      value: 'Значення',
+    },
+    privacyPolicy: 'Політика конфіденційності',
+    privacyPolicyPlaceholder: 'Введіть політику конфіденційності',
+  },
+
+  test: {
+    title: 'Тест',
+    parametersValue: 'Параметри та значення',
+    parameters: 'Параметри',
+    value: 'Значення',
+    testResult: 'Результати тесту',
+    testResultPlaceholder: 'Результат тесту буде відображатися тут',
+  },
+  thought: {
+    using: 'Використання',
+    used: 'Використано',
+    requestTitle: 'Запит до',
+    responseTitle: 'Відповідь від',
+  },
+  setBuiltInTools: {
+    info: 'Інформація',
+    setting: 'Налаштування',
+    toolDescription: 'Опис інструменту',
+    parameters: 'Параметри',
+    string: 'Рядок',
+    number: 'Число',
+    required: 'Обов’язково',
+    infoAndSetting: 'Інформація та налаштування',
+  },
+  noCustomTool: {
+    title: 'Немає користувацьких інструментів!',
+    content: 'Додавайте та керуйте своїми власними інструментами тут для створення програм зі штучним інтелектом.',
+    createTool: 'Створити інструмент',
+  },
+  noSearchRes: {
+    title: 'Вибачте, немає результатів!',
+    content: 'Ми не знайшли жодних інструментів, які б відповідали вашому пошуку.',
+    reset: 'Скинути пошук',
+  },
+  builtInPromptTitle: 'Підказка',
+  toolRemoved: 'Інструмент видалено',
+  notAuthorized: 'Інструмент не авторизовано',
+  howToGet: 'Як отримати',
+}
+
+export default translation

+ 10 - 2
web/utils/language.ts

@@ -3,8 +3,8 @@ export type Item = {
   name: string
 }
 
-export const LanguagesSupported = ['en-US', 'zh-Hans', 'pt-BR', 'es-ES', 'fr-FR', 'de-DE', 'ja-JP', 'ko-KR', 'ru-RU', 'it-IT', 'th-TH', 'id-ID']
-export const LanguagesSupportedUnderscore = ['en_US', 'zh_Hans', 'pt_BR', 'es_ES', 'fr_FR', 'de_DE', 'ja_JP', 'ko_KR', 'ru_RU', 'it_IT', 'th_TH', 'id_ID']
+export const LanguagesSupported = ['en-US', 'zh-Hans', 'pt-BR', 'es-ES', 'fr-FR', 'de-DE', 'ja-JP', 'ko-KR', 'ru-RU', 'it-IT', 'th-TH', 'id-ID', 'uk-UA']
+export const LanguagesSupportedUnderscore = ['en_US', 'zh_Hans', 'pt_BR', 'es_ES', 'fr_FR', 'de_DE', 'ja_JP', 'ko_KR', 'ru_RU', 'it_IT', 'th_TH', 'id_ID', 'uk_UA']
 
 export const languages = [
   {
@@ -55,6 +55,10 @@ export const languages = [
     value: 'id-ID',
     name: 'Bahasa Indonesia',
   },
+  {
+    value: 'uk-UA',
+    name: 'Українська(Україна)',
+  },
 ]
 
 export const getModelRuntimeSupported = (locale: string) => {
@@ -74,6 +78,7 @@ export const languageMaps = {
   'ko-KR': 'ko-KR',
   'ru-RU': 'ru-RU',
   'it-IT': 'it-IT',
+  'uk-UA': 'uk-UA',
 }
 
 export type I18nText = {
@@ -87,6 +92,7 @@ export type I18nText = {
   'ko-KR': string
   'ru-RU': string
   'it-IT': string
+  'uk-UA': string
 }
 
 export const NOTICE_I18N = {
@@ -99,6 +105,7 @@ export const NOTICE_I18N = {
     de_DE: 'Wichtiger Hinweis',
     ja_JP: '重要なお知らせ',
     ko_KR: '중요 공지',
+    uk_UA: 'Важливе повідомлення',
   },
   desc: {
     en_US: 'Our system will be unavailable from 19:00 to 24:00 UTC on August 28 for an upgrade. For questions, kindly contact our support team (support@dify.ai). We value your patience.',
@@ -109,6 +116,7 @@ export const NOTICE_I18N = {
     de_DE: 'Our system will be unavailable from 19:00 to 24:00 UTC on August 28 for an upgrade. For questions, kindly contact our support team (support@dify.ai). We value your patience.',
     ja_JP: 'Our system will be unavailable from 19:00 to 24:00 UTC on August 28 for an upgrade. For questions, kindly contact our support team (support@dify.ai). We value your patience.',
     ko_KR: 'Our system will be unavailable from 19:00 to 24:00 UTC on August 28 for an upgrade. For questions, kindly contact our support team (support@dify.ai). We value your patience.',
+    uk_UA: 'Наша система буде недоступна з 19:00 до 24:00 UTC 28 серпня для оновлення. Якщо у вас виникнуть запитання, будь ласка, зв’яжіться з нашою службою підтримки (support@dify.ai). Дякуємо за терпіння.',
   },
   href: '#',
 }