From b4bfe2b2b5a6fa08207f81e0bba2536f05117ecd Mon Sep 17 00:00:00 2001 From: qwerin Date: Fri, 16 Oct 2026 06:27:52 +0200 Subject: [PATCH] M14: complete and review the Czech catalog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Czech had every `tl!` literal but lacked ~220 keys the other catalogs carry: the sentences the engine words (signature details, accessibility findings and report, PDF/A problems, pages to print, history labels), the date picker's weekday heads, the certificate viewer's fields and shared buttons. All are now translated (2,674 entries). "Tag" is "tag" throughout, as the catalog's own glossary says: the Tags panel said "značky", which also names redaction marks, and "{n} tags" read "1 značek". Two new tests pin the engine wordings (with their holes), weekdays and certificate fields; both fail on the previous catalog. Co-Authored-By: Claude Opus 5.5 --- ATTRIBUTION.toml | 2 +- ROADMAP.md | 5 +- crates/ui-egui/src/i18n/cs.tsv | 269 ++++++++++++++++++++++++++++++--- crates/ui-egui/src/i18n/mod.rs | 64 ++++++++ docs/localization-parity.md | 5 +- docs/localization.md | 6 +- docs/roadmap.md | 6 +- 7 files changed, 326 insertions(+), 31 deletions(-) diff --git a/ATTRIBUTION.toml b/ATTRIBUTION.toml index db3dd6124..08f7341f2 100644 --- a/ATTRIBUTION.toml +++ b/ATTRIBUTION.toml @@ -52,7 +52,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Czech UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "5de19834f293efaea68cb6b7f51a71d320391f53345f56cfebcd73dab828b665" +sha256 = "315dcb83e419afbde61617d5d16c8338aee6eebefd4d853dc16d8b49f86e3320" [[asset]] path = "crates/ui-egui/src/i18n/pt-br.tsv" diff --git a/ROADMAP.md b/ROADMAP.md index 907beb98a..aba21f369 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -15,6 +15,7 @@ > **Last reviewed:** 2026-10-13 · **Last updated:** 2026-10-13 · **Change:** minor (M6: preserve XML/XFDF attribute whitespace; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) > **Last reviewed:** 2026-10-14 · **Last updated:** 2026-10-14 · **Change:** minor (M1: raw-deflate fallback preserves decoding-limit errors; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) > **Last reviewed:** 2026-10-16 | **Last updated:** 2026-10-16 | **Change:** minor (M10 #1201 partial: lossless image Decode; estimates unchanged) | **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) +> **Last reviewed:** 2026-10-15 · **Last updated:** 2026-10-16 · **Change:** minor (M14: Czech catalog completed and reviewed; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) > **Last reviewed:** 2026-10-13 · **Last updated:** 2026-10-14 · **Change:** minor (M14: the Italian catalog has every entry the other catalogs had and the code looks up; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) > **Last reviewed:** 2026-10-14 · **Last updated:** 2026-10-14 · **Change:** minor (M3 #2080 candidate: explicit search jumps join per-tab history; rail and control-channel Back/Forward; estimates unchanged) > **Last reviewed:** 2026-10-13 · **Last updated:** 2026-10-13 · **Change:** minor (M4 #1910: Organize Pages opens on the current page; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) @@ -149,7 +150,7 @@ union). Detail and script notes: [localization-parity.md](docs/localization-pari | Vietnamese | `vi` | 100% of current union | partial (dialogs / tooltips; no help) | Also shipped: Traditional Chinese, Russian, Bulgarian, Telugu, Hungarian, Ukrainian, Italian, -Kazakh, Polish, Slovenian, Greek, Turkish, Lithuanian and Czech (menus only): **14 more catalogs** +Kazakh, Polish, Slovenian, Greek, Turkish, Lithuanian and Czech: **14 more catalogs** (23 interface languages including English). ## Upcoming @@ -183,6 +184,7 @@ Ranked; detail and the full milestone table in [docs/roadmap.md](docs/roadmap.md - **2026-10-15 (M1, #2267 refresh):** Integrated upstream `99941daa` while retaining the raw-deflate fallback correction and all upstream progress. Only independent documentation conflicts required resolution; focused production and test files are unchanged from the previously green CI head. Estimates unchanged. - **2026-10-16 (M10, #1201 partial):** Lossless image export applies each component's Decode pair. Indexed values round and clip before palette lookup. Color-key masks keep raw samples. The existing 16-bit precision limit remains. JPEG and mask Decode, ICC transforms, and calibrated colors remain outside this fix. Estimates unchanged. - **2026-10-16 (M3, #2739):** Wrapped revision buttons stay above Binding in Document Properties. A synthetic regression checks control bounds and opens a saved revision at two viewport widths. Estimates unchanged. +- **2026-10-16 (M14, localization):** Czech goes from menus-and-dialogs to the whole surface: 2,674 entries after adding the ~220 keys the other catalogs had -- the sentences the engine words (signature details, accessibility findings and report, PDF/A problems, pages to print, history labels), the date picker's weekday heads, the certificate viewer's fields and shared buttons. "Tag" is *tag* throughout (the Tags panel said *značky*, which is also a redaction mark), and "{n} tags" no longer reads "1 značek". Two new catalog tests. Estimates unchanged. - **2026-10-15 (M2, gap 12):** `cargo xtask text-oracle` scores reading order as well as word F1: the longest common subsequence of the two word sequences over the longer one. F1 is a bag of words and cannot see order at all -- measuring #2431, a change that moves text and nothing else, it called 26 of the 29 files whose output changed identical, where the order score separated 18 improvements from 6 regressions. Reports, does not gate; a disagreement with Poppler, not a verdict. Estimates unchanged. - **2026-10-15 (M2, #2305 follow-up):** WinAnsiEncoding 0xA0 and 0xAD and MacRomanEncoding 0xCA extract as the ordinary space and hyphen Annex D.2 names them, in the vendored hayro tables (patch 30) as well as `crates/fonts`, so search, copy and redaction see characters that were hidden behind U+00A0 and U+00AD. Across the pdf.js corpus the soft hyphens we extract fall 117 to 13 and the non-breaking spaces 30 to 26; the rest come from `/ToUnicode`. An explicit `/Differences` name keeps its glyph list value, as pdftotext does. Estimates unchanged. - **2026-10-15 (M12, XFA, #2574):** A `pageArea` with no `` repeats without limit instead of taking a subform's default of one use, so a later page area with `occur max="1"` is no longer drawn (with a copy of its fields) over every body page. A page area's `occur min` is honoured too: one the body never reached gets the pages it still needs after the body (the once-only closing page of the public ISCIII form, with its button, is page 7 of 7). Acrobat Pro shows the form as 7 pages with that page last, as here; when printing, Acrobat keeps that page but leaves it blank (`relevant="-print"` on the page area), which PdfCraft does not do yet. Synthetic regression tests. Estimates unchanged. @@ -539,6 +541,7 @@ Newest first: the date, what moved, and the new overall estimate. | 2026-10-15 | minor | M6: Plain AcroForm XML imports retain all direct text around comments and processing instructions, including CDATA and character references. Estimates unchanged. | | 2026-10-13 | minor | M6: XML/XFDF attribute whitespace survives form and comment export/import; estimates unchanged | | 2026-10-14 | minor | M1: raw-deflate fallback preserves decoding-limit errors in strict and tolerant decoding; synthetic filter and COS stream regressions. Estimates unchanged. | +| 2026-10-16 | minor | M14: Czech catalog completed (2,674 entries) and "tag" terminology unified. Estimates unchanged. | | 2026-10-13 | minor | M9: separate page validation overlays preserve signature artwork, and snapshot tabs reuse instead of multiplying; baked captions remain unchanged (#79 open); estimates unchanged | | 2026-10-16 | minor | M10 #1201 partial: lossless image export applies component Decode pairs and Indexed mapping. Estimates unchanged. | | 2026-10-15 | minor | M6: CSV export and spreadsheet merging quote tabs, and import distinguishes quoted tabs from TSV delimiters without changing field identities. Estimates unchanged. | diff --git a/crates/ui-egui/src/i18n/cs.tsv b/crates/ui-egui/src/i18n/cs.tsv index 993632552..7a614e11d 100644 --- a/crates/ui-egui/src/i18n/cs.tsv +++ b/crates/ui-egui/src/i18n/cs.tsv @@ -2396,20 +2396,20 @@ animation effects Off Vypnuto Couldn't print from the browser ({e}); downloaded {name} to print instead Z prohlížeče nelze tisknout ({e}); místo toho byl k tisku stažen soubor {name} Tools panel side Strana panelu nástrojů Add comment Přidat komentář - Change tag properties Změnit vlastnosti značky + Change tag properties Změnit vlastnosti tagu # Accessibility structure tags. - Tags panel Panel značek - Tags Značky - Tag type Typ značky + Tags panel Panel tagů + Tags Tagy + Tag type Typ tagu Actual text Skutečný text - Find a tag Najít značku - Collapse tag Sbalit značku - Expand tag Rozbalit značku + Find a tag Najít tag + Collapse tag Sbalit tag + Expand tag Rozbalit tag Revert changes Vrátit změny - Save tag properties Uložit vlastnosti značky - This document has no editable structure tags. Tento dokument nemá upravitelné značky struktury. - {n} tags {n} značek - Save or revert changes before selecting another tag. Před výběrem jiné značky změny uložte nebo vraťte. + Save tag properties Uložit vlastnosti tagu + This document has no editable structure tags. Tento dokument nemá žádné upravitelné tagy struktury. + {n} tags Tagy: {n} + Save or revert changes before selecting another tag. Před výběrem jiného tagu změny uložte nebo vraťte. Left out: {names} Vynecháno: {names} already a PDF již je PDF no unused output name žádný volný název výstupního souboru @@ -2454,8 +2454,8 @@ animation effects Off Vypnuto Not now Teď ne Open this local PDF? Otevřít tento místní soubor PDF? This document is trying to open a local file: Tento dokument se pokouší otevřít místní soubor: - Move tag earlier Přesunout značku dříve - Move tag later Přesunout značku později + Move tag earlier Přesunout tag dříve + Move tag later Přesunout tag později # Historical snapshot notice bar (View signed version / View revision). You are viewing the signed version of “{from}” (revision {rev}). It is a snapshot: changes here won't affect the original. Prohlížíte si podepsanou verzi dokumentu „{from}“ (revize {rev}). Je to snímek: změny zde neovlivní originál. @@ -2463,19 +2463,19 @@ animation effects Off Vypnuto Turn upside down (180°) Otočit vzhůru nohama (180°) 4 x 6 in label (101.6 x 152.4 mm) Štítek 4 × 6 in (101,6 × 152,4 mm) Cuts each page to its printed area, turns it upright and fits it to the sheet without stretching. One label per sheet. Ořízne každou stránku na potištěnou oblast, otočí ji svisle a přizpůsobí listu bez deformace. Jeden štítek na list. - Find untagged content Najít neoznačený obsah - No untagged content was found. Nebyl nalezen žádný neoznačený obsah. - Found {n} untagged content problems. Nalezeno problémů s neoznačeným obsahem: {n}. - Tag form fields Označit pole formuláře + Find untagged content Najít neoznačkovaný obsah + No untagged content was found. Nebyl nalezen žádný neoznačkovaný obsah. + Found {n} untagged content problems. Nalezeno problémů s neoznačkovaným obsahem: {n}. + Tag form fields Označkovat formulářová pole Mark as artifact Označit jako artefakt - Remove this leaf tag from reading order and mark its direct content as an artifact Odeberte tuto značku listu z pořadí čtení a označte její přímý obsah jako artefakt + Remove this leaf tag from reading order and mark its direct content as an artifact Odebrat tento koncový tag z pořadí čtení a jeho přímý obsah označit jako artefakt Mark content as artifact Označit obsah jako artefakt Word count Počet slov Current page only Pouze aktuální stránka - Exclude tagged tables Vynechat označené tabulky - Exclude tagged code blocks Vynechat označené bloky kódu + Exclude tagged tables Vynechat označkované tabulky + Exclude tagged code blocks Vynechat označkované bloky kódu Exclude image/OCR text Vynechat text obrázků a OCR - Exclusions use PDF tags. Untagged tables and code remain included. Image exclusion also removes invisible text. Vynechávání využívá tagy PDF. Neoznačené tabulky a kód zůstávají zahrnuty. Vynechání obrázků odstraní i neviditelný text. + Exclusions use PDF tags. Untagged tables and code remain included. Image exclusion also removes invisible text. Vynechávání využívá tagy PDF. Neoznačkované tabulky a kód zůstávají zahrnuty. Vynechání obrázků odstraní i neviditelný text. Words Slova Characters Znaky Characters without spaces Znaky bez mezer @@ -2508,3 +2508,230 @@ animation effects Off Vypnuto Make properties default Nastavit vlastnosti jako výchozí Pages selected Vybrané stránky Page properties Vlastnosti stránky + +# What the layers below word for themselves (engine `WORDINGS` lists): accessibility findings and +# the saved report, PDF/A problems, signature details and the changes they name, pages to print, +# history labels. Terms: timestamp = "časové razítko", timestamp authority = "autorita časových +# razítek", signer = "podepisující osoba", byte range = "rozsah bajtů". + A font isn't embedded Písmo není vložené + A {} action isn't allowed Akce {} není povolena + A {} annotation has additional actions Anotace {} má další akce + A {} annotation has no appearance stream Anotace {} nemá datový proud vzhledu + A {} annotation isn't set to print, or is hidden Anotace {} není nastavena k tisku nebo je skrytá + Accessibility Report Zpráva o přístupnosti + Change Author Změnit: Autor + Change Keywords Změnit: Klíčová slova + Change Subject Změnit: Předmět + Change Title Změnit: Název + Create links Vytvořit odkazy + Detailed Report Podrobná zpráva + DeviceCMYK is used, but the PDF/A output intent isn't a CMYK profile Je použit DeviceCMYK, ale výstupní záměr PDF/A není profil CMYK + DeviceRGB is used, but the PDF/A output intent isn't an RGB profile Je použit DeviceRGB, ale výstupní záměr PDF/A není profil RGB + Field "{}" on page {p} has no description (tooltip) Pole „{}“ na stránce {p} nemá popis (popisek nástroje) + Filename Název souboru + Flatten Fill & Sign Sloučit Vyplnit a podepsat se stránkou + Font (unnamed) on page {p} doesn't map its characters to Unicode Písmo (bez názvu) na stránce {p} nemapuje své znaky na Unicode + Font {} on page {p} doesn't map its characters to Unicode Písmo {} na stránce {p} nemapuje své znaky na Unicode + Form field on page {p} isn't tagged Formulářové pole na stránce {p} není označkované + H{n} follows an H{d}; headings should not skip levels H{n} následuje po H{d}; nadpisy by neměly přeskakovat úrovně + No document language is set Není nastaven jazyk dokumentu + No page has text: the document appears to be images of pages Žádná stránka nemá text: dokument se zdá být tvořen obrázky stránek + Page {p} doesn't tab in structure order Stránka {p} nepřechází tabulátorem v pořadí struktury + Page {p}: {n} untagged content item Stránka {p}: neoznačkované položky obsahu: {n} + Page {p}: {n} untagged content items Stránka {p}: neoznačkované položky obsahu: {n} + Page {} has additional actions Stránka {} má další akce + PdfCraft can't check this signature yet: {}. PdfCraft zatím nedokáže tento podpis ověřit: {}. + Report created Zpráva vytvořena + Rule Name Název pravidla + Save as {level} Uložit jako {level} + Signature is invalid Podpis je neplatný + Signature is valid Podpis je platný + Signature validity is unknown Platnost podpisu je neznámá + Signing time is from the clock on the signer's computer. Čas podpisu pochází z hodin v počítači podepisující osoby. + The ECDSA signature is not in canonical DER (trailing bytes, padding or a missing sign byte); it was read anyway. Podpis ECDSA není v kanonickém DER (přebytečné bajty, výplň nebo chybějící bajt znaménka); přesto byl načten. + The ECDSA signature is the raw r and s values instead of a DER sequence; it was read anyway. Podpis ECDSA tvoří holé hodnoty r a s místo sekvence DER; přesto byl načten. + The RSA signature value does not have the length of the key's modulus (leading zero bytes dropped or added); it was read anyway. Hodnota podpisu RSA nemá délku modulu klíče (úvodní nulové bajty chybí nebo přebývají); přesto byla načtena. + The RSA signature's DigestInfo has no NULL parameter (older signers write it so); it was read anyway. DigestInfo podpisu RSA nemá parametr NULL (starší podepisovací programy jej tak zapisují); přesto byl načten. + The certificate of {} does not allow this many CA certificates below it (path length), so it is not used to vouch for {}. Certifikát {} nepovoluje pod sebou tolik certifikátů CA (délka cesty), proto se nepoužije k ručení za {}. + The certificate of {} is not a CA certificate that may issue certificates, so it is not used to vouch for {}. Certifikát {} není certifikát CA, který smí vydávat certifikáty, proto se nepoužije k ručení za {}. + The certificate of {} was not valid at the time of signing, so it is not used to vouch for {}. Certifikát {} nebyl v době podpisu platný, proto se nepoužije k ručení za {}. + The checker found problems which may prevent the document from being fully accessible. Kontrola našla problémy, které mohou bránit plné přístupnosti dokumentu. + The document has been altered or corrupted since the signature was applied. Dokument byl od připojení podpisu změněn nebo poškozen. + The document has been altered or corrupted since the timestamp was applied. Dokument byl od připojení časového razítka změněn nebo poškozen. + The document has been altered since this signature was applied in ways it does not permit ({}). Dokument byl od připojení tohoto podpisu změněn způsobem, který podpis nepovoluje ({}). + The document has been altered since this timestamp was applied in ways it does not permit ({}). Dokument byl od připojení tohoto časového razítka změněn způsobem, který razítko nepovoluje ({}). + The document has been modified since this signature was applied, but the changes are permitted ({}). Dokument byl od připojení tohoto podpisu upraven, ale změny jsou povolené ({}). + The document has been modified since this timestamp was applied, but the changes are permitted ({}). Dokument byl od připojení tohoto časového razítka upraven, ale změny jsou povolené ({}). + The document has no tags (structure tree) Dokument nemá tagy (strom struktury) + The document has no title Dokument nemá název + The document isn't marked as tagged (MarkInfo Marked) Dokument není označen jako označkovaný (MarkInfo Marked) + The document isn't tagged, so none of its content is Dokument není označkovaný, a tak není označkovaný ani žádný jeho obsah + The document's embedded revocation information shows that the signer's certificate has not been revoked. Informace o odvolání vložené v dokumentu ukazují, že certifikát podepisující osoby nebyl odvolán. + The embedded timestamp token is valid and its authority is trusted; trusted time is {}. Vložené časové razítko je platné a jeho autorita je důvěryhodná; důvěryhodný čas je {}. + The font {} isn't embedded Písmo {} není vložené + The metadata doesn't identify the file as {} Metadata neoznačují soubor jako {} + The security settings don't allow screen readers to read the text Nastavení zabezpečení nedovoluje čtečkám obrazovky číst text + The signature algorithm and the SignerInfo's digest algorithm name different hashes; the signature was made with the SignerInfo's. Algoritmus podpisu a algoritmus otisku v SignerInfo uvádějí různé hashe; podpis byl vytvořen tím ze SignerInfo. + The signature carries an unverified timestamp ({}): the timestamp authority is not in your list of trusted certificates, so the signing time claimed by the signer is used instead. Podpis nese neověřené časové razítko ({}): autorita časových razítek není ve vašem seznamu důvěryhodných certifikátů, proto se místo něj použije čas podpisu uvedený podepisující osobou. + The signature contents are not hexadecimal. Obsah podpisu není šestnáctkový. + The signature could not be checked ({}). Podpis nebylo možné zkontrolovat ({}). + The signature could not be read ({}). Podpis nebylo možné načíst ({}). + The signature could not be verified ({}). Podpis nebylo možné ověřit ({}). + The signature has no valid byte range. Podpis nemá platný rozsah bajtů. + The signature includes an embedded timestamp. Podpis obsahuje vložené časové razítko. + The signature is BER-encoded (indefinite lengths) rather than DER; it was read leniently. Podpis je kódován v BER (neurčité délky) místo DER; byl načten benevolentně. + The signature uses the legacy adbe.x509.rsa_sha1 format. Podpis používá zastaralý formát adbe.x509.rsa_sha1. + The signature value does not match the signer's certificate: the signature is corrupt. Hodnota podpisu neodpovídá certifikátu podepisující osoby: podpis je poškozený. + The signature's byte range does not exclude exactly its contents. Rozsah bajtů podpisu nevynechává přesně jeho obsah. + The signature's byte range does not match the file. Rozsah bajtů podpisu neodpovídá souboru. + The signature's timestamp token could not be verified ({}). Časové razítko podpisu nebylo možné ověřit ({}). + The signature's timestamp token does not cover the signature value. Časové razítko podpisu nepokrývá hodnotu podpisu. + The signed content is a constructed (segmented) OCTET STRING, as BER allows; it was read anyway. Podepsaný obsah je složený (segmentovaný) OCTET STRING, jak BER dovoluje; přesto byl načten. + The signer's certificate does not allow digital signatures (its key usage has neither digital signature nor non-repudiation). Certifikát podepisující osoby nepovoluje digitální podpisy (jeho použití klíče nezahrnuje digitální podpis ani nepopiratelnost). + The signer's certificate has been revoked ({}). Certifikát podepisující osoby byl odvolán ({}). + The signer's certificate has critical extensions PdfCraft does not recognize ({}). Certifikát podepisující osoby má kritická rozšíření, která PdfCraft nezná ({}). + The signer's certificate is not in the signature. Certifikát podepisující osoby není v podpisu. + The signer's certificate is not issued for signing documents (its extended key usage has no document-signing purpose). Certifikát podepisující osoby není vydán k podepisování dokumentů (jeho rozšířené použití klíče nezahrnuje podepisování dokumentů). + The signer's certificate was not valid at the time of signing. Certifikát podepisující osoby nebyl v době podpisu platný. + The signer's identity is unknown because it has not been included in your list of trusted certificates and none of its parent certificates are trusted certificates. Identita podepisující osoby je neznámá, protože není ve vašem seznamu důvěryhodných certifikátů a žádný z jejích nadřazených certifikátů není důvěryhodný. + The signer's identity is valid. Identita podepisující osoby je platná. + The timestamp authority's certificate was not valid at the time of timestamping. Certifikát autority časových razítek nebyl v době vystavení razítka platný. + The timestamp contents are not hexadecimal. Obsah časového razítka není šestnáctkový. + The timestamp has no valid byte range. Časové razítko nemá platný rozsah bajtů. + The timestamp token could not be read ({}). Časové razítko nebylo možné načíst ({}). + The timestamp token is valid and its authority is trusted. Časové razítko je platné a jeho autorita je důvěryhodná. + The timestamp token is valid, but the timestamp authority is not in your list of trusted certificates. Časové razítko je platné, ale autorita časových razítek není ve vašem seznamu důvěryhodných certifikátů. + The timestamp's byte range does not exclude exactly its contents. Rozsah bajtů časového razítka nevynechává přesně jeho obsah. + The timestamp's byte range does not match the file. Rozsah bajtů časového razítka neodpovídá souboru. + The window shows the file name, not the title (Initial View > Show) Okno zobrazuje název souboru, ne název dokumentu (Počáteční zobrazení > Zobrazit) + This document has not been modified since this signature was applied. Tento dokument nebyl od připojení tohoto podpisu upraven. + This document has not been modified since this timestamp was applied. Tento dokument nebyl od připojení tohoto časového razítka upraven. + This signature uses RIPEMD-160, a legacy 160-bit hash algorithm that is no longer recommended for signatures. It still validates, but it should not be relied on. Tento podpis používá RIPEMD-160, zastaralý 160bitový hashovací algoritmus, který se už pro podpisy nedoporučuje. Podpis se stále ověří, ale nelze na něj spoléhat. + This signature uses SHA-1, a weak hash algorithm: collisions in it have been demonstrated. It still validates because many documents signed years ago use it, but it should not be relied on. Tento podpis používá SHA-1, slabý hashovací algoritmus, u kterého byly prokázány kolize. Stále se ověří, protože jej používá mnoho dokumentů podepsaných před lety, ale nelze na něj spoléhat. + Unsigned signature field Nepodepsané podpisové pole + alternate text hides an annotation inside it alternativní text skrývá anotaci uvnitř + alternate text on an element with no page content alternativní text u prvku bez obsahu stránky + comments komentáře + document security store úložiště zabezpečení dokumentu + document structure struktura dokumentu + form fill vyplnění formuláře + its alternate text is inside another element's and will never be read jeho alternativní text je uvnitř alternativního textu jiného prvku a nikdy nebude přečten + links odkazy + metadata metadata + no alternate text chybí alternativní text + no header cells (TH) chybí buňky záhlaví (TH) + no summary chybí souhrn + not in a TR není v TR + not in a Table, THead, TBody or TFoot není v Table, THead, TBody ani TFoot + not in an L (list) není v L (seznam) + not in an LI (list item) není v LI (položka seznamu) + other changes jiné změny + page content obsah stránek + page {n} is out of range (1–{count}) stránka {n} je mimo rozsah (1–{count}) + pages added or removed přidané nebo odebrané stránky + rows have between {min} and {max} columns řádky mají {min} až {max} sloupců + the first heading is an H{n}; headings should not skip levels první nadpis je H{n}; nadpisy by neměly přeskakovat úrovně + the signed version could not be read podepsanou verzi nebylo možné načíst + {n} pages and no bookmarks Počet stránek: {n}, žádné záložky + {page} is not a page number or label {page} není číslo ani označení stránky + {ty} element on page {p}: {what} Prvek {ty} na stránce {p}: {what} + {ty} element: {what} Prvek {ty}: {what} + {} annotation on page {p} isn't tagged Anotace {} na stránce {p} není označkovaná + {} annotations aren't allowed Anotace {} nejsou povoleny + … and {n} more … a další ({n}) + +# Labels other catalogs carry (shared buttons, tooltips with key caps, the folder picker). + on page {label} na stránce {label} + of z + Add the PDFs to combine Přidejte soubory PDF ke sloučení + Added the first {n} PDFs in {folder} Přidány první soubory PDF ze složky {folder} (počet: {n}) + Always Vždy + Automatically Automaticky + Choose a file… Vybrat soubor… + Choose a folder… Vybrat složku… + Choose… Vybrat… + Color Barva + Comment Komentář + Comment and review Komentovat a revidovat + Copied to clipboard Zkopírováno do schránky + Copy to clipboard Kopírovat do schránky + Create folder Vytvořit složku + Disabled Vypnuto + Document properties (⌘D) Vlastnosti dokumentu (⌘D) + Drop PDFs or folders here, or choose them. Přetáhněte sem soubory PDF nebo složky, nebo je vyberte. + Duplicate Duplikovat + Enabled Zapnuto + Error Chyba + Every PDF in the folder Všechny soubory PDF ve složce + Every PDF in the folder and the folders inside it Všechny soubory PDF ve složce a jejích podsložkách + Folder Složka + Font Písmo + Help… Nápověda… + Import Importovat + Information Informace + Loading… Načítání… + Mouse wheel scroll speed Rychlost posouvání kolečkem myši + Move Přesunout + Never Nikdy + New bookmark (⌘B) Nová záložka (⌘B) + Next Další + Next (⌘G) Další (⌘G) + No PDFs found in {folder} Ve složce {folder} nebyly nalezeny žádné soubory PDF + No results Žádné výsledky + On Zapnuto + Open a PDF (⌘O) Otevřít PDF (⌘O) + Open folder Otevřít složku + Organize Uspořádat + Page {n} Stránka {n} + Page {n} of {total} Stránka {n} z {total} + Paste Vložit + Previous Předchozí + Previous (⇧⌘G) Předchozí (⇧⌘G) + Print (⌘P) Tisk (⌘P) + Refresh Obnovit + Rotate view clockwise (⇧⌘+) Otočit zobrazení po směru hodinových ručiček (⇧⌘+) + Save changes? Uložit změny? + Save file Uložit soubor + Search results Výsledky hledání + Select all Vybrat vše + Success Hotovo + System Podle systému + The password must have at least 6 characters. Heslo musí mít alespoň 6 znaků. + The standard fonts can't draw “{c}” ({code}). Only Western European characters can be added as text for now. Standardní písma nedokážou vykreslit „{c}“ ({code}). Jako text lze zatím přidat jen západoevropské znaky. + This file changed on disk. Reload it to see the new version; your unsaved changes will be lost. Tento soubor se na disku změnil. Načtěte ho znovu, abyste viděli novou verzi; neuložené změny budou ztraceny. + Theme Motiv + Warning Upozornění + Zoom in (⌘+) Přiblížit (⌘+) + Zoom in / out (also pinch or ⌘-scroll) Přiblížit / oddálit (také sevřením prstů nebo posouváním s ⌘) + Zoom out (⌘−) Oddálit (⌘−) +@plural {n} comment|{n} comments {n} komentář|{n} komentáře|{n} komentářů +@plural {n} file|{n} files {n} soubor|{n} soubory|{n} souborů +@plural {n} result|{n} results {n} výsledek|{n} výsledky|{n} výsledků +theme Appearance Vzhled + +# The date picker's weekday heads. +calendar weekday Su Ne +calendar weekday Mo Po +calendar weekday Tu Út +calendar weekday We St +calendar weekday Th Čt +calendar weekday Fr Pá +calendar weekday Sa So + +# A certificate's fields in the certificate viewer. +certificate Issued to Vydáno pro +certificate Issued by Vydal +certificate Valid from Platný od +certificate Valid to Platný do +certificate Intended usage Zamýšlené použití +certificate Serial number Sériové číslo +certificate Issuer Vydavatel +certificate Validity starts Začátek platnosti +certificate Validity ends Konec platnosti +certificate Public key Veřejný klíč +certificate Basic constraints Základní omezení +certificate Key usage Použití klíče +certificate Self-signed Samopodepsaný +certificate SHA-1 digest Otisk SHA-1 +certificate SHA-256 digest Otisk SHA-256 +certificate Version Verze diff --git a/crates/ui-egui/src/i18n/mod.rs b/crates/ui-egui/src/i18n/mod.rs index 20c0fd046..160e2c2d9 100644 --- a/crates/ui-egui/src/i18n/mod.rs +++ b/crates/ui-egui/src/i18n/mod.rs @@ -1457,6 +1457,7 @@ mod tests { "Text", "Index", "Metadata", + "metadata", "Model", "{field}: {e}", "{0}: {1}", @@ -1544,6 +1545,69 @@ mod tests { set_current(Lang::EN); } + /// Czech says everything the layers below word for themselves (see + /// `spanish_covers_what_the_engine_says`), and keeps each sentence's holes. + #[test] + fn czech_covers_what_the_engine_says() { + let cs = Lang::from_code("cs").expect("cs registered"); + let lists: [(&str, &[&str]); 8] = [ + ("accessibility finding", pdfcraft_engine::a11y::WORDINGS), + ("accessibility report", pdfcraft_engine::a11y::REPORT_WORDS), + ("PDF/A problem", pdfcraft_engine::pdfa::WORDINGS), + ("signature detail", pdfcraft_engine::sign::pdf::WORDINGS), + ("change after signing", pdfcraft_engine::sign::pdf::kind::ALL), + ("pages to print", pdfcraft_engine::print::WORDINGS), + ("edit label", pdfcraft_engine::EDIT_LABELS), + ("batch label", pdfcraft_engine::BATCH_LABELS), + ]; + for (what, list) in lists { + assert!(!list.is_empty(), "no {what} wordings to cover"); + for wording in list { + assert!(has(cs, wording), "missing {what}: {wording}"); + let said = tr(cs, wording); + assert_eq!(wording.matches("{}").count(), said.matches("{}").count(), "the Czech of {wording:?} loses a hole: {said:?}"); + for hole in wording.split('{').skip(1).filter_map(|rest| rest.split_once('}')).map(|(name, _)| name).filter(|n| !n.is_empty()) { + assert!(said.contains(&format!("{{{hole}}}")), "the Czech of {wording:?} loses {{{hole}}}: {said:?}"); + } + } + } + assert_eq!(tr(cs, "Signature is valid"), "Podpis je platný"); + } + + /// The date picker's weekday heads and the certificate viewer's fields are looked up in their + /// own contexts, which the `tl!` scan doesn't see: none of them may fall back to English. + #[test] + fn czech_covers_weekdays_and_certificate_fields() { + let cs = Lang::from_code("cs").expect("cs registered"); + assert_eq!( + ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map(|day| tr_ctx(cs, "calendar weekday", day)), + ["Ne", "Po", "Út", "St", "Čt", "Pá", "So"] + ); + assert_eq!(tr_ctx(cs, "certificate", "Subject"), "Subjekt"); + for field in [ + "Issued to", + "Issued by", + "Valid from", + "Valid to", + "Intended usage", + "Serial number", + "Issuer", + "Validity starts", + "Validity ends", + "Public key", + "Basic constraints", + "Key usage", + "Self-signed", + "SHA-1 digest", + "SHA-256 digest", + "Version", + ] { + assert_ne!(tr_ctx(cs, "certificate", field), field, "certificate field remains untranslated: {field}"); + } + assert_eq!(trn(cs, 3, "{n} file", "{n} files"), "3 soubory"); + assert_eq!(fmt(tr(cs, "{n} tags"), &[("n", "1")]), "Tagy: 1"); + } + /// Turkish covers every registered menu title and menu command label, keeps ellipses, and /// persists in preferences. #[test] diff --git a/docs/localization-parity.md b/docs/localization-parity.md index 995293af3..7b1a300db 100644 --- a/docs/localization-parity.md +++ b/docs/localization-parity.md @@ -1,7 +1,7 @@ # Localization parity > **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-13 · **Change:** minor (Vietnamese 100% of current key union; native-speaker community review; twelve-language mean ≈68%) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-14 · **Change:** minor (Italian count after completing its catalog) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-16 · **Change:** minor (Czech catalog completed and reviewed) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Per-language status of PdfCraft's interface against Acrobat Pro's. How translations work and how to add a language: [localization.md](localization.md). Summary in [ROADMAP.md](../ROADMAP.md). @@ -59,7 +59,7 @@ none has translated help. Vietnamese's **To `full`** hours are therefore residua | Traditional Chinese | `zh-hant` | 2,016 (94.1%) | partial (same Hans/Hant face caveat) | yes | | Russian | `ru` | 2,043 (95.3%) | partial | yes | | Bulgarian | `bg` | 2,094 (97.7%) | partial | no | -| Czech | `cs` | 135 (6.3%) | menus only | yes | +| Czech | `cs` | 2,674 entries (every key of the other catalogs, the engine's sentences, weekdays and certificate fields) | partial | yes | | Telugu | `te` | 2,058 (96.0%) | partial (the release-pinned craft-fonts has no Telugu face yet) | no | | Hungarian | `hu` | 2,126 (99.2%) | partial | yes | | Ukrainian | `uk` | 2,142 (100%) | partial | yes | @@ -82,6 +82,7 @@ Acrobat languages PdfCraft lacks: Danish, Dutch, Finnish, Norwegian, Swedish, He | Date | Change | Summary | |---|---|---| +| 2026-10-16 | minor | Czech: 2,674 entries after adding the keys the other catalogs had (the engine's sentences, weekday heads, certificate fields, shared buttons) and unifying "tag" as *tag* (not *značka*, which is a redaction mark) | | 2026-10-13 | minor | Vietnamese (`vi`) catalog: 2,591 entries (100% of current key union + `theme`/`Appearance`); twelve-language mean ≈ 68%; native-speaker community review; registered with `plural_none` | | 2026-10-14 | minor | Italian: 2,528 entries after adding the 201 keys the other catalogs had and the code looks up | | 2026-10-12 | minor | Added current counts for Kazakh, Polish, Slovenian, Greek, Turkish and Lithuanian; retained existing language assessments and the original percentage snapshot | diff --git a/docs/localization.md b/docs/localization.md index 657e2eb24..b2f89fb1f 100644 --- a/docs/localization.md +++ b/docs/localization.md @@ -14,9 +14,9 @@ The control channel exposes the setting through `ui.set`: The value is `auto` or a language code (`en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr`, `lt` or `vi`), in any case. `ui.state` reports `language` as written in the preferences (`auto`, `en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr`, `lt` or `vi`). Unknown values return an error without changing the current setting. Preferences saved before this setting existed follow the system language. -Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Most shipped catalogs (Japanese, Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Italian, Brazilian Portuguese, Arabic, Slovenian, Kazakh, Polish, Greek, Turkish, Lithuanian, Vietnamese and others) cover the current localizable surface (about 2,000–2,600 entries each); Czech still covers mainly the menus. Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Document contents, filenames, CLI/MCP/control protocol strings and external help stay outside the catalog. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). -Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Brazilian Portuguese and Arabic translate them (about 2,000–2,140 entries each), and Italian has 2,528 entries; Czech and Turkish cover the menus so far. Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). -Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Brazilian Portuguese, Arabic and Slovenian translate them (about 2,000–2,190 entries each), and Italian has 2,528 entries; Czech covers the menus so far. Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). +Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Most shipped catalogs (Japanese, Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Italian, Brazilian Portuguese, Arabic, Slovenian, Kazakh, Polish, Greek, Turkish, Lithuanian, Vietnamese and others) cover the current localizable surface (about 2,000–2,600 entries each), and Czech (2,674 entries) covers the same surface. Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Document contents, filenames, CLI/MCP/control protocol strings and external help stay outside the catalog. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). +Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Brazilian Portuguese and Arabic translate them (about 2,000–2,140 entries each), and Italian has 2,528 entries, and Czech has 2,674 entries; Turkish covers the menus so far. Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). +Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Brazilian Portuguese, Arabic and Slovenian translate them (about 2,000–2,190 entries each), and Italian has 2,528 entries, and Czech has 2,674 entries. Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). Whole sentences that the layers below word — what the accessibility checker found, what the PDF/A verifier reports, what a signature's details say, what is wrong with the pages to print, what an edit is called in the history — are translated too, because those layers hand the sentence over apart from the document's own words. See [Sentences the engine words](#sentences-the-engine-words). diff --git a/docs/roadmap.md b/docs/roadmap.md index 9b5100f37..6972815a9 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -149,10 +149,10 @@ total matches the parity estimate. | M13 | Automation (MCP, Action Wizard, CLI) + AI providers | 60–120 | 45% | 25–45 | Done: MCP resources (document info, text, page images); headless tool table (123 tools incl. signing, optimizing, initial view, links, stamps, data exchange, comment review, forms authoring and scripts, redaction, sanitize, print, add content), opt-in MCP server over stdio, CLI `run`/`tools` (closed stdout pipes exit cleanly), UI control channel with drag. Missing: Action Wizard, AI providers
Done since: CLI run and MCP reject missing, empty, repeated and option-valued --root arguments before any tool/script execution or MCP initialization. A single-hyphen directory name remains valid; synthetic CLI regressions preserve a would-be overwritten file. `text_find` also caps the per-page match ranges it materializes at the remaining result limit plus one continuation match. CLI robustness scans visit each directory once through overlapping roots and symlink aliases. | | M12 | Accessibility, compare, measure, search, XFA | 200–380 | 30% | 90–160 | Done: new `a11y` crate with the Accessibility Checker (all 32 rules, report, Fix/Skip/Explain, options dialog and results panel, agent tools). Locatable figure, annotation and form findings highlight their page bounds.
Done since: 2D distance, perimeter and area measurements with persistent viewport calibration, snapping, live information and CSV export; a bounded text-only auto-tag proposal tool; text-only Apply writes marked content, paragraph tags and a parent tree, then opens the Tags panel for review. Missing: mixed-content and field autotag, heading/list/table/figure classification, Order/Content panels, Reading Order tool, compare, geospatial/3D measurement, search index, XFA
Done since: CLI info, text and render use dynamic XFA layout pages, with synthetic count/text/pixel and copy-permission regressions (#1645). | | M13 | Automation (MCP, Action Wizard, CLI) + AI providers | 60–120 | 45% | 25–45 | Done: MCP resources (document info, text, page images); headless tool table (123 tools incl. signing, optimizing, initial view, links, stamps, data exchange, comment review, forms authoring and scripts, redaction, sanitize, print, add content), opt-in MCP server over stdio, CLI `run`/`tools` (closed stdout pipes exit cleanly), UI control channel with drag. Missing: Action Wizard, AI providers
Done since: CLI run and MCP reject missing, empty, repeated and option-valued --root arguments before any tool/script execution or MCP initialization. A single-hyphen directory name remains valid; synthetic CLI regressions preserve a would-be overwritten file. `text_find` also caps the per-page match ranges it materializes at the remaining result limit plus one continuation match. | -| M14 | 1.0 polish: performance, localization, installers | 120–250 | 15% | 80–150 | Done: PhotoCraft's translation system (`i18n/`: TSV catalogs, `tl!`, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through `tl!`. Catalogs of ≈ 2,000–2,140 entries for Japanese, Simplified and Traditional Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Brazilian Portuguese and Arabic (logical-order catalog put into display order; layout not yet mirrored); Czech covers the menus. Italian has 2,528 entries: every key of the other catalogs that the code looks up. Signed and notarized macOS builds, signed Windows installers (x64, x86, ARM64), AppImage, deb, rpm, Flatpak and FreeBSD packages. #307 (bounded large-PDF memory): shared resource indexes and parser metadata, lazy inspection, bounded caches; a 9,156-page file inspects in ≈ 1.8 s at ≈ 500 MiB instead of exceeding 10 GiB. Edits let go of the previous working file before writing the next (a 1 GiB file peaks at two copies while editing, not three; gap 13). Shortcut display uses localized modifier/key names across menus, toolbar, palette, Help and tooltips (#496). Lithuanian adds a 2,578-entry catalog and date names, reviewed by a native-speaking contributor. Validated candidate (macOS raster probe; Windows runtime unverified): the Windows policy changes only embedded JetBrains Mono; horizontal alpha-edge energy per ink improves 2.78%, 3.87% and 1.59% at 100%, 125% and 150%, and is down 0.79% at 200%. Inter is pixel-identical; layout hashes, glyph coverage and the 8 MiB atlas are unchanged. Timing and RSS ranges overlap, with no improvement claimed. Estimates unchanged. Candidate #2383 clamps GPU requests to supported limits while retaining the adapter texture extent; synthetic V3D/downlevel and Windows GPU-required tests pass, but Raspberry Pi startup is unverified. Estimates unchanged. Missing: a right-to-left layout, a Chinese UI face in releases, Hindi/Indonesian/Korean/Vietnamese, file-backed input and global memory budgets, performance budgets, keyboard-only operation Linux/Unix UI fallback fonts also use Fontconfig directories, including Nix store paths, with bounded discovery and the existing candidate allowlist; relative includes and digit-prefixed config filtering have isolated regressions. | -| M14 | 1.0 polish: performance, localization, installers | 120–250 | 15% | 80–150 | Done: PhotoCraft's translation system (`i18n/`: TSV catalogs, `tl!`, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through `tl!`. Catalogs of ≈ 2,000–2,140 entries for Japanese, Simplified and Traditional Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Brazilian Portuguese and Arabic (logical-order catalog put into display order; layout not yet mirrored); Czech covers the menus. Italian has 2,528 entries: every key of the other catalogs that the code looks up. Signed and notarized macOS builds, signed Windows installers (x64, x86, ARM64), AppImage, deb, rpm, Flatpak and FreeBSD packages. #307 (bounded large-PDF memory): shared resource indexes and parser metadata, lazy inspection, bounded caches; a 9,156-page file inspects in ≈ 1.8 s at ≈ 500 MiB instead of exceeding 10 GiB. Edits let go of the previous working file before writing the next (a 1 GiB file peaks at two copies while editing, not three; gap 13). Shortcut display uses localized modifier/key names across menus, toolbar, palette, Help and tooltips (#496). Lithuanian adds a 2,578-entry catalog and date names, reviewed by a native-speaking contributor. Validated candidate (macOS raster probe; Windows runtime unverified): the Windows policy changes only embedded JetBrains Mono; horizontal alpha-edge energy per ink improves 2.78%, 3.87% and 1.59% at 100%, 125% and 150%, and is down 0.79% at 200%. Inter is pixel-identical; layout hashes, glyph coverage and the 8 MiB atlas are unchanged. Timing and RSS ranges overlap, with no improvement claimed. Estimates unchanged. Missing: a right-to-left layout, a Chinese UI face in releases, Hindi/Indonesian/Korean/Vietnamese, file-backed input and global memory budgets, performance budgets, keyboard-only operation XDG desktops use the configuration base for preferences with non-overwriting migration and original-data preservation (#1395). | +| M14 | 1.0 polish: performance, localization, installers | 120–250 | 15% | 80–150 | Done: PhotoCraft's translation system (`i18n/`: TSV catalogs, `tl!`, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through `tl!`. Catalogs of ≈ 2,000–2,140 entries for Japanese, Simplified and Traditional Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Brazilian Portuguese and Arabic (logical-order catalog put into display order; layout not yet mirrored); Czech has 2,674 entries (2026-10-16). Italian has 2,528 entries: every key of the other catalogs that the code looks up. Signed and notarized macOS builds, signed Windows installers (x64, x86, ARM64), AppImage, deb, rpm, Flatpak and FreeBSD packages. #307 (bounded large-PDF memory): shared resource indexes and parser metadata, lazy inspection, bounded caches; a 9,156-page file inspects in ≈ 1.8 s at ≈ 500 MiB instead of exceeding 10 GiB. Edits let go of the previous working file before writing the next (a 1 GiB file peaks at two copies while editing, not three; gap 13). Shortcut display uses localized modifier/key names across menus, toolbar, palette, Help and tooltips (#496). Lithuanian adds a 2,578-entry catalog and date names, reviewed by a native-speaking contributor. Validated candidate (macOS raster probe; Windows runtime unverified): the Windows policy changes only embedded JetBrains Mono; horizontal alpha-edge energy per ink improves 2.78%, 3.87% and 1.59% at 100%, 125% and 150%, and is down 0.79% at 200%. Inter is pixel-identical; layout hashes, glyph coverage and the 8 MiB atlas are unchanged. Timing and RSS ranges overlap, with no improvement claimed. Estimates unchanged. Candidate #2383 clamps GPU requests to supported limits while retaining the adapter texture extent; synthetic V3D/downlevel and Windows GPU-required tests pass, but Raspberry Pi startup is unverified. Estimates unchanged. Missing: a right-to-left layout, a Chinese UI face in releases, Hindi/Indonesian/Korean/Vietnamese, file-backed input and global memory budgets, performance budgets, keyboard-only operation Linux/Unix UI fallback fonts also use Fontconfig directories, including Nix store paths, with bounded discovery and the existing candidate allowlist; relative includes and digit-prefixed config filtering have isolated regressions. | +| M14 | 1.0 polish: performance, localization, installers | 120–250 | 15% | 80–150 | Done: PhotoCraft's translation system (`i18n/`: TSV catalogs, `tl!`, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through `tl!`. Catalogs of ≈ 2,000–2,140 entries for Japanese, Simplified and Traditional Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Brazilian Portuguese and Arabic (logical-order catalog put into display order; layout not yet mirrored); Czech has 2,674 entries (2026-10-16). Italian has 2,528 entries: every key of the other catalogs that the code looks up. Signed and notarized macOS builds, signed Windows installers (x64, x86, ARM64), AppImage, deb, rpm, Flatpak and FreeBSD packages. #307 (bounded large-PDF memory): shared resource indexes and parser metadata, lazy inspection, bounded caches; a 9,156-page file inspects in ≈ 1.8 s at ≈ 500 MiB instead of exceeding 10 GiB. Edits let go of the previous working file before writing the next (a 1 GiB file peaks at two copies while editing, not three; gap 13). Shortcut display uses localized modifier/key names across menus, toolbar, palette, Help and tooltips (#496). Lithuanian adds a 2,578-entry catalog and date names, reviewed by a native-speaking contributor. Validated candidate (macOS raster probe; Windows runtime unverified): the Windows policy changes only embedded JetBrains Mono; horizontal alpha-edge energy per ink improves 2.78%, 3.87% and 1.59% at 100%, 125% and 150%, and is down 0.79% at 200%. Inter is pixel-identical; layout hashes, glyph coverage and the 8 MiB atlas are unchanged. Timing and RSS ranges overlap, with no improvement claimed. Estimates unchanged. Missing: a right-to-left layout, a Chinese UI face in releases, Hindi/Indonesian/Korean/Vietnamese, file-backed input and global memory budgets, performance budgets, keyboard-only operation XDG desktops use the configuration base for preferences with non-overwriting migration and original-data preservation (#1395). | | M13 | Automation (MCP, Action Wizard, CLI) + AI providers | 60–120 | 45% | 25–45 | Done: MCP resources (document info, text, page images); headless tool table (123 tools incl. signing, optimizing, initial view, links, stamps, data exchange, comment review, forms authoring and scripts, redaction, sanitize, print, add content), opt-in MCP server over stdio, CLI `run`/`tools` (closed stdout pipes exit cleanly), UI control channel with drag. Missing: Action Wizard, AI providers | -| M14 | 1.0 polish: performance, localization, installers | 120–250 | 15% | 80–150 | Done: PhotoCraft's translation system (`i18n/`: TSV catalogs, `tl!`, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through `tl!`. Catalogs of ≈ 2,000–2,140 entries for Japanese, Simplified and Traditional Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Brazilian Portuguese and Arabic (logical-order catalog put into display order; layout not yet mirrored); Czech covers the menus. Italian has 2,528 entries: every key of the other catalogs that the code looks up. Signed and notarized macOS builds, signed Windows installers (x64, x86, ARM64), AppImage, deb, rpm, Flatpak and FreeBSD packages. #307 (bounded large-PDF memory): shared resource indexes and parser metadata, lazy inspection, bounded caches; a 9,156-page file inspects in ≈ 1.8 s at ≈ 500 MiB instead of exceeding 10 GiB. Edits let go of the previous working file before writing the next (a 1 GiB file peaks at two copies while editing, not three; gap 13). Shortcut display uses localized modifier/key names across menus, toolbar, palette, Help and tooltips (#496). Traditional Chinese accessibility statuses, rule semantics and Taiwan form/table terms have catalog regressions. Missing: a right-to-left layout, a Chinese UI face in releases, Hindi/Indonesian/Korean/Vietnamese, file-backed input and global memory budgets, performance budgets, keyboard-only operation | +| M14 | 1.0 polish: performance, localization, installers | 120–250 | 15% | 80–150 | Done: PhotoCraft's translation system (`i18n/`: TSV catalogs, `tl!`, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through `tl!`. Catalogs of ≈ 2,000–2,140 entries for Japanese, Simplified and Traditional Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Brazilian Portuguese and Arabic (logical-order catalog put into display order; layout not yet mirrored); Czech has 2,674 entries (2026-10-16). Italian has 2,528 entries: every key of the other catalogs that the code looks up. Signed and notarized macOS builds, signed Windows installers (x64, x86, ARM64), AppImage, deb, rpm, Flatpak and FreeBSD packages. #307 (bounded large-PDF memory): shared resource indexes and parser metadata, lazy inspection, bounded caches; a 9,156-page file inspects in ≈ 1.8 s at ≈ 500 MiB instead of exceeding 10 GiB. Edits let go of the previous working file before writing the next (a 1 GiB file peaks at two copies while editing, not three; gap 13). Shortcut display uses localized modifier/key names across menus, toolbar, palette, Help and tooltips (#496). Traditional Chinese accessibility statuses, rule semantics and Taiwan form/table terms have catalog regressions. Missing: a right-to-left layout, a Chinese UI face in releases, Hindi/Indonesian/Korean/Vietnamese, file-backed input and global memory budgets, performance budgets, keyboard-only operation | | | **Total** | **2,085–3,840** | **≈ 49% ready** | **≈ 770–1,400** | Area view of the same work: [target-app-parity.md](target-app-parity.md#by-feature-area) | ## Upcoming milestones, ranked