diff --git a/App/Minesweeper/Resources/Localizable.xcstrings b/App/Minesweeper/Resources/Localizable.xcstrings index e51ba3e0..07de7a64 100644 --- a/App/Minesweeper/Resources/Localizable.xcstrings +++ b/App/Minesweeper/Resources/Localizable.xcstrings @@ -1265,7 +1265,8 @@ } }, "gc.minesweeper.leaderboard.easy.daily.title" : { - "extractionState" : "stale", + "comment" : "#1086: read by ASCRegister (`Config.leaderboards(for: .minesweeper)` titleKey, required by `validate`/`plan`/`apply --app minesweeper`) for the Game Center leaderboard name, not by app code. Do not delete.", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -1312,7 +1313,8 @@ } }, "gc.minesweeper.leaderboard.hard.daily.title" : { - "extractionState" : "stale", + "comment" : "#1086: read by ASCRegister (`Config.leaderboards(for: .minesweeper)` titleKey, required by `validate`/`plan`/`apply --app minesweeper`) for the Game Center leaderboard name, not by app code. Do not delete.", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -1359,7 +1361,8 @@ } }, "gc.minesweeper.leaderboard.medium.daily.title" : { - "extractionState" : "stale", + "comment" : "#1086: read by ASCRegister (`Config.leaderboards(for: .minesweeper)` titleKey, required by `validate`/`plan`/`apply --app minesweeper`) for the Game Center leaderboard name, not by app code. Do not delete.", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -1406,7 +1409,8 @@ } }, "iap.minesweeper.remove_ads.description" : { - "extractionState" : "stale", + "comment" : "#1086: read by ASCRegister (`IAPProduct.descriptionKey`: required by `validate --app minesweeper`, uploaded by `iap plan`/`iap apply` as the App Store IAP description), not by app code. Do not delete.", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -1453,7 +1457,7 @@ } }, "iap.minesweeper.remove_ads.name" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { diff --git a/App/Sudoku/Resources/Localizable.xcstrings b/App/Sudoku/Resources/Localizable.xcstrings index febb56f5..1910c8fa 100644 --- a/App/Sudoku/Resources/Localizable.xcstrings +++ b/App/Sudoku/Resources/Localizable.xcstrings @@ -985,55 +985,8 @@ } } }, - "3 puzzles today" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "3 puzzles today" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "3 puzles para hoy" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "今日のパズル 3 問" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "오늘의 퍼즐 3개" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "3 ข้อสำหรับวันนี้" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "今日 3 题" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "今日 3 題" - } - } - } - }, "About" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -1079,55 +1032,8 @@ } } }, - "Account / language" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Account / language" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cuenta / idioma" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "アカウント / 言語" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "계정 / 언어" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "บัญชี / ภาษา" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "账号 / 语言" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "帳號 / 語言" - } - } - } - }, "Cancel" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -1174,7 +1080,7 @@ } }, "Clear cache" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -1220,53 +1126,6 @@ } } }, - "Completed" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Completed" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Completado" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "完了" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "완료" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "เสร็จสิ้น" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "已完成" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "已完成" - } - } - } - }, "Couldn't clear cache" : { "comment" : "#687 Settings — failure toast shown when the Clear cache action's delete throws (the error also funnels through ErrorReporter). Mirrors MinesweeperKit's entry (#284).", "extractionState" : "manual", @@ -1364,803 +1223,426 @@ } }, "Couldn't generate today's puzzle" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Couldn't generate today's puzzle" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "No se pudo generar el puzle de hoy" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "今日のパズルを生成できませんでした" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "오늘의 퍼즐을 생성하지 못했습니다" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "ไม่สามารถสร้างปริศนาประจำวันนี้ได้" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "今日题目暂时无法生成" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "今日題目暫無法產生" - } - } - } - }, - "Couldn't load puzzle." : { - "comment" : "#854 — BoardLoaderView .failed block title.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Couldn't load puzzle." - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "No se pudo cargar el puzle." - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "パズルを読み込めませんでした。" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "퍼즐을 불러오지 못했습니다." - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "ไม่สามารถโหลดปริศนาได้" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "无法加载题目。" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "無法載入題目。" - } - } - } - }, - "Daily" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Daily" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Diario" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "今日のパズル" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "오늘의 퍼즐" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "ประจำวัน" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "每日" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "今日" - } - } - } - }, - "Difficulty" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Difficulty" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dificultad" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "難易度" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "난이도" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "ระดับความยาก" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "难度" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "難度" - } - } - } - }, - "Digit %lld" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Digit %lld" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dígito %lld" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "数字 %lld" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "숫자 %lld" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "หมายเลข %lld" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "数字 %lld" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "數字 %lld" - } - } - } - }, - "New Game" : { - "comment" : "#885 Practice hub primary CTA (2026-07-18 owner adjudication: wording unified across both apps, was \"Draw new puzzle\" here / \"Start\" on Minesweeper). Translations copied from Minesweeper's existing \"New Game\" key.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "New Game" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nueva partida" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "新しいゲーム" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "새 게임" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "เกมใหม่" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "新游戏" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "新遊戲" - } - } - } - }, - "Easy" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Easy" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fácil" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "やさしい" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "쉬움" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "ง่าย" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "简单" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "簡單" - } - } - } - }, - "Elapsed time %@" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Elapsed time %@" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tiempo transcurrido %@" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "経過時間 %@" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "경과 시간 %@" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "เวลาที่ผ่านไป %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "已用时间 %@" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "已用時間 %@" - } - } - } - }, - "Erase" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Erase" + "value" : "Couldn't generate today's puzzle" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Borrar" + "value" : "No se pudo generar el puzle de hoy" } }, "ja" : { "stringUnit" : { "state" : "translated", - "value" : "消去" + "value" : "今日のパズルを生成できませんでした" } }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "지우기" + "value" : "오늘의 퍼즐을 생성하지 못했습니다" } }, "th" : { "stringUnit" : { "state" : "translated", - "value" : "ลบ" + "value" : "ไม่สามารถสร้างปริศนาประจำวันนี้ได้" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "擦除" + "value" : "今日题目暂时无法生成" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "擦除" + "value" : "今日題目暫無法產生" } } } }, - "error.gameCenter.not_authenticated.action" : { - "extractionState" : "stale", + "Couldn't load puzzle." : { + "comment" : "#854 — BoardLoaderView .failed block title.", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Open Settings" + "value" : "Couldn't load puzzle." } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Abrir Ajustes" + "value" : "No se pudo cargar el puzle." } }, "ja" : { "stringUnit" : { "state" : "translated", - "value" : "設定を開く" + "value" : "パズルを読み込めませんでした。" } }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "설정 열기" + "value" : "퍼즐을 불러오지 못했습니다." } }, "th" : { "stringUnit" : { "state" : "translated", - "value" : "เปิดการตั้งค่า" + "value" : "ไม่สามารถโหลดปริศนาได้" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "打开设置" + "value" : "无法加载题目。" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "開啟設定" + "value" : "無法載入題目。" } } } }, - "error.gameCenter.not_authenticated.title" : { - "extractionState" : "stale", + "Daily" : { + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Sign in to Game Center" + "value" : "Daily" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Inicia sesión en Game Center" + "value" : "Diario" } }, "ja" : { "stringUnit" : { "state" : "translated", - "value" : "Game Center にサインイン" + "value" : "今日のパズル" } }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "Game Center에 로그인" + "value" : "오늘의 퍼즐" } }, "th" : { "stringUnit" : { "state" : "translated", - "value" : "ลงชื่อเข้าใช้ Game Center" + "value" : "ประจำวัน" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "请登录 Game Center" + "value" : "每日" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "請登入 Game Center" + "value" : "今日" } } } }, - "error.persistence.icloud_unavailable.action" : { - "extractionState" : "stale", + "Difficulty" : { + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Open Settings" + "value" : "Difficulty" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Abrir Ajustes" + "value" : "Dificultad" } }, "ja" : { "stringUnit" : { "state" : "translated", - "value" : "設定を開く" + "value" : "難易度" } }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "설정 열기" + "value" : "난이도" } }, "th" : { "stringUnit" : { "state" : "translated", - "value" : "เปิดการตั้งค่า" + "value" : "ระดับความยาก" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "打开设置" + "value" : "难度" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "開啟設定" + "value" : "難度" } } } }, - "error.persistence.icloud_unavailable.body" : { - "extractionState" : "stale", + "Digit %lld" : { + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Sign in to iCloud in Settings to sync your progress across devices." + "value" : "Digit %lld" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Inicia sesión en iCloud desde Ajustes para sincronizar tu progreso entre dispositivos." + "value" : "Dígito %lld" } }, "ja" : { "stringUnit" : { "state" : "translated", - "value" : "「設定」から iCloud にサインインすると、デバイス間で進行状況を同期できます。" + "value" : "数字 %lld" } }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "기기 간에 진행 상황을 동기화하려면 「설정」에서 iCloud에 로그인하세요." + "value" : "숫자 %lld" } }, "th" : { "stringUnit" : { "state" : "translated", - "value" : "ลงชื่อเข้าใช้ iCloud ใน «การตั้งค่า» เพื่อซิงค์ความคืบหน้าข้ามอุปกรณ์" + "value" : "หมายเลข %lld" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "请前往「设置」登录 iCloud,以便跨设备同步进度。" + "value" : "数字 %lld" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "請至「設定」登入 iCloud,以便跨裝置同步進度。" + "value" : "數字 %lld" } } } }, - "error.persistence.icloud_unavailable.title" : { - "comment" : "Error vocabulary — Persistence iCloud unavailable", - "extractionState" : "stale", + "New Game" : { + "comment" : "#885 Practice hub primary CTA (2026-07-18 owner adjudication: wording unified across both apps, was \"Draw new puzzle\" here / \"Start\" on Minesweeper). Translations copied from Minesweeper's existing \"New Game\" key.", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "iCloud unavailable" + "value" : "New Game" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "iCloud no disponible" + "value" : "Nueva partida" } }, "ja" : { "stringUnit" : { "state" : "translated", - "value" : "iCloud を利用できません" + "value" : "新しいゲーム" } }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "iCloud을 사용할 수 없습니다" + "value" : "새 게임" } }, "th" : { "stringUnit" : { "state" : "translated", - "value" : "iCloud ใช้งานไม่ได้" + "value" : "เกมใหม่" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "iCloud 暂时不可用" + "value" : "新游戏" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "iCloud 暫時無法使用" + "value" : "新遊戲" } } } }, - "error.puzzleStore.generator_failed.action" : { - "extractionState" : "stale", + "Easy" : { + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Try again" + "value" : "Easy" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Reintentar" + "value" : "Fácil" } }, "ja" : { "stringUnit" : { "state" : "translated", - "value" : "もう一度試す" + "value" : "やさしい" } }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "다시 시도" + "value" : "쉬움" } }, "th" : { "stringUnit" : { "state" : "translated", - "value" : "ลองอีกครั้ง" + "value" : "ง่าย" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "重试" + "value" : "简单" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "重試" + "value" : "簡單" } } } }, - "error.puzzleStore.generator_failed.body" : { - "extractionState" : "stale", + "Elapsed time %@" : { + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Please try a different difficulty." + "value" : "Elapsed time %@" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Prueba con otra dificultad." + "value" : "Tiempo transcurrido %@" } }, "ja" : { "stringUnit" : { "state" : "translated", - "value" : "別の難易度をお試しください。" + "value" : "経過時間 %@" } }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "다른 난이도를 시도해 주세요." + "value" : "경과 시간 %@" } }, "th" : { "stringUnit" : { "state" : "translated", - "value" : "โปรดลองระดับความยากอื่น" + "value" : "เวลาที่ผ่านไป %@" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "请改试其他难度。" + "value" : "已用时间 %@" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "請改試其他難度。" + "value" : "已用時間 %@" } } } }, - "error.puzzleStore.generator_failed.title" : { - "extractionState" : "stale", + "Erase" : { + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Couldn't generate puzzle" + "value" : "Erase" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "No se pudo generar el puzle" + "value" : "Borrar" } }, "ja" : { "stringUnit" : { "state" : "translated", - "value" : "パズルを生成できませんでした" + "value" : "消去" } }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "퍼즐을 생성하지 못했습니다" + "value" : "지우기" } }, "th" : { "stringUnit" : { "state" : "translated", - "value" : "ไม่สามารถสร้างปริศนาได้" + "value" : "ลบ" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "题目暂时无法生成" + "value" : "擦除" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "題目暫無法產生" + "value" : "擦除" } } } @@ -2401,7 +1883,7 @@ } }, "Generated puzzles will be re-derived next play. Saved games are not affected." : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -2448,7 +1930,7 @@ } }, "Generator" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -2542,102 +2024,8 @@ } } }, - "Global" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Global" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Global" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "グローバル" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "전체" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "ทั่วโลก" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "全球" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "全球" - } - } - } - }, - "Global / friends" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Global / friends" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Global / amigos" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "グローバル / フレンド" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "전체 / 친구" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "ทั่วโลก / เพื่อน" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "全球 / 好友" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "全球 / 朋友" - } - } - } - }, "Hard" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -2684,7 +2072,7 @@ } }, "iap.remove_ads.description" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -2731,7 +2119,7 @@ } }, "iap.remove_ads.name" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -2778,7 +2166,7 @@ } }, "Medium" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -2824,55 +2212,8 @@ } } }, - "Mixed difficulty pool" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mixed difficulty pool" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Banco de dificultad mixta" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "難易度ミックスのプール" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "난이도 혼합 풀" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "คลังปริศนาคละความยาก" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "混合难度题库" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "混合難度題庫" - } - } - } - }, "Notes" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -2919,7 +2260,7 @@ } }, "Pause" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3014,7 +2355,7 @@ } }, "Practice" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3061,7 +2402,7 @@ } }, "Ready to play" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3156,7 +2497,7 @@ } }, "Redo" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3203,7 +2544,7 @@ } }, "Reset session cache" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3250,7 +2591,7 @@ } }, "Resume" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3297,7 +2638,7 @@ } }, "Resume %@" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3344,7 +2685,7 @@ } }, "Retry" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3391,7 +2732,7 @@ } }, "Settings" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3438,7 +2779,7 @@ } }, "Sign in to Game Center" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3485,7 +2826,7 @@ } }, "Sign in to Game Center to compare with others." : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3532,7 +2873,7 @@ } }, "Solved in %@" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3579,7 +2920,7 @@ } }, "Solved!" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3626,7 +2967,7 @@ } }, "Storage" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3673,7 +3014,7 @@ } }, "Tap to resume" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3720,7 +3061,7 @@ } }, "Today" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3767,7 +3108,7 @@ } }, "Try a different difficulty, or come back tomorrow." : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3814,7 +3155,7 @@ } }, "Try another difficulty" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3861,7 +3202,7 @@ } }, "Undo" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3908,7 +3249,7 @@ } }, "Version" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { diff --git a/Packages/SudokuKit/Tests/SudokuAppCompositionTests/Resources/Localizable.xcstrings.json b/Packages/SudokuKit/Tests/SudokuAppCompositionTests/Resources/Localizable.xcstrings.json index febb56f5..1910c8fa 100644 --- a/Packages/SudokuKit/Tests/SudokuAppCompositionTests/Resources/Localizable.xcstrings.json +++ b/Packages/SudokuKit/Tests/SudokuAppCompositionTests/Resources/Localizable.xcstrings.json @@ -985,55 +985,8 @@ } } }, - "3 puzzles today" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "3 puzzles today" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "3 puzles para hoy" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "今日のパズル 3 問" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "오늘의 퍼즐 3개" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "3 ข้อสำหรับวันนี้" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "今日 3 题" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "今日 3 題" - } - } - } - }, "About" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -1079,55 +1032,8 @@ } } }, - "Account / language" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Account / language" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cuenta / idioma" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "アカウント / 言語" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "계정 / 언어" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "บัญชี / ภาษา" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "账号 / 语言" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "帳號 / 語言" - } - } - } - }, "Cancel" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -1174,7 +1080,7 @@ } }, "Clear cache" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -1220,53 +1126,6 @@ } } }, - "Completed" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Completed" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Completado" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "完了" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "완료" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "เสร็จสิ้น" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "已完成" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "已完成" - } - } - } - }, "Couldn't clear cache" : { "comment" : "#687 Settings — failure toast shown when the Clear cache action's delete throws (the error also funnels through ErrorReporter). Mirrors MinesweeperKit's entry (#284).", "extractionState" : "manual", @@ -1364,803 +1223,426 @@ } }, "Couldn't generate today's puzzle" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Couldn't generate today's puzzle" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "No se pudo generar el puzle de hoy" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "今日のパズルを生成できませんでした" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "오늘의 퍼즐을 생성하지 못했습니다" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "ไม่สามารถสร้างปริศนาประจำวันนี้ได้" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "今日题目暂时无法生成" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "今日題目暫無法產生" - } - } - } - }, - "Couldn't load puzzle." : { - "comment" : "#854 — BoardLoaderView .failed block title.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Couldn't load puzzle." - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "No se pudo cargar el puzle." - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "パズルを読み込めませんでした。" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "퍼즐을 불러오지 못했습니다." - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "ไม่สามารถโหลดปริศนาได้" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "无法加载题目。" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "無法載入題目。" - } - } - } - }, - "Daily" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Daily" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Diario" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "今日のパズル" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "오늘의 퍼즐" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "ประจำวัน" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "每日" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "今日" - } - } - } - }, - "Difficulty" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Difficulty" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dificultad" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "難易度" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "난이도" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "ระดับความยาก" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "难度" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "難度" - } - } - } - }, - "Digit %lld" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Digit %lld" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dígito %lld" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "数字 %lld" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "숫자 %lld" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "หมายเลข %lld" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "数字 %lld" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "數字 %lld" - } - } - } - }, - "New Game" : { - "comment" : "#885 Practice hub primary CTA (2026-07-18 owner adjudication: wording unified across both apps, was \"Draw new puzzle\" here / \"Start\" on Minesweeper). Translations copied from Minesweeper's existing \"New Game\" key.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "New Game" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nueva partida" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "新しいゲーム" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "새 게임" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "เกมใหม่" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "新游戏" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "新遊戲" - } - } - } - }, - "Easy" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Easy" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fácil" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "やさしい" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "쉬움" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "ง่าย" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "简单" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "簡單" - } - } - } - }, - "Elapsed time %@" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Elapsed time %@" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tiempo transcurrido %@" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "経過時間 %@" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "경과 시간 %@" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "เวลาที่ผ่านไป %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "已用时间 %@" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "已用時間 %@" - } - } - } - }, - "Erase" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Erase" + "value" : "Couldn't generate today's puzzle" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Borrar" + "value" : "No se pudo generar el puzle de hoy" } }, "ja" : { "stringUnit" : { "state" : "translated", - "value" : "消去" + "value" : "今日のパズルを生成できませんでした" } }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "지우기" + "value" : "오늘의 퍼즐을 생성하지 못했습니다" } }, "th" : { "stringUnit" : { "state" : "translated", - "value" : "ลบ" + "value" : "ไม่สามารถสร้างปริศนาประจำวันนี้ได้" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "擦除" + "value" : "今日题目暂时无法生成" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "擦除" + "value" : "今日題目暫無法產生" } } } }, - "error.gameCenter.not_authenticated.action" : { - "extractionState" : "stale", + "Couldn't load puzzle." : { + "comment" : "#854 — BoardLoaderView .failed block title.", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Open Settings" + "value" : "Couldn't load puzzle." } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Abrir Ajustes" + "value" : "No se pudo cargar el puzle." } }, "ja" : { "stringUnit" : { "state" : "translated", - "value" : "設定を開く" + "value" : "パズルを読み込めませんでした。" } }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "설정 열기" + "value" : "퍼즐을 불러오지 못했습니다." } }, "th" : { "stringUnit" : { "state" : "translated", - "value" : "เปิดการตั้งค่า" + "value" : "ไม่สามารถโหลดปริศนาได้" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "打开设置" + "value" : "无法加载题目。" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "開啟設定" + "value" : "無法載入題目。" } } } }, - "error.gameCenter.not_authenticated.title" : { - "extractionState" : "stale", + "Daily" : { + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Sign in to Game Center" + "value" : "Daily" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Inicia sesión en Game Center" + "value" : "Diario" } }, "ja" : { "stringUnit" : { "state" : "translated", - "value" : "Game Center にサインイン" + "value" : "今日のパズル" } }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "Game Center에 로그인" + "value" : "오늘의 퍼즐" } }, "th" : { "stringUnit" : { "state" : "translated", - "value" : "ลงชื่อเข้าใช้ Game Center" + "value" : "ประจำวัน" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "请登录 Game Center" + "value" : "每日" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "請登入 Game Center" + "value" : "今日" } } } }, - "error.persistence.icloud_unavailable.action" : { - "extractionState" : "stale", + "Difficulty" : { + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Open Settings" + "value" : "Difficulty" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Abrir Ajustes" + "value" : "Dificultad" } }, "ja" : { "stringUnit" : { "state" : "translated", - "value" : "設定を開く" + "value" : "難易度" } }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "설정 열기" + "value" : "난이도" } }, "th" : { "stringUnit" : { "state" : "translated", - "value" : "เปิดการตั้งค่า" + "value" : "ระดับความยาก" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "打开设置" + "value" : "难度" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "開啟設定" + "value" : "難度" } } } }, - "error.persistence.icloud_unavailable.body" : { - "extractionState" : "stale", + "Digit %lld" : { + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Sign in to iCloud in Settings to sync your progress across devices." + "value" : "Digit %lld" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Inicia sesión en iCloud desde Ajustes para sincronizar tu progreso entre dispositivos." + "value" : "Dígito %lld" } }, "ja" : { "stringUnit" : { "state" : "translated", - "value" : "「設定」から iCloud にサインインすると、デバイス間で進行状況を同期できます。" + "value" : "数字 %lld" } }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "기기 간에 진행 상황을 동기화하려면 「설정」에서 iCloud에 로그인하세요." + "value" : "숫자 %lld" } }, "th" : { "stringUnit" : { "state" : "translated", - "value" : "ลงชื่อเข้าใช้ iCloud ใน «การตั้งค่า» เพื่อซิงค์ความคืบหน้าข้ามอุปกรณ์" + "value" : "หมายเลข %lld" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "请前往「设置」登录 iCloud,以便跨设备同步进度。" + "value" : "数字 %lld" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "請至「設定」登入 iCloud,以便跨裝置同步進度。" + "value" : "數字 %lld" } } } }, - "error.persistence.icloud_unavailable.title" : { - "comment" : "Error vocabulary — Persistence iCloud unavailable", - "extractionState" : "stale", + "New Game" : { + "comment" : "#885 Practice hub primary CTA (2026-07-18 owner adjudication: wording unified across both apps, was \"Draw new puzzle\" here / \"Start\" on Minesweeper). Translations copied from Minesweeper's existing \"New Game\" key.", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "iCloud unavailable" + "value" : "New Game" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "iCloud no disponible" + "value" : "Nueva partida" } }, "ja" : { "stringUnit" : { "state" : "translated", - "value" : "iCloud を利用できません" + "value" : "新しいゲーム" } }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "iCloud을 사용할 수 없습니다" + "value" : "새 게임" } }, "th" : { "stringUnit" : { "state" : "translated", - "value" : "iCloud ใช้งานไม่ได้" + "value" : "เกมใหม่" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "iCloud 暂时不可用" + "value" : "新游戏" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "iCloud 暫時無法使用" + "value" : "新遊戲" } } } }, - "error.puzzleStore.generator_failed.action" : { - "extractionState" : "stale", + "Easy" : { + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Try again" + "value" : "Easy" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Reintentar" + "value" : "Fácil" } }, "ja" : { "stringUnit" : { "state" : "translated", - "value" : "もう一度試す" + "value" : "やさしい" } }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "다시 시도" + "value" : "쉬움" } }, "th" : { "stringUnit" : { "state" : "translated", - "value" : "ลองอีกครั้ง" + "value" : "ง่าย" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "重试" + "value" : "简单" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "重試" + "value" : "簡單" } } } }, - "error.puzzleStore.generator_failed.body" : { - "extractionState" : "stale", + "Elapsed time %@" : { + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Please try a different difficulty." + "value" : "Elapsed time %@" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Prueba con otra dificultad." + "value" : "Tiempo transcurrido %@" } }, "ja" : { "stringUnit" : { "state" : "translated", - "value" : "別の難易度をお試しください。" + "value" : "経過時間 %@" } }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "다른 난이도를 시도해 주세요." + "value" : "경과 시간 %@" } }, "th" : { "stringUnit" : { "state" : "translated", - "value" : "โปรดลองระดับความยากอื่น" + "value" : "เวลาที่ผ่านไป %@" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "请改试其他难度。" + "value" : "已用时间 %@" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "請改試其他難度。" + "value" : "已用時間 %@" } } } }, - "error.puzzleStore.generator_failed.title" : { - "extractionState" : "stale", + "Erase" : { + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Couldn't generate puzzle" + "value" : "Erase" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "No se pudo generar el puzle" + "value" : "Borrar" } }, "ja" : { "stringUnit" : { "state" : "translated", - "value" : "パズルを生成できませんでした" + "value" : "消去" } }, "ko" : { "stringUnit" : { "state" : "translated", - "value" : "퍼즐을 생성하지 못했습니다" + "value" : "지우기" } }, "th" : { "stringUnit" : { "state" : "translated", - "value" : "ไม่สามารถสร้างปริศนาได้" + "value" : "ลบ" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "题目暂时无法生成" + "value" : "擦除" } }, "zh-Hant" : { "stringUnit" : { "state" : "translated", - "value" : "題目暫無法產生" + "value" : "擦除" } } } @@ -2401,7 +1883,7 @@ } }, "Generated puzzles will be re-derived next play. Saved games are not affected." : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -2448,7 +1930,7 @@ } }, "Generator" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -2542,102 +2024,8 @@ } } }, - "Global" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Global" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Global" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "グローバル" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "전체" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "ทั่วโลก" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "全球" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "全球" - } - } - } - }, - "Global / friends" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Global / friends" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Global / amigos" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "グローバル / フレンド" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "전체 / 친구" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "ทั่วโลก / เพื่อน" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "全球 / 好友" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "全球 / 朋友" - } - } - } - }, "Hard" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -2684,7 +2072,7 @@ } }, "iap.remove_ads.description" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -2731,7 +2119,7 @@ } }, "iap.remove_ads.name" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -2778,7 +2166,7 @@ } }, "Medium" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -2824,55 +2212,8 @@ } } }, - "Mixed difficulty pool" : { - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mixed difficulty pool" - } - }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Banco de dificultad mixta" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "難易度ミックスのプール" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "난이도 혼합 풀" - } - }, - "th" : { - "stringUnit" : { - "state" : "translated", - "value" : "คลังปริศนาคละความยาก" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "混合难度题库" - } - }, - "zh-Hant" : { - "stringUnit" : { - "state" : "translated", - "value" : "混合難度題庫" - } - } - } - }, "Notes" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -2919,7 +2260,7 @@ } }, "Pause" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3014,7 +2355,7 @@ } }, "Practice" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3061,7 +2402,7 @@ } }, "Ready to play" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3156,7 +2497,7 @@ } }, "Redo" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3203,7 +2544,7 @@ } }, "Reset session cache" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3250,7 +2591,7 @@ } }, "Resume" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3297,7 +2638,7 @@ } }, "Resume %@" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3344,7 +2685,7 @@ } }, "Retry" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3391,7 +2732,7 @@ } }, "Settings" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3438,7 +2779,7 @@ } }, "Sign in to Game Center" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3485,7 +2826,7 @@ } }, "Sign in to Game Center to compare with others." : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3532,7 +2873,7 @@ } }, "Solved in %@" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3579,7 +2920,7 @@ } }, "Solved!" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3626,7 +2967,7 @@ } }, "Storage" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3673,7 +3014,7 @@ } }, "Tap to resume" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3720,7 +3061,7 @@ } }, "Today" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3767,7 +3108,7 @@ } }, "Try a different difficulty, or come back tomorrow." : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3814,7 +3155,7 @@ } }, "Try another difficulty" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3861,7 +3202,7 @@ } }, "Undo" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3908,7 +3249,7 @@ } }, "Version" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { diff --git a/mise-tasks/scan/l10n b/mise-tasks/scan/l10n index 13e09c3d..86440f30 100755 --- a/mise-tasks/scan/l10n +++ b/mise-tasks/scan/l10n @@ -1,5 +1,5 @@ #!/usr/bin/env bash -#MISE description="L10n completeness + SudokuAppCompositionTests fixture-sync gate: shipping catalogs (Sudoku + Minesweeper) have 0 placeholders and all 7 locales per key (#394); the Localizable + PrivacyInfo test fixtures stay byte-copies of shipping (#361 C)." +#MISE description="L10n completeness + SudokuAppCompositionTests fixture-sync gate: shipping catalogs (Sudoku + Minesweeper) have 0 placeholders, 0 stale entries (#1086) and all 7 locales per key (#394); the Localizable + PrivacyInfo test fixtures stay byte-copies of shipping (#361 C)." set -euo pipefail REPO_ROOT="$(git rev-parse --show-toplevel)" @@ -24,6 +24,16 @@ check_catalog() { fail=1 fi + # 1b) No `extractionState: stale` entries (#1086). Xcode's extraction pass + # cannot see `bundle: .main` lookups from SwiftPM packages, so live keys + # carry `manual`; a `stale` label is an unproven orphan — prove it + # unreferenced and delete it, or prove it live and relabel it `manual`. + n="$(grep -c '"extractionState" : "stale"' "$path" || true)" + if [ "$n" -ne 0 ]; then + echo "FAIL [$name]: $n extractionState \"stale\" entr(y/ies) in $path — delete (proven orphan) or relabel to \"manual\" (live)" >&2 + fail=1 + fi + # 2) Every translatable key carries all 7 locales (skip shouldTranslate=false). REPO_ROOT="$REPO_ROOT" python3 - "$path" "$name" $LOCALES <<'PY' || fail=1 import json, sys @@ -147,4 +157,4 @@ if [ "$fail" -ne 0 ]; then echo "L10n gate FAILED." >&2 exit 1 fi -echo "L10n gate passed: all 2 catalogs 0 placeholders, all 7 locales complete." +echo "L10n gate passed: all 2 catalogs 0 placeholders, 0 stale, all 7 locales complete."