feat(i18n): add Uzbek and Brazilian Portuguese translations (#4061)
* feat(i18n): add Uzbek (Oʻzbek) translation Adds `uz` as a first-class supported locale across the Readest app and the readest.koplugin companion. Also refactors the supported locale set to source from a single ground-truth file (`apps/readest-app/i18n-langs.json`) consumed by both the i18next runtime and the i18next-scanner config, and replaces a NUL-byte sentinel in `extract-i18n.js#unescapePo` with a single-pass regex so git no longer treats the script as binary. Closes #4053 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(i18n): add Brazilian Portuguese (pt-BR) translation Adds `pt-BR` as a regional variant supported alongside `pt`. Falls back to `pt` then `en` for any future missing keys, so European Portuguese gracefully covers gaps. Translations follow Brazilian conventions (arquivo / tela / excluir / salvar / baixar / senha, gerundive verb forms) rather than verbatim copying the European catalog. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
---
|
||||
name: i18n-koplugin
|
||||
description: >
|
||||
Extract i18n strings from readest.koplugin Lua sources and translate empty
|
||||
msgstrs in apps/readest.koplugin/locales. Use when the user invokes
|
||||
/i18n-koplugin or asks to extract/translate koplugin i18n strings.
|
||||
Runs scripts/extract-i18n.js to sync .po catalogs from `_("...")` calls,
|
||||
then fills any empty `msgstr ""` entries across all locale files.
|
||||
user_invocable: true
|
||||
---
|
||||
|
||||
Extract/translate i18n strings for `readest.koplugin`. The catalogs are gettext `.po` files (not JSON like the main app). Run from the repo root or any worktree — the script resolves paths relative to the plugin dir.
|
||||
|
||||
## Step 1: Determine the working directory
|
||||
|
||||
If currently in a PR worktree (e.g., `/Users/chrox/dev/readest-pr-*`), use that. Otherwise use the main repo. The plugin dir is `<repo-root>/apps/readest.koplugin`.
|
||||
|
||||
## Step 2: Extract msgids from Lua sources
|
||||
|
||||
```bash
|
||||
cd <repo-root>/apps/readest.koplugin
|
||||
node scripts/extract-i18n.js
|
||||
```
|
||||
|
||||
This scans every `*.lua` file under `apps/readest.koplugin/` (except `spec/` and dotdirs) for `_("...")` and `_([[...]])` calls, then for each language listed in `apps/readest-app/i18next-scanner.config.cjs`:
|
||||
|
||||
- appends new msgids with empty `msgstr ""`
|
||||
- preserves existing translations
|
||||
- drops obsolete msgids
|
||||
- rewrites the `.po` header (Plural-Forms etc.)
|
||||
|
||||
The output prints `<lang> <kept>/<total> (-<dropped> obsolete)` per locale.
|
||||
|
||||
## Step 3: Find untranslated entries
|
||||
|
||||
An untranslated entry is a non-empty `msgid` followed by an empty `msgstr ""` (the file's header pair `msgid ""` / `msgstr ""` is NOT a translation — skip it).
|
||||
|
||||
```bash
|
||||
cd <repo-root>/apps/readest.koplugin/locales
|
||||
# List locales that still have untranslated strings, with counts
|
||||
for f in */translation.po; do
|
||||
# Count empty msgstrs that follow a non-empty msgid
|
||||
n=$(awk '
|
||||
/^msgid "/ { msgid=$0; next }
|
||||
/^msgstr ""$/ { if (msgid != "msgid \"\"") c++; next }
|
||||
' "$f")
|
||||
[ "$n" -gt 0 ] && echo "$f: $n untranslated"
|
||||
done
|
||||
```
|
||||
|
||||
If no results, report that all strings are translated and stop.
|
||||
|
||||
To list the actual untranslated msgids in one locale:
|
||||
|
||||
```bash
|
||||
awk '
|
||||
/^msgid "/ { msgid=$0; next }
|
||||
/^msgstr ""$/ { if (msgid != "msgid \"\"") print msgid; next }
|
||||
' <repo-root>/apps/readest.koplugin/locales/<lang>/translation.po
|
||||
```
|
||||
|
||||
## Step 4: Translate empty msgstrs
|
||||
|
||||
For each empty `msgstr ""` found:
|
||||
|
||||
1. Read the preceding `msgid "..."` — that's the English source string.
|
||||
2. Identify the target locale from the file path (e.g., `locales/ja/translation.po` → Japanese; see table below).
|
||||
3. Provide an accurate translation. Use the locale reference table for the language; match the tone/terminology already used in the same file (check existing translated entries for context).
|
||||
4. Preserve `printf`-style placeholders verbatim: `%s`, `%d`, `%1$s`, `%(name)s`, etc.
|
||||
5. Preserve newlines as `\n`, tabs as `\t`, and escape `"` as `\"` and backslashes as `\\` inside the msgstr.
|
||||
|
||||
Edit the `.po` files directly with the Edit tool — do NOT use sed for this, because msgids may contain characters that confuse shell quoting. Each replacement should target the unique `msgid "<English>"\nmsgstr ""` block:
|
||||
|
||||
Old:
|
||||
```
|
||||
msgid "<English string>"
|
||||
msgstr ""
|
||||
```
|
||||
|
||||
New:
|
||||
```
|
||||
msgid "<English string>"
|
||||
msgstr "<translation>"
|
||||
```
|
||||
|
||||
Batch all locales for the same key together when possible — keeps the translation set consistent.
|
||||
|
||||
### Locale reference
|
||||
|
||||
The supported language set is **not hardcoded in this skill**. The ground truth is `apps/readest-app/i18n-langs.json` — both `i18next-scanner.config.cjs` (via `require`) and `src/i18n/i18n.ts` (via JSON import) source from it, and `extract-i18n.js` reads `lngs` from the scanner config at runtime. To list the current set:
|
||||
|
||||
```bash
|
||||
cat <repo-root>/apps/readest-app/i18n-langs.json
|
||||
```
|
||||
|
||||
Map each code to a language name when translating. If a code in `i18n-langs.json` is missing from the `LANG_META` table inside `extract-i18n.js`, the script prints `<code> skipped (no metadata in extract-i18n.js)` — in that case, add the metadata entry there first, then re-run extraction.
|
||||
|
||||
## Step 5: Verify
|
||||
|
||||
Re-run the count loop from Step 3 and confirm zero untranslated strings remain. Report:
|
||||
|
||||
- number of msgids extracted
|
||||
- per-locale count of strings translated
|
||||
- any locales that were already complete
|
||||
|
||||
Optionally, run the koplugin Lua tests if `busted`/`luajit` are installed:
|
||||
|
||||
```bash
|
||||
cd <repo-root>/apps/readest-app
|
||||
pnpm test:lua
|
||||
```
|
||||
@@ -41,6 +41,30 @@ pnpm i18n:extract # Scans codebase, adds new keys with __STRING_NOT_TRANSLATE
|
||||
- Translation files: `public/locales/<locale>/translation.json`
|
||||
- Only `_('KEY')` and `_('KEY', options)` patterns are recognized by i18next-scanner
|
||||
|
||||
### Adding a New Translation Language
|
||||
|
||||
The supported language set has a single ground truth: [`i18n-langs.json`](../i18n-langs.json). Both the i18next runtime (`src/i18n/i18n.ts`) and the extractor (`i18next-scanner.config.cjs`) read from it, so adding a locale is a two-file change plus a translation pass.
|
||||
|
||||
1. **Add the locale code** to [`i18n-langs.json`](../i18n-langs.json). Use the exact code i18next will emit (e.g. `hu`, `zh-CN`). Do not add `en` — it's the source language and lives outside this list.
|
||||
|
||||
2. **Add a display label** to `TRANSLATED_LANGS` in [`src/services/constants.ts`](../src/services/constants.ts). The key is the locale code, the value is the language's native name (e.g. `hu: 'Magyar'`). This is what users see in the language picker.
|
||||
|
||||
3. **Generate the translation file**:
|
||||
|
||||
```bash
|
||||
pnpm i18n:extract
|
||||
```
|
||||
|
||||
This creates `public/locales/<code>/translation.json` with every key set to `__STRING_NOT_TRANSLATED__`.
|
||||
|
||||
4. **Translate** every `__STRING_NOT_TRANSLATED__` placeholder in the new file. The `/i18n` skill automates this; the singular `en/translation.json` only holds plural variants and proper nouns, so use the JSON keys themselves as the English source.
|
||||
|
||||
5. **Verify** with `grep -r "__STRING_NOT_TRANSLATED__" public/locales/<code>/` — the result should be empty.
|
||||
|
||||
6. **Translate the KOReader companion plugin** (`apps/readest.koplugin`). It pulls the locale set from the same `i18n-langs.json` via the scanner config, but the catalog format is gettext `.po`, not JSON. Steps:
|
||||
- Add a `LANG_META` entry (label + Plural-Forms) for the new code in [`apps/readest.koplugin/scripts/extract-i18n.js`](../../readest.koplugin/scripts/extract-i18n.js). Without it the extractor prints `<code> skipped (no metadata in extract-i18n.js)` and the catalog is never created.
|
||||
- Trigger the `/i18n-koplugin` skill to run extraction and fill every empty `msgstr ""` in `apps/readest.koplugin/locales/<code>/translation.po`.
|
||||
|
||||
### Rules
|
||||
|
||||
- `stubTranslation` is for extraction only — always apply `_()` from `useTranslation` in the component for runtime translation.
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
[
|
||||
"de",
|
||||
"ja",
|
||||
"es",
|
||||
"fa",
|
||||
"fr",
|
||||
"it",
|
||||
"el",
|
||||
"ko",
|
||||
"uk",
|
||||
"nl",
|
||||
"sl",
|
||||
"sv",
|
||||
"pl",
|
||||
"pt",
|
||||
"ru",
|
||||
"tr",
|
||||
"hi",
|
||||
"id",
|
||||
"vi",
|
||||
"ms",
|
||||
"he",
|
||||
"ar",
|
||||
"th",
|
||||
"bo",
|
||||
"bn",
|
||||
"ta",
|
||||
"si",
|
||||
"ro",
|
||||
"hu",
|
||||
"uz",
|
||||
"pt-BR",
|
||||
"zh-CN",
|
||||
"zh-TW"
|
||||
]
|
||||
@@ -1,3 +1,5 @@
|
||||
const lngs = require('./i18n-langs.json');
|
||||
|
||||
const options = {
|
||||
debug: false,
|
||||
sort: false,
|
||||
@@ -5,39 +7,7 @@ const options = {
|
||||
list: ['_'],
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||||
},
|
||||
lngs: [
|
||||
'de',
|
||||
'ja',
|
||||
'es',
|
||||
'fa',
|
||||
'fr',
|
||||
'it',
|
||||
'el',
|
||||
'ko',
|
||||
'uk',
|
||||
'nl',
|
||||
'sl',
|
||||
'sv',
|
||||
'pl',
|
||||
'pt',
|
||||
'ru',
|
||||
'tr',
|
||||
'hi',
|
||||
'id',
|
||||
'vi',
|
||||
'ms',
|
||||
'he',
|
||||
'ar',
|
||||
'th',
|
||||
'bo',
|
||||
'bn',
|
||||
'ta',
|
||||
'si',
|
||||
'zh-CN',
|
||||
'zh-TW',
|
||||
'ro',
|
||||
'hu',
|
||||
],
|
||||
lngs,
|
||||
ns: ['translation'],
|
||||
defaultNs: 'translation',
|
||||
defaultValue: '__STRING_NOT_TRANSLATED__',
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,41 +1,10 @@
|
||||
import i18n from 'i18next';
|
||||
import LanguageDetector from 'i18next-browser-languagedetector';
|
||||
import translatableLngs from '../../i18n-langs.json';
|
||||
import { initReactI18next } from 'react-i18next';
|
||||
// Keep in sync with i18next-scanner.config.cjs
|
||||
const SUPPORTED_LNGS = [
|
||||
'en',
|
||||
'de',
|
||||
'ja',
|
||||
'es',
|
||||
'fa',
|
||||
'fr',
|
||||
'it',
|
||||
'el',
|
||||
'ko',
|
||||
'uk',
|
||||
'nl',
|
||||
'sl',
|
||||
'sv',
|
||||
'pl',
|
||||
'pt',
|
||||
'ru',
|
||||
'tr',
|
||||
'hi',
|
||||
'id',
|
||||
'vi',
|
||||
'ms',
|
||||
'he',
|
||||
'ar',
|
||||
'th',
|
||||
'bo',
|
||||
'bn',
|
||||
'ta',
|
||||
'si',
|
||||
'zh-CN',
|
||||
'zh-TW',
|
||||
'ro',
|
||||
'hu',
|
||||
];
|
||||
|
||||
// 'en' is the source language and not listed in the translatable set.
|
||||
const SUPPORTED_LNGS = ['en', ...translatableLngs];
|
||||
|
||||
const isBrowser = typeof window !== 'undefined';
|
||||
|
||||
@@ -52,10 +21,10 @@ const initI18n = async () => {
|
||||
supportedLngs: SUPPORTED_LNGS,
|
||||
fallbackLng: {
|
||||
'zh-HK': ['zh-TW', 'en'],
|
||||
'pt-BR': ['pt', 'en'],
|
||||
kk: ['ru', 'en'],
|
||||
ky: ['ru', 'en'],
|
||||
tk: ['ru', 'en'],
|
||||
uz: ['ru', 'en'],
|
||||
ug: ['ru', 'en'],
|
||||
tt: ['ru', 'en'],
|
||||
default: ['en'],
|
||||
|
||||
@@ -842,6 +842,7 @@ export const TRANSLATED_LANGS = {
|
||||
ko: '한국어',
|
||||
es: 'Español',
|
||||
pt: 'Português',
|
||||
'pt-BR': 'Português (Brasil)',
|
||||
ru: 'Русский',
|
||||
he: 'עברית',
|
||||
ar: 'العربية',
|
||||
@@ -864,6 +865,7 @@ export const TRANSLATED_LANGS = {
|
||||
'zh-TW': '正體中文',
|
||||
ro: 'Română',
|
||||
hu: 'Magyar',
|
||||
uz: 'Oʻzbek',
|
||||
};
|
||||
|
||||
export const TRANSLATOR_LANGS: Record<string, string> = {
|
||||
|
||||
@@ -0,0 +1,438 @@
|
||||
# Portuguese (Brazil) translation for readest.koplugin
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: readest.koplugin\n"
|
||||
"Last-Translator: Readest contributors\n"
|
||||
"Language-Team: Portuguese (Brazil)\n"
|
||||
"Language: pt-BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Readest"
|
||||
msgstr "Readest"
|
||||
|
||||
msgid "Keeps your KOReader and Readest devices in sync."
|
||||
msgstr "Mantém seus dispositivos KOReader e Readest sincronizados."
|
||||
|
||||
msgid "Library view"
|
||||
msgstr "Visualização da biblioteca"
|
||||
|
||||
msgid "View"
|
||||
msgstr "Visualizar"
|
||||
|
||||
msgid "Grid"
|
||||
msgstr "Grade"
|
||||
|
||||
msgid "List"
|
||||
msgstr "Lista"
|
||||
|
||||
msgid "Group by"
|
||||
msgstr "Agrupar por"
|
||||
|
||||
msgid "Authors"
|
||||
msgstr "Autores"
|
||||
|
||||
msgid "Books"
|
||||
msgstr "Livros"
|
||||
|
||||
msgid "Groups"
|
||||
msgstr "Grupos"
|
||||
|
||||
msgid "Series"
|
||||
msgstr "Séries"
|
||||
|
||||
msgid "Sort by"
|
||||
msgstr "Ordenar por"
|
||||
|
||||
msgid "Date Read"
|
||||
msgstr "Data de leitura"
|
||||
|
||||
msgid "Date Added"
|
||||
msgstr "Data de adição"
|
||||
|
||||
msgid "Title"
|
||||
msgstr "Título"
|
||||
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
||||
|
||||
msgid "Descending"
|
||||
msgstr "Decrescente"
|
||||
|
||||
msgid "Ascending"
|
||||
msgstr "Crescente"
|
||||
|
||||
msgid "Actions"
|
||||
msgstr "Ações"
|
||||
|
||||
msgid "Rescan library"
|
||||
msgstr "Reescanear biblioteca"
|
||||
|
||||
msgid "Download folder…"
|
||||
msgstr "Pasta de download…"
|
||||
|
||||
msgid "Pick a folder for downloaded books"
|
||||
msgstr "Escolha uma pasta para os livros baixados"
|
||||
|
||||
msgid "Sign in to Readest to open the Library"
|
||||
msgstr "Faça login no Readest para abrir a biblioteca"
|
||||
|
||||
msgid "Library"
|
||||
msgstr "Biblioteca"
|
||||
|
||||
msgid "Readest Library"
|
||||
msgstr "Biblioteca Readest"
|
||||
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
msgid "Clear"
|
||||
msgstr "Limpar"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Buscar"
|
||||
|
||||
msgid "Search library"
|
||||
msgstr "Buscar na biblioteca"
|
||||
|
||||
msgid "Search title or author"
|
||||
msgstr "Buscar título ou autor"
|
||||
|
||||
msgid "Cover Browser plugin required for full Library rendering. Falling back to plain list."
|
||||
msgstr "Plugin Cover Browser necessário para renderização completa da biblioteca. Voltando à lista simples."
|
||||
|
||||
msgid "File moved or deleted. Rescan library?"
|
||||
msgstr "Arquivo movido ou excluído. Reescanear biblioteca?"
|
||||
|
||||
msgid "Download this book from Readest?"
|
||||
msgstr "Baixar este livro do Readest?"
|
||||
|
||||
msgid "Download"
|
||||
msgstr "Baixar"
|
||||
|
||||
msgid "Set Home folder in File Manager first to enable downloads."
|
||||
msgstr "Configure primeiro a pasta inicial no Gerenciador de Arquivos para ativar os downloads."
|
||||
|
||||
msgid "Downloading…"
|
||||
msgstr "Baixando…"
|
||||
|
||||
msgid "Cloud copy unavailable."
|
||||
msgstr "Cópia na nuvem indisponível."
|
||||
|
||||
msgid "Download failed."
|
||||
msgstr "Falha no download."
|
||||
|
||||
msgid "No cover available on Readest."
|
||||
msgstr "Nenhuma capa disponível no Readest."
|
||||
|
||||
msgid "Cover download failed."
|
||||
msgstr "Falha ao baixar a capa."
|
||||
|
||||
msgid "Could not delete the file."
|
||||
msgstr "Não foi possível excluir o arquivo."
|
||||
|
||||
msgid "Removing from cloud…"
|
||||
msgstr "Removendo da nuvem…"
|
||||
|
||||
msgid "Cloud removal failed."
|
||||
msgstr "Falha na remoção da nuvem."
|
||||
|
||||
msgid "Remove from Cloud & Device"
|
||||
msgstr "Remover da nuvem e do dispositivo"
|
||||
|
||||
msgid "Remove this book from cloud and device?"
|
||||
msgstr "Remover este livro da nuvem e do dispositivo?"
|
||||
|
||||
msgid "Remove"
|
||||
msgstr "Remover"
|
||||
|
||||
msgid "Remove from Cloud Only"
|
||||
msgstr "Remover apenas da nuvem"
|
||||
|
||||
msgid "Remove this book from the cloud only?"
|
||||
msgstr "Remover este livro apenas da nuvem?"
|
||||
|
||||
msgid "Remove from Device Only"
|
||||
msgstr "Remover apenas do dispositivo"
|
||||
|
||||
msgid "Remove the local copy of this book?"
|
||||
msgstr "Remover a cópia local deste livro?"
|
||||
|
||||
msgid "Upload to Cloud"
|
||||
msgstr "Enviar para a nuvem"
|
||||
|
||||
msgid "Uploading…"
|
||||
msgstr "Enviando…"
|
||||
|
||||
msgid "Storage quota exceeded."
|
||||
msgstr "Cota de armazenamento excedida."
|
||||
|
||||
msgid "Upload failed."
|
||||
msgstr "Falha no envio."
|
||||
|
||||
msgid "Download Book"
|
||||
msgstr "Baixar livro"
|
||||
|
||||
msgid "Download Cover"
|
||||
msgstr "Baixar capa"
|
||||
|
||||
msgid "Download All"
|
||||
msgstr "Baixar tudo"
|
||||
|
||||
msgid "Open Readest Library"
|
||||
msgstr "Abrir biblioteca do Readest"
|
||||
|
||||
msgid "Push Readest book library"
|
||||
msgstr "Enviar biblioteca do Readest"
|
||||
|
||||
msgid "Pull Readest book library"
|
||||
msgstr "Obter biblioteca do Readest"
|
||||
|
||||
msgid "Set auto progress sync"
|
||||
msgstr "Definir sincronização automática do progresso"
|
||||
|
||||
msgid "on"
|
||||
msgstr "ativado"
|
||||
|
||||
msgid "off"
|
||||
msgstr "desativado"
|
||||
|
||||
msgid "Toggle auto readest sync"
|
||||
msgstr "Alternar sincronização automática do Readest"
|
||||
|
||||
msgid "Push readest progress from this device"
|
||||
msgstr "Enviar progresso do Readest deste dispositivo"
|
||||
|
||||
msgid "Pull readest progress from other devices"
|
||||
msgstr "Obter progresso do Readest de outros dispositivos"
|
||||
|
||||
msgid "Push readest annotations from this device"
|
||||
msgstr "Enviar anotações do Readest deste dispositivo"
|
||||
|
||||
msgid "Pull readest annotations from other devices"
|
||||
msgstr "Obter anotações do Readest de outros dispositivos"
|
||||
|
||||
msgid "Add to Readest"
|
||||
msgstr "Adicionar ao Readest"
|
||||
|
||||
msgid "Sign in to Readest first."
|
||||
msgstr "Faça login no Readest primeiro."
|
||||
|
||||
msgid "File not found."
|
||||
msgstr "Arquivo não encontrado."
|
||||
|
||||
msgid "Unsupported book format."
|
||||
msgstr "Formato de livro não suportado."
|
||||
|
||||
msgid "Hashing book…"
|
||||
msgstr "Calculando hash do livro…"
|
||||
|
||||
msgid "Could not read file."
|
||||
msgstr "Não foi possível ler o arquivo."
|
||||
|
||||
msgid "Already in your Readest library:"
|
||||
msgstr "Já está na sua biblioteca do Readest:"
|
||||
|
||||
msgid "Added to Readest:"
|
||||
msgstr "Adicionado ao Readest:"
|
||||
|
||||
msgid "Log in Readest Account"
|
||||
msgstr "Entrar na conta Readest"
|
||||
|
||||
msgid "Log out as %1"
|
||||
msgstr "Sair como %1"
|
||||
|
||||
msgid "Auto sync"
|
||||
msgstr "Sincronização automática"
|
||||
|
||||
msgid "Readest library"
|
||||
msgstr "Biblioteca Readest"
|
||||
|
||||
msgid "Push books now"
|
||||
msgstr "Enviar livros agora"
|
||||
|
||||
msgid "Pull books now"
|
||||
msgstr "Obter livros agora"
|
||||
|
||||
msgid "Push reading progress now"
|
||||
msgstr "Enviar progresso de leitura agora"
|
||||
|
||||
msgid "Pull reading progress now"
|
||||
msgstr "Obter progresso de leitura agora"
|
||||
|
||||
msgid "Push annotations now"
|
||||
msgstr "Enviar anotações agora"
|
||||
|
||||
msgid "Pull annotations now"
|
||||
msgstr "Obter anotações agora"
|
||||
|
||||
msgid "Full sync all annotations"
|
||||
msgstr "Sincronizar todas as anotações por completo"
|
||||
|
||||
msgid "Sync info"
|
||||
msgstr "Informações de sincronização"
|
||||
|
||||
msgid "Check for update (v%1)"
|
||||
msgstr "Verificar atualização (v%1)"
|
||||
|
||||
msgid "Check for update"
|
||||
msgstr "Verificar atualização"
|
||||
|
||||
msgid "Please login first"
|
||||
msgstr "Faça login primeiro"
|
||||
|
||||
msgid "Please configure Readest settings first"
|
||||
msgstr "Configure primeiro as definições do Readest"
|
||||
|
||||
msgid "No book is open"
|
||||
msgstr "Nenhum livro aberto"
|
||||
|
||||
msgid "(none)"
|
||||
msgstr "(nenhum)"
|
||||
|
||||
msgid "Never synced"
|
||||
msgstr "Nunca sincronizado"
|
||||
|
||||
msgid "Book Fingerprint"
|
||||
msgstr "Impressão digital do livro"
|
||||
|
||||
msgid "Identifiers"
|
||||
msgstr "Identificadores"
|
||||
|
||||
msgid "Last Synced"
|
||||
msgstr "Última sincronização"
|
||||
|
||||
msgid "Sync Info"
|
||||
msgstr "Informações de sincronização"
|
||||
|
||||
msgid "Library not initialized"
|
||||
msgstr "Biblioteca não inicializada"
|
||||
|
||||
msgid "Books synced"
|
||||
msgstr "Livros sincronizados"
|
||||
|
||||
msgid "Books sync failed"
|
||||
msgstr "Falha na sincronização de livros"
|
||||
|
||||
msgid "Checking for update…"
|
||||
msgstr "Verificando atualização…"
|
||||
|
||||
msgid "Failed to check for update. Please try again later."
|
||||
msgstr "Falha ao verificar atualização. Tente novamente mais tarde."
|
||||
|
||||
msgid "A new version is available: v%1 (current: v%2).\n\nDo you want to update now?"
|
||||
msgstr "Uma nova versão está disponível: v%1 (atual: v%2).\n\nDeseja atualizar agora?"
|
||||
|
||||
msgid "A new version is available: v%1.\n\nDo you want to update now?"
|
||||
msgstr "Uma nova versão está disponível: v%1.\n\nDeseja atualizar agora?"
|
||||
|
||||
msgid "Update"
|
||||
msgstr "Atualizar"
|
||||
|
||||
msgid "You are up to date (v%1)."
|
||||
msgstr "Você está atualizado (v%1)."
|
||||
|
||||
msgid "Downloading update…"
|
||||
msgstr "Baixando atualização…"
|
||||
|
||||
msgid "Failed to download update. Please try again later."
|
||||
msgstr "Falha ao baixar a atualização. Tente novamente mais tarde."
|
||||
|
||||
msgid "Readest plugin updated to v%1.\n\nPlease restart KOReader to apply the update."
|
||||
msgstr "Plugin Readest atualizado para v%1.\n\nReinicie o KOReader para aplicar a atualização."
|
||||
|
||||
msgid "Restart now"
|
||||
msgstr "Reiniciar agora"
|
||||
|
||||
msgid "Later"
|
||||
msgstr "Mais tarde"
|
||||
|
||||
msgid "Failed to install update: %1"
|
||||
msgstr "Falha ao instalar a atualização: %1"
|
||||
|
||||
msgid "unknown error"
|
||||
msgstr "erro desconhecido"
|
||||
|
||||
msgid "No annotations to push"
|
||||
msgstr "Sem anotações para enviar"
|
||||
|
||||
msgid "Pushing annotations..."
|
||||
msgstr "Enviando anotações..."
|
||||
|
||||
msgid "%1 annotations pushed successfully"
|
||||
msgstr "%1 anotações enviadas com sucesso"
|
||||
|
||||
msgid "Failed to push annotations"
|
||||
msgstr "Falha ao enviar as anotações"
|
||||
|
||||
msgid "Annotation sync is not supported for PDF documents"
|
||||
msgstr "A sincronização de anotações não é suportada para documentos PDF"
|
||||
|
||||
msgid "Full sync: pulling all annotations..."
|
||||
msgstr "Sincronização completa: obtendo todas as anotações..."
|
||||
|
||||
msgid "Pulling annotations..."
|
||||
msgstr "Obtendo anotações..."
|
||||
|
||||
msgid "Authentication failed, please login again"
|
||||
msgstr "Falha de autenticação, faça login novamente"
|
||||
|
||||
msgid "Failed to pull annotations"
|
||||
msgstr "Falha ao obter as anotações"
|
||||
|
||||
msgid "No new annotations found"
|
||||
msgstr "Nenhuma nova anotação encontrada"
|
||||
|
||||
msgid "%1 annotations pulled"
|
||||
msgstr "%1 anotações obtidas"
|
||||
|
||||
msgid "Login"
|
||||
msgstr "Entrar"
|
||||
|
||||
msgid "Please enter both email and password"
|
||||
msgstr "Insira o e-mail e a senha"
|
||||
|
||||
msgid "Please configure Supabase URL and API key first"
|
||||
msgstr "Configure primeiro a URL do Supabase e a chave de API"
|
||||
|
||||
msgid "Logging in..."
|
||||
msgstr "Entrando..."
|
||||
|
||||
msgid "Successfully logged in to Readest"
|
||||
msgstr "Login no Readest realizado com sucesso"
|
||||
|
||||
msgid "Login failed: %1"
|
||||
msgstr "Falha no login: %1"
|
||||
|
||||
msgid "Logged out from Readest"
|
||||
msgstr "Sessão encerrada do Readest"
|
||||
|
||||
msgid "Cannot identify the current book"
|
||||
msgstr "Não foi possível identificar o livro atual"
|
||||
|
||||
msgid "Progress has been synchronized."
|
||||
msgstr "O progresso foi sincronizado."
|
||||
|
||||
msgid "Pushing reading progress..."
|
||||
msgstr "Enviando progresso de leitura..."
|
||||
|
||||
msgid "Reading progress pushed successfully"
|
||||
msgstr "Progresso de leitura enviado com sucesso"
|
||||
|
||||
msgid "Failed to push reading progress"
|
||||
msgstr "Falha ao enviar o progresso de leitura"
|
||||
|
||||
msgid "Pulling reading progress..."
|
||||
msgstr "Obtendo progresso de leitura..."
|
||||
|
||||
msgid "Failed to pull reading progress"
|
||||
msgstr "Falha ao obter o progresso de leitura"
|
||||
|
||||
msgid "Reading progress synchronized"
|
||||
msgstr "Progresso de leitura sincronizado"
|
||||
|
||||
msgid "No saved reading progress found for this book"
|
||||
msgstr "Nenhum progresso de leitura salvo encontrado para este livro"
|
||||
@@ -0,0 +1,438 @@
|
||||
# Uzbek translation for readest.koplugin
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: readest.koplugin\n"
|
||||
"Last-Translator: Readest contributors\n"
|
||||
"Language-Team: Uzbek\n"
|
||||
"Language: uz\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Readest"
|
||||
msgstr "Readest"
|
||||
|
||||
msgid "Keeps your KOReader and Readest devices in sync."
|
||||
msgstr "KOReader va Readest qurilmalaringizni sinxronlashda saqlaydi."
|
||||
|
||||
msgid "Library view"
|
||||
msgstr "Kutubxona koʻrinishi"
|
||||
|
||||
msgid "View"
|
||||
msgstr "Koʻrinish"
|
||||
|
||||
msgid "Grid"
|
||||
msgstr "Katak"
|
||||
|
||||
msgid "List"
|
||||
msgstr "Roʻyxat"
|
||||
|
||||
msgid "Group by"
|
||||
msgstr "Guruhlash"
|
||||
|
||||
msgid "Authors"
|
||||
msgstr "Mualliflar"
|
||||
|
||||
msgid "Books"
|
||||
msgstr "Kitoblar"
|
||||
|
||||
msgid "Groups"
|
||||
msgstr "Guruhlar"
|
||||
|
||||
msgid "Series"
|
||||
msgstr "Seriya"
|
||||
|
||||
msgid "Sort by"
|
||||
msgstr "Saralash"
|
||||
|
||||
msgid "Date Read"
|
||||
msgstr "Oʻqilgan sana"
|
||||
|
||||
msgid "Date Added"
|
||||
msgstr "Qoʻshilgan sana"
|
||||
|
||||
msgid "Title"
|
||||
msgstr "Sarlavha"
|
||||
|
||||
msgid "Author"
|
||||
msgstr "Muallif"
|
||||
|
||||
msgid "Descending"
|
||||
msgstr "Kamayish boʻyicha"
|
||||
|
||||
msgid "Ascending"
|
||||
msgstr "Oʻsish boʻyicha"
|
||||
|
||||
msgid "Actions"
|
||||
msgstr "Amallar"
|
||||
|
||||
msgid "Rescan library"
|
||||
msgstr "Kutubxonani qayta skanerlash"
|
||||
|
||||
msgid "Download folder…"
|
||||
msgstr "Yuklab olish jildi…"
|
||||
|
||||
msgid "Pick a folder for downloaded books"
|
||||
msgstr "Yuklab olingan kitoblar uchun jildni tanlang"
|
||||
|
||||
msgid "Sign in to Readest to open the Library"
|
||||
msgstr "Kutubxonani ochish uchun Readest-ga kiring"
|
||||
|
||||
msgid "Library"
|
||||
msgstr "Kutubxona"
|
||||
|
||||
msgid "Readest Library"
|
||||
msgstr "Readest kutubxonasi"
|
||||
|
||||
msgid "Cancel"
|
||||
msgstr "Bekor qilish"
|
||||
|
||||
msgid "Clear"
|
||||
msgstr "Tozalash"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Qidirish"
|
||||
|
||||
msgid "Search library"
|
||||
msgstr "Kutubxonada qidirish"
|
||||
|
||||
msgid "Search title or author"
|
||||
msgstr "Sarlavha yoki muallif boʻyicha qidirish"
|
||||
|
||||
msgid "Cover Browser plugin required for full Library rendering. Falling back to plain list."
|
||||
msgstr "Toʻliq kutubxona koʻrinishi uchun Cover Browser plagini talab qilinadi. Oddiy roʻyxatga oʻtilmoqda."
|
||||
|
||||
msgid "File moved or deleted. Rescan library?"
|
||||
msgstr "Fayl koʻchirilgan yoki oʻchirilgan. Kutubxonani qayta skanerlaysizmi?"
|
||||
|
||||
msgid "Download this book from Readest?"
|
||||
msgstr "Ushbu kitobni Readest-dan yuklab olasizmi?"
|
||||
|
||||
msgid "Download"
|
||||
msgstr "Yuklab olish"
|
||||
|
||||
msgid "Set Home folder in File Manager first to enable downloads."
|
||||
msgstr "Yuklab olishlarni yoqish uchun avval Fayl menejerida bosh sahifa jildini belgilang."
|
||||
|
||||
msgid "Downloading…"
|
||||
msgstr "Yuklab olinmoqda…"
|
||||
|
||||
msgid "Cloud copy unavailable."
|
||||
msgstr "Bulutdagi nusxa mavjud emas."
|
||||
|
||||
msgid "Download failed."
|
||||
msgstr "Yuklab olib boʻlmadi."
|
||||
|
||||
msgid "No cover available on Readest."
|
||||
msgstr "Readest-da muqova mavjud emas."
|
||||
|
||||
msgid "Cover download failed."
|
||||
msgstr "Muqovani yuklab olib boʻlmadi."
|
||||
|
||||
msgid "Could not delete the file."
|
||||
msgstr "Faylni oʻchirib boʻlmadi."
|
||||
|
||||
msgid "Removing from cloud…"
|
||||
msgstr "Bulutdan olib tashlanmoqda…"
|
||||
|
||||
msgid "Cloud removal failed."
|
||||
msgstr "Bulutdan olib tashlab boʻlmadi."
|
||||
|
||||
msgid "Remove from Cloud & Device"
|
||||
msgstr "Bulut va qurilmadan olib tashlash"
|
||||
|
||||
msgid "Remove this book from cloud and device?"
|
||||
msgstr "Ushbu kitobni bulut va qurilmadan olib tashlaysizmi?"
|
||||
|
||||
msgid "Remove"
|
||||
msgstr "Olib tashlash"
|
||||
|
||||
msgid "Remove from Cloud Only"
|
||||
msgstr "Faqat bulutdan olib tashlash"
|
||||
|
||||
msgid "Remove this book from the cloud only?"
|
||||
msgstr "Ushbu kitobni faqat bulutdan olib tashlaysizmi?"
|
||||
|
||||
msgid "Remove from Device Only"
|
||||
msgstr "Faqat qurilmadan olib tashlash"
|
||||
|
||||
msgid "Remove the local copy of this book?"
|
||||
msgstr "Ushbu kitobning mahalliy nusxasini olib tashlaysizmi?"
|
||||
|
||||
msgid "Upload to Cloud"
|
||||
msgstr "Bulutga yuklash"
|
||||
|
||||
msgid "Uploading…"
|
||||
msgstr "Yuklanmoqda…"
|
||||
|
||||
msgid "Storage quota exceeded."
|
||||
msgstr "Xotira kvotasi oshib ketdi."
|
||||
|
||||
msgid "Upload failed."
|
||||
msgstr "Yuklab boʻlmadi."
|
||||
|
||||
msgid "Download Book"
|
||||
msgstr "Kitobni yuklab olish"
|
||||
|
||||
msgid "Download Cover"
|
||||
msgstr "Muqovani yuklab olish"
|
||||
|
||||
msgid "Download All"
|
||||
msgstr "Barchasini yuklab olish"
|
||||
|
||||
msgid "Open Readest Library"
|
||||
msgstr "Readest kutubxonasini ochish"
|
||||
|
||||
msgid "Push Readest book library"
|
||||
msgstr "Readest kitob kutubxonasini yuborish"
|
||||
|
||||
msgid "Pull Readest book library"
|
||||
msgstr "Readest kitob kutubxonasini olish"
|
||||
|
||||
msgid "Set auto progress sync"
|
||||
msgstr "Avtomatik jarayon sinxronlashni belgilash"
|
||||
|
||||
msgid "on"
|
||||
msgstr "yoqilgan"
|
||||
|
||||
msgid "off"
|
||||
msgstr "oʻchirilgan"
|
||||
|
||||
msgid "Toggle auto readest sync"
|
||||
msgstr "Avtomatik readest sinxronlashni ochish/yopish"
|
||||
|
||||
msgid "Push readest progress from this device"
|
||||
msgstr "Readest jarayonini ushbu qurilmadan yuborish"
|
||||
|
||||
msgid "Pull readest progress from other devices"
|
||||
msgstr "Readest jarayonini boshqa qurilmalardan olish"
|
||||
|
||||
msgid "Push readest annotations from this device"
|
||||
msgstr "Readest izohlarini ushbu qurilmadan yuborish"
|
||||
|
||||
msgid "Pull readest annotations from other devices"
|
||||
msgstr "Readest izohlarini boshqa qurilmalardan olish"
|
||||
|
||||
msgid "Add to Readest"
|
||||
msgstr "Readest-ga qoʻshish"
|
||||
|
||||
msgid "Sign in to Readest first."
|
||||
msgstr "Avval Readest-ga kiring."
|
||||
|
||||
msgid "File not found."
|
||||
msgstr "Fayl topilmadi."
|
||||
|
||||
msgid "Unsupported book format."
|
||||
msgstr "Qoʻllab-quvvatlanmaydigan kitob formati."
|
||||
|
||||
msgid "Hashing book…"
|
||||
msgstr "Kitob xeshlanmoqda…"
|
||||
|
||||
msgid "Could not read file."
|
||||
msgstr "Faylni oʻqib boʻlmadi."
|
||||
|
||||
msgid "Already in your Readest library:"
|
||||
msgstr "Allaqachon Readest kutubxonangizda:"
|
||||
|
||||
msgid "Added to Readest:"
|
||||
msgstr "Readest-ga qoʻshildi:"
|
||||
|
||||
msgid "Log in Readest Account"
|
||||
msgstr "Readest hisobiga kirish"
|
||||
|
||||
msgid "Log out as %1"
|
||||
msgstr "%1 sifatida chiqish"
|
||||
|
||||
msgid "Auto sync"
|
||||
msgstr "Avtomatik sinxronlash"
|
||||
|
||||
msgid "Readest library"
|
||||
msgstr "Readest kutubxonasi"
|
||||
|
||||
msgid "Push books now"
|
||||
msgstr "Kitoblarni hozir yuborish"
|
||||
|
||||
msgid "Pull books now"
|
||||
msgstr "Kitoblarni hozir olish"
|
||||
|
||||
msgid "Push reading progress now"
|
||||
msgstr "Oʻqish jarayonini hozir yuborish"
|
||||
|
||||
msgid "Pull reading progress now"
|
||||
msgstr "Oʻqish jarayonini hozir olish"
|
||||
|
||||
msgid "Push annotations now"
|
||||
msgstr "Izohlarni hozir yuborish"
|
||||
|
||||
msgid "Pull annotations now"
|
||||
msgstr "Izohlarni hozir olish"
|
||||
|
||||
msgid "Full sync all annotations"
|
||||
msgstr "Barcha izohlarni toʻliq sinxronlash"
|
||||
|
||||
msgid "Sync info"
|
||||
msgstr "Sinxronlash maʼlumoti"
|
||||
|
||||
msgid "Check for update (v%1)"
|
||||
msgstr "Yangilanishni tekshirish (v%1)"
|
||||
|
||||
msgid "Check for update"
|
||||
msgstr "Yangilanishni tekshirish"
|
||||
|
||||
msgid "Please login first"
|
||||
msgstr "Iltimos, avval tizimga kiring"
|
||||
|
||||
msgid "Please configure Readest settings first"
|
||||
msgstr "Iltimos, avval Readest sozlamalarini sozlang"
|
||||
|
||||
msgid "No book is open"
|
||||
msgstr "Hech qanday kitob ochilmagan"
|
||||
|
||||
msgid "(none)"
|
||||
msgstr "(yoʻq)"
|
||||
|
||||
msgid "Never synced"
|
||||
msgstr "Sinxronlanmagan"
|
||||
|
||||
msgid "Book Fingerprint"
|
||||
msgstr "Kitob barmoq izi"
|
||||
|
||||
msgid "Identifiers"
|
||||
msgstr "Identifikatorlar"
|
||||
|
||||
msgid "Last Synced"
|
||||
msgstr "Oxirgi sinxronlash"
|
||||
|
||||
msgid "Sync Info"
|
||||
msgstr "Sinxronlash maʼlumoti"
|
||||
|
||||
msgid "Library not initialized"
|
||||
msgstr "Kutubxona ishga tushirilmagan"
|
||||
|
||||
msgid "Books synced"
|
||||
msgstr "Kitoblar sinxronlandi"
|
||||
|
||||
msgid "Books sync failed"
|
||||
msgstr "Kitoblarni sinxronlab boʻlmadi"
|
||||
|
||||
msgid "Checking for update…"
|
||||
msgstr "Yangilanishlar tekshirilmoqda…"
|
||||
|
||||
msgid "Failed to check for update. Please try again later."
|
||||
msgstr "Yangilanishni tekshirib boʻlmadi. Keyinroq qayta urinib koʻring."
|
||||
|
||||
msgid "A new version is available: v%1 (current: v%2).\n\nDo you want to update now?"
|
||||
msgstr "Yangi versiya mavjud: v%1 (joriy: v%2).\n\nHozir yangilamoqchimisiz?"
|
||||
|
||||
msgid "A new version is available: v%1.\n\nDo you want to update now?"
|
||||
msgstr "Yangi versiya mavjud: v%1.\n\nHozir yangilamoqchimisiz?"
|
||||
|
||||
msgid "Update"
|
||||
msgstr "Yangilash"
|
||||
|
||||
msgid "You are up to date (v%1)."
|
||||
msgstr "Sizda eng songgi versiya (v%1)."
|
||||
|
||||
msgid "Downloading update…"
|
||||
msgstr "Yangilanish yuklanmoqda…"
|
||||
|
||||
msgid "Failed to download update. Please try again later."
|
||||
msgstr "Yangilanishni yuklab boʻlmadi. Keyinroq qayta urinib koʻring."
|
||||
|
||||
msgid "Readest plugin updated to v%1.\n\nPlease restart KOReader to apply the update."
|
||||
msgstr "Readest plagini v%1 ga yangilandi.\n\nYangilanishni qoʻllash uchun KOReader-ni qayta ishga tushiring."
|
||||
|
||||
msgid "Restart now"
|
||||
msgstr "Hozir qayta ishga tushirish"
|
||||
|
||||
msgid "Later"
|
||||
msgstr "Keyinroq"
|
||||
|
||||
msgid "Failed to install update: %1"
|
||||
msgstr "Yangilanishni oʻrnatib boʻlmadi: %1"
|
||||
|
||||
msgid "unknown error"
|
||||
msgstr "nomaʼlum xato"
|
||||
|
||||
msgid "No annotations to push"
|
||||
msgstr "Yuborish uchun izohlar yoʻq"
|
||||
|
||||
msgid "Pushing annotations..."
|
||||
msgstr "Izohlar yuborilmoqda..."
|
||||
|
||||
msgid "%1 annotations pushed successfully"
|
||||
msgstr "%1 ta izoh muvaffaqiyatli yuborildi"
|
||||
|
||||
msgid "Failed to push annotations"
|
||||
msgstr "Izohlarni yuborib boʻlmadi"
|
||||
|
||||
msgid "Annotation sync is not supported for PDF documents"
|
||||
msgstr "PDF hujjatlar uchun izoh sinxronlash qoʻllab-quvvatlanmaydi"
|
||||
|
||||
msgid "Full sync: pulling all annotations..."
|
||||
msgstr "Toʻliq sinxronlash: barcha izohlar olinmoqda..."
|
||||
|
||||
msgid "Pulling annotations..."
|
||||
msgstr "Izohlar olinmoqda..."
|
||||
|
||||
msgid "Authentication failed, please login again"
|
||||
msgstr "Autentifikatsiya muvaffaqiyatsiz tugadi, qayta tizimga kiring"
|
||||
|
||||
msgid "Failed to pull annotations"
|
||||
msgstr "Izohlarni olib boʻlmadi"
|
||||
|
||||
msgid "No new annotations found"
|
||||
msgstr "Yangi izohlar topilmadi"
|
||||
|
||||
msgid "%1 annotations pulled"
|
||||
msgstr "%1 ta izoh olindi"
|
||||
|
||||
msgid "Login"
|
||||
msgstr "Kirish"
|
||||
|
||||
msgid "Please enter both email and password"
|
||||
msgstr "Iltimos, email va parolni kiriting"
|
||||
|
||||
msgid "Please configure Supabase URL and API key first"
|
||||
msgstr "Iltimos, avval Supabase URL va API kalitini sozlang"
|
||||
|
||||
msgid "Logging in..."
|
||||
msgstr "Tizimga kirilmoqda..."
|
||||
|
||||
msgid "Successfully logged in to Readest"
|
||||
msgstr "Readest-ga muvaffaqiyatli kirildi"
|
||||
|
||||
msgid "Login failed: %1"
|
||||
msgstr "Kirish muvaffaqiyatsiz tugadi: %1"
|
||||
|
||||
msgid "Logged out from Readest"
|
||||
msgstr "Readest-dan chiqildi"
|
||||
|
||||
msgid "Cannot identify the current book"
|
||||
msgstr "Joriy kitobni aniqlab boʻlmadi"
|
||||
|
||||
msgid "Progress has been synchronized."
|
||||
msgstr "Jarayon sinxronlandi."
|
||||
|
||||
msgid "Pushing reading progress..."
|
||||
msgstr "Oʻqish jarayoni yuborilmoqda..."
|
||||
|
||||
msgid "Reading progress pushed successfully"
|
||||
msgstr "Oʻqish jarayoni muvaffaqiyatli yuborildi"
|
||||
|
||||
msgid "Failed to push reading progress"
|
||||
msgstr "Oʻqish jarayonini yuborib boʻlmadi"
|
||||
|
||||
msgid "Pulling reading progress..."
|
||||
msgstr "Oʻqish jarayoni olinmoqda..."
|
||||
|
||||
msgid "Failed to pull reading progress"
|
||||
msgstr "Oʻqish jarayonini olib boʻlmadi"
|
||||
|
||||
msgid "Reading progress synchronized"
|
||||
msgstr "Oʻqish jarayoni sinxronlandi"
|
||||
|
||||
msgid "No saved reading progress found for this book"
|
||||
msgstr "Ushbu kitob uchun saqlangan oʻqish jarayoni topilmadi"
|
||||
Binary file not shown.
Reference in New Issue
Block a user