diff --git a/MinimalCountdown.xcodeproj/project.pbxproj b/MinimalCountdown.xcodeproj/project.pbxproj index cd8f19a..3ed2a44 100644 --- a/MinimalCountdown.xcodeproj/project.pbxproj +++ b/MinimalCountdown.xcodeproj/project.pbxproj @@ -43,6 +43,7 @@ Models/EffectStyle.swift, Models/FontWeight.swift, Models/LegacySettings.swift, + Models/NumeralSystem.swift, Models/SafeIntDecodable.swift, Models/SaverSettings.swift, Models/Schedule.swift, @@ -202,6 +203,11 @@ de, es, fr, + ar, + he, + fa, + hi, + sa, ); mainGroup = E9B531912B854D60002A2B79; productRefGroup = E9B5319C2B854D60002A2B79 /* Products */; diff --git a/MinimalCountdown/ConfigureView/ConfigurationWindow.swift b/MinimalCountdown/ConfigureView/ConfigurationWindow.swift index 1d3de72..b44c4a1 100644 --- a/MinimalCountdown/ConfigureView/ConfigurationWindow.swift +++ b/MinimalCountdown/ConfigureView/ConfigurationWindow.swift @@ -153,6 +153,17 @@ private extension ConfigurationWindow { } } .help(Text(Resources.Digits.roundedHint)) + + Picker(selection: $settings.typography.numeralSystem) { + ForEach(NumeralSystem.allCases) { system in + Text(numeralRow(system)).tag(system) + } + } label: { + Text(Resources.Digits.numerals) + Text(Resources.Digits.numeralsHint) + .subtitleFont + } + .help(Text(Resources.Digits.numeralsHint)) } header: { Text(Resources.Digits.title) } @@ -224,6 +235,16 @@ private extension ConfigurationWindow { return Text(row) } + /// Picker row: the numeral-system name + a `123` glyph sample for the explicit systems. + /// `.automatic` shows the name only — its glyphs depend on the viewer's locale. + func numeralRow(_ system: NumeralSystem) -> String { + let name = String(localized: system.label) + guard let numbering = system.numberingSystem else { return name } + var components = Locale.Components(identifier: "en_US") + components.numberingSystem = numbering + return "\(name) \(UIModel.formattedDigits(123, in: Locale(components: components)))" + } + func prepareForDisplay() { withAnimation(.none) { settings = settingsManager.settings diff --git a/MinimalCountdown/Extensions/CGFloat+Extensions.swift b/MinimalCountdown/Extensions/CGFloat+Extensions.swift index 1788c0d..1783e2d 100644 --- a/MinimalCountdown/Extensions/CGFloat+Extensions.swift +++ b/MinimalCountdown/Extensions/CGFloat+Extensions.swift @@ -51,6 +51,8 @@ extension CGFloat { /// Label text size relative to the digits baseline. CGFloat = 1.0 / 5.0 static let labelsToDigitsRatio: CGFloat = 1.0 / 5.0 + /// Non Latin label text size relative to the digits baseline. CGFloat = 1.0 / 3.8 + static let nonLatinLabelsToDigitsRatio: CGFloat = 1.0 / 3.8 /// Title text size relative to the digits baseline. CGFloat = 1.0 / 4.0 static let titleToDigitsRatio: CGFloat = 1.0 / 4.0 /// Inter-element spacing as a fraction of window width. CGFloat = 0.04 diff --git a/MinimalCountdown/Extensions/Date+Extensions.swift b/MinimalCountdown/Extensions/Date+Extensions.swift index 30205c4..d6d6c3c 100644 --- a/MinimalCountdown/Extensions/Date+Extensions.swift +++ b/MinimalCountdown/Extensions/Date+Extensions.swift @@ -9,10 +9,10 @@ import Foundation extension Date { // MARK: - Duration components relative to a reference `now` for target date - func daysString(relativeTo now: Date) -> String { self.duration(from: now, for: .days) } - func hoursString(relativeTo now: Date) -> String { self.duration(from: now, for: .hours) } - func minutesString(relativeTo now: Date) -> String { self.duration(from: now, for: .minutes) } - func secondsString(relativeTo now: Date) -> String { self.duration(from: now, for: .seconds) } + func days(relativeTo now: Date) -> Int { self.duration(from: now, for: .days) } + func hours(relativeTo now: Date) -> Int { self.duration(from: now, for: .hours) } + func minutes(relativeTo now: Date) -> Int { self.duration(from: now, for: .minutes) } + func seconds(relativeTo now: Date) -> Int { self.duration(from: now, for: .seconds) } // MARK: - DatePicker and date verification components func datesInBetween() -> ClosedRange { minDate ... maxDate } @@ -23,19 +23,18 @@ extension Date { // MARK: - Private helpers private extension Date { - func duration(from now: Date, for element: AppearanceStyle) -> String { + func duration(from now: Date, for element: AppearanceStyle) -> Int { // use ceil to fix double-zero issue let total = Int(abs(ceil(self.timeIntervalSince(now)))) - let elementDuration: Int = switch element { + return switch element { case .days: total / .oneDay case .hours: total % .oneDay / .oneHour case .minutes: total % .oneHour / .oneMinute case .seconds: total % .oneMinute } - return String(format: "%02d", elementDuration) } - + func farAvailableDate(isFuture: Bool) -> Self { Date(timeInterval: (isFuture ? .oneYearAndOneDay : -.oneYearAndOneDay), since: self) } diff --git a/MinimalCountdown/Models/NumeralSystem.swift b/MinimalCountdown/Models/NumeralSystem.swift new file mode 100644 index 0000000..9b31848 --- /dev/null +++ b/MinimalCountdown/Models/NumeralSystem.swift @@ -0,0 +1,43 @@ +// +// NumeralSystem.swift +// MinimalCountdown +// +// Created by Sergey Kemenov +// + +import Foundation + +enum NumeralSystem: Int, CaseIterable, Identifiable, SafeIntDecodable, Equatable, Hashable { + case automatic = 0, latin, arabic, persian, devanagari + + // safe and un-optional, defaults to .automatic + init(_ rawValue: Int) { + self = .init(rawValue: rawValue) ?? .automatic + } +} + +extension NumeralSystem { + var id: Self { self } + + /// `nil` for `.automatic` — the caller falls back to the resolved locale's own numbering + /// system (UAE → Latin, Egypt → Arabic). The explicit cases override that. + var numberingSystem: Locale.NumberingSystem? { + switch self { + case .automatic: nil + case .latin: Locale.NumberingSystem("latn") + case .arabic: Locale.NumberingSystem("arab") + case .persian: Locale.NumberingSystem("arabext") + case .devanagari: Locale.NumberingSystem("deva") + } + } + + var label: LocalizedStringResource { + switch self { + case .automatic: Resources.Labels.NumeralSystem.automatic + case .latin: Resources.Labels.NumeralSystem.latin + case .arabic: Resources.Labels.NumeralSystem.arabic + case .persian: Resources.Labels.NumeralSystem.persian + case .devanagari: Resources.Labels.NumeralSystem.devanagari + } + } +} diff --git a/MinimalCountdown/Models/SaverSettings.swift b/MinimalCountdown/Models/SaverSettings.swift index 4daaa3f..8f96f91 100644 --- a/MinimalCountdown/Models/SaverSettings.swift +++ b/MinimalCountdown/Models/SaverSettings.swift @@ -37,7 +37,7 @@ extension SaverSettings { effect: .none, effectColor: .white ), - typography: .init(weight: .ultraLight, isRounded: false), + typography: .init(weight: .ultraLight, isRounded: false, numeralSystem: .automatic), title: .init(text: "", isHidden: true) ) } @@ -45,7 +45,7 @@ extension SaverSettings { #if DEBUG extension SaverSettings { static let preview = SaverSettings( - appearance: .init(style: .days, isLabelHidden: false), + appearance: .init(style: .seconds, isLabelHidden: false), schedule: .init(target: Date(timeIntervalSinceNow: .oneDay * 365)), theme: .init( accent: .white, @@ -54,7 +54,7 @@ extension SaverSettings { effect: .none, effectColor: .white ), - typography: .init(weight: .ultraLight, isRounded: false), + typography: .init(weight: .ultraLight, isRounded: false, numeralSystem: .automatic), title: .init(text: "See you soon", isHidden: false) ) } diff --git a/MinimalCountdown/Models/Typography.swift b/MinimalCountdown/Models/Typography.swift index 6da9f3b..a8d53ce 100644 --- a/MinimalCountdown/Models/Typography.swift +++ b/MinimalCountdown/Models/Typography.swift @@ -10,4 +10,16 @@ import Foundation struct Typography: Codable, Equatable, Hashable { var weight: FontWeight var isRounded: Bool + var numeralSystem: NumeralSystem = .automatic +} + +extension Typography { + // Settings written before the Numerals picker have no `numeralSystem` key — decode it + // tolerantly so existing v2 files still load (no schema version bump needed). + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + weight = try container.decode(FontWeight.self, forKey: .weight) + isRounded = try container.decode(Bool.self, forKey: .isRounded) + numeralSystem = try container.decodeIfPresent(NumeralSystem.self, forKey: .numeralSystem) ?? .automatic + } } diff --git a/MinimalCountdown/Resources/Localizable.xcstrings b/MinimalCountdown/Resources/Localizable.xcstrings index 00a1e73..73bfec5 100644 --- a/MinimalCountdown/Resources/Localizable.xcstrings +++ b/MinimalCountdown/Resources/Localizable.xcstrings @@ -3,6 +3,12 @@ "strings" : { "⚠️ Looks better at lighter weights." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "⚠️ يبدو أفضل مع أوزان أخف." + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -15,22 +21,52 @@ "value" : "⚠️ Se ve mejor con grosores más finos." } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "⚠️ با ضخامت‌های نازک‌تر بهتر به نظر می‌رسد." + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "⚠️ Plus joli avec des épaisseurs plus fines." } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "⚠️ נראה טוב יותר עם עוביים דקים יותר." + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "⚠️ हल्की मोटाई में बेहतर दिखता है।" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "⚠️ Лучше смотрится на тонких начертаниях." } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "⚠️ लघु-स्थौल्येषु श्रेष्ठं दृश्यते।" + } } } }, "⚠️ Looks better at Regular weight or higher." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "⚠️ يبدو أفضل مع وزن «عادي» أو أعلى." + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -43,22 +79,52 @@ "value" : "⚠️ Se ve mejor con el grosor Normal o superior." } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "⚠️ با ضخامت «معمولی» یا بیشتر بهتر به نظر می‌رسد." + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "⚠️ Plus joli à l’épaisseur Normale ou supérieure." } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "⚠️ נראה טוב יותר עם עובי «רגיל» ומעלה." + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "⚠️ नियमित या उससे अधिक मोटाई में बेहतर दिखता है।" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "⚠️ Лучше смотрится при толщине Обычная или жирнее." } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "⚠️ «सामान्य» स्थौल्यात् ऊर्ध्वं श्रेष्ठं दृश्यते।" + } } } }, "⚠️ Looks better with Rounded enabled." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "⚠️ يبدو أفضل عند تفعيل التدوير." + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -71,22 +137,52 @@ "value" : "⚠️ Se ve mejor con el redondeado activado." } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "⚠️ با فعال بودن گرد کردن بهتر به نظر می‌رسد." + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "⚠️ Plus joli avec l’arrondi activé." } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "⚠️ נראה טוב יותר עם העיגול מופעל." + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "⚠️ गोलाकार सक्षम होने पर बेहतर दिखता है।" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "⚠️ Лучше смотрится со скруглением." } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "⚠️ वृत्ताकार-सक्षमे श्रेष्ठं दृश्यते।" + } } } }, "Adds an effect to the digits:" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "يضيف تأثيراً على الأرقام:" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -99,22 +195,52 @@ "value" : "Añade un efecto a los dígitos:" } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "جلوه‌ای به ارقام اضافه می‌کند:" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Ajoute un effet aux chiffres :" } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "מוסיף אפקט לספרות:" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "अंकों में प्रभाव जोड़ता है:" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Добавляет эффект к цифрам:" } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "अङ्केषु प्रभावं योजयति:" + } } } }, "Appearance" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "المظهر" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -127,1142 +253,2778 @@ "value" : "Aspecto" } }, - "fr" : { + "fa" : { "stringUnit" : { "state" : "translated", - "value" : "Apparence" + "value" : "ظاهر" } }, - "ru" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Оформление" + "value" : "Apparence" } - } - } - }, - "Backlight" : { - "localizations" : { - "de" : { + }, + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Hintergrundbeleuchtung" + "value" : "מראה" } }, - "es" : { + "hi" : { "stringUnit" : { "state" : "translated", - "value" : "Retroiluminación" + "value" : "दिखावट" } }, - "fr" : { + "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Rétroéclairage" + "value" : "Оформление" } }, - "ru" : { + "sa" : { "stringUnit" : { "state" : "translated", - "value" : "Подсветка" + "value" : "रूपम्" } } } }, - "Black" : { + "Arabic" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "عربية" + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Schwarz" + "value" : "Arabisch" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Negro" + "value" : "Árabes" } }, - "fr" : { + "fa" : { "stringUnit" : { "state" : "translated", - "value" : "Noir" + "value" : "عربی" } }, - "ru" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Чёрный" + "value" : "Arabes" } - } - } - }, - "Blue" : { - "localizations" : { - "de" : { + }, + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Blau" + "value" : "ערבי" } }, - "es" : { + "hi" : { "stringUnit" : { "state" : "translated", - "value" : "Azul" + "value" : "अरबी" } }, - "fr" : { + "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Bleu" + "value" : "Арабские" } }, - "ru" : { + "sa" : { "stringUnit" : { "state" : "translated", - "value" : "Синий" + "value" : "अरबी" } } } }, - "Blur" : { + "Automatic" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تلقائي" + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Unschärfe" + "value" : "Automatisch" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Desenfoque" + "value" : "Automático" } }, - "fr" : { + "fa" : { "stringUnit" : { "state" : "translated", - "value" : "Flou" + "value" : "خودکار" } }, - "ru" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Размытие" + "value" : "Automatique" } - } - } - }, - "Brightness" : { - "localizations" : { - "de" : { + }, + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Helligkeit" + "value" : "אוטומטי" } }, - "es" : { + "hi" : { "stringUnit" : { "state" : "translated", - "value" : "Brillo" + "value" : "स्वचालित" } }, - "fr" : { + "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Luminosité" + "value" : "Автоматически" } }, - "ru" : { + "sa" : { "stringUnit" : { "state" : "translated", - "value" : "Яркость" + "value" : "स्वचालितम्" } } } }, - "Close" : { + "Backlight" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "إضاءة خلفية" + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Schließen" + "value" : "Hintergrundbeleuchtung" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Cerrar" + "value" : "Retroiluminación" } }, - "fr" : { + "fa" : { "stringUnit" : { "state" : "translated", - "value" : "Fermer" + "value" : "نور پس‌زمینه" } }, - "ru" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Закрыть" + "value" : "Rétroéclairage" } - } - } - }, - "Close this window and click Preview to see all the changes in detail, full-screen." : { - "localizations" : { - "de" : { + }, + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Schließen Sie dieses Fenster und klicken Sie auf „Vorschau“, um alle Änderungen im Vollbildmodus zu sehen." + "value" : "תאורה אחורית" } }, - "es" : { + "hi" : { "stringUnit" : { "state" : "translated", - "value" : "Cierra esta ventana y haz clic en «Previsualizar» para ver todos los cambios en pantalla completa." + "value" : "बैकलाइट" } }, - "fr" : { + "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Fermez cette fenêtre et cliquez sur « Aperçu » pour voir tous les changements en détail, en plein écran." + "value" : "Подсветка" } }, - "ru" : { + "sa" : { "stringUnit" : { "state" : "translated", - "value" : "Закройте это окно и нажмите «Просмотр», чтобы в полноэкранном режиме увидеть все изменения." + "value" : "पृष्ठप्रकाशः" } } } }, - "Color" : { + "Black" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "أسود" + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Farbe" + "value" : "Schwarz" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Color" + "value" : "Negro" } }, - "fr" : { + "fa" : { "stringUnit" : { "state" : "translated", - "value" : "Couleur" + "value" : "سیاه" } }, - "ru" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Цвет" + "value" : "Noir" } - } - } - }, - "Could not save settings. Try closing and reopening Settings, restarting your Mac, or reinstalling the screen saver." : { - "localizations" : { - "de" : { + }, + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Einstellungen konnten nicht gespeichert werden. Schließen Sie die Einstellungen und öffnen Sie sie erneut, starten Sie Ihren Mac neu oder installieren Sie den Bildschirmschoner neu." + "value" : "שחור" } }, - "es" : { + "hi" : { "stringUnit" : { "state" : "translated", - "value" : "No se pudieron guardar los ajustes. Prueba a cerrar y volver a abrir Ajustes, reiniciar el Mac o reinstalar el salvapantallas." + "value" : "काला" } }, - "fr" : { + "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Impossible d’enregistrer les réglages. Essayez de fermer puis de rouvrir les Réglages, de redémarrer votre Mac ou de réinstaller l’économiseur d’écran." + "value" : "Чёрный" } }, - "ru" : { + "sa" : { "stringUnit" : { "state" : "translated", - "value" : "Не удалось сохранить настройки. Попробуйте закрыть и снова открыть «Настройки», перезагрузить Mac или переустановить заставку." + "value" : "कृष्णः" } } } }, - "Cyan" : { + "Blue" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "أزرق" + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Cyan" + "value" : "Blau" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Cian" + "value" : "Azul" } }, - "fr" : { + "fa" : { "stringUnit" : { "state" : "translated", - "value" : "Cyan" + "value" : "آبی" } }, - "ru" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Голубой" + "value" : "Bleu" } - } - } - }, - "Date" : { - "localizations" : { - "de" : { + }, + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Datum" + "value" : "כחול" } }, - "es" : { + "hi" : { "stringUnit" : { "state" : "translated", - "value" : "Fecha" + "value" : "नीला" } }, - "fr" : { + "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Date" + "value" : "Синий" } }, - "ru" : { + "sa" : { "stringUnit" : { "state" : "translated", - "value" : "Дата" + "value" : "नीलः" + } + } + } + }, + "Blur" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تمويه" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Unschärfe" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Desenfoque" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "تاری" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Flou" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "טשטוש" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "धुंधला" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Размытие" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "अस्पष्टता" + } + } + } + }, + "Brightness" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "السطوع" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Helligkeit" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Brillo" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "روشنایی" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Luminosité" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "בהירות" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "चमक" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Яркость" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "प्रकाशः" + } + } + } + }, + "Close" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "إغلاق" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Schließen" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cerrar" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "بستن" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fermer" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "סגור" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "\"बंद करें" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Закрыть" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "पिधानम्" + } + } + } + }, + "Close this window and click Preview to see all the changes in detail, full-screen." : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "أغلق هذه النافذة وانقر على «معاينة» لرؤية جميع التغييرات بالتفصيل على الشاشة الكاملة." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Schließen Sie dieses Fenster und klicken Sie auf „Vorschau“, um alle Änderungen im Vollbildmodus zu sehen." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cierra esta ventana y haz clic en «Previsualizar» para ver todos los cambios en pantalla completa." + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "این پنجره را ببند و روی «پیش‌نمایش» کلیک کن تا تمام تغییرات را در حالت تمام‌صفحه ببینی." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fermez cette fenêtre et cliquez sur « Aperçu » pour voir tous les changements en détail, en plein écran." + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "סגור חלון זה ולחץ על «תצוגה מקדימה» כדי לראות את כל השינויים במסך מלא." + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "इस विंडो को बंद करें और «पूर्वावलोकन» पर क्लिक करें ताकि सभी बदलाव पूर्ण स्क्रीन पर देख सकें।" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Закройте это окно и нажмите «Просмотр», чтобы в полноэкранном режиме увидеть все изменения." + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "इदं विण्डो पिधाय «पूर्वावलोकन» नुद «सर्वाणि परिवर्तनानि पूर्णपटले द्रष्टुं»।" + } + } + } + }, + "Color" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "اللون" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Farbe" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Color" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "رنگ" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Couleur" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "צבע" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "रंग" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Цвет" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "वर्णः" + } + } + } + }, + "Could not save settings. Try closing and reopening Settings, restarting your Mac, or reinstalling the screen saver." : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تعذّر حفظ الإعدادات. حاول إغلاق الإعدادات وإعادة فتحها، أو إعادة تشغيل الـ Mac، أو إعادة تثبيت شاشة التوقف." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Einstellungen konnten nicht gespeichert werden. Schließen Sie die Einstellungen und öffnen Sie sie erneut, starten Sie Ihren Mac neu oder installieren Sie den Bildschirmschoner neu." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "No se pudieron guardar los ajustes. Prueba a cerrar y volver a abrir Ajustes, reiniciar el Mac o reinstalar el salvapantallas." + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "تنظیمات ذخیره نشد. پنجره تنظیمات را ببند و دوباره باز کن، مک را ری‌استارت کن یا محافظ صفحه را دوباره نصب کن." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Impossible d’enregistrer les réglages. Essayez de fermer puis de rouvrir les Réglages, de redémarrer votre Mac ou de réinstaller l’économiseur d’écran." + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "לא ניתן לשמור את ההגדרות. נסה לסגור ולפתוח מחדש את ההגדרות, לאתחל את ה-Mac או להתקין מחדש את שומר המסך." + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "सेटिंग्स सेव नहीं हो सकीं। सेटिंग्स विंडो बंद करके फिर से खोलें, Mac रीस्टार्ट करें या स्क्रीन सेवर दोबारा इंस्टॉल करें।" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Не удалось сохранить настройки. Попробуйте закрыть и снова открыть «Настройки», перезагрузить Mac или переустановить заставку." + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "सेटिङ्ग्स् रक्षितुं न शक्यते। सेटिङ्ग्स् विण्डो पिधाय पुनः उद्घाटय, Mac पुनः आरभस्व वा स्क्रीनसेवरं पुनः संस्थापय।" + } + } + } + }, + "Cyan" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "سماوي" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cyan" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cian" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "فیروزه‌ای" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cyan" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "ציאן" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "सियान" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Голубой" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "नीलहरितः" + } + } + } + }, + "Date" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "التاريخ" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Datum" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Fecha" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "تاریخ" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Date" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "תאריך" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "तारीख" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Дата" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "तिथिः" } } } }, "Day" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "اليوم" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tag" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Día" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "روز" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Jour" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "יום" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "दिन" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "День" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "दिनम्" + } + } + } + }, + "Days" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "أيام" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tage" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Días" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "روزها" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Jours" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "ימים" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "दिन" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Дни" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "दिनानि" + } + } + } + }, + "Defaults to midnight." : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "الافتراضي: منتصف الليل." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Standardmäßig Mitternacht." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Por defecto, medianoche." + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "پیش‌فرض: نیمه‌شب." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Minuit par défaut." + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "ברירת מחדל: חצות." + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "डिफ़ॉल्ट: मध्यरात्रि।" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "По умолчанию — полночь." + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "पूर्वनिर्धारितम्: मध्यरात्रिः।" + } + } + } + }, + "Devanagari" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "ديفاناغاري" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Devanagari" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Devanagari" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "دواناگری" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Devanagari" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "דוונגרי" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "देवनागरी" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Деванагари" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "देवनागरी" + } + } + } + }, + "Digits" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "الأرقام" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ziffern" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dígitos" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "ارقام" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Chiffres" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "ספרות" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "अंक" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Цифры" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "अङ्काः" + } + } + } + }, + "Effect" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "التأثير" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Effekt" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Efecto" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "جلوه" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Effet" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "אפקט" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "प्रभाव" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Эффект" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "प्रभावः" + } + } + } + }, + "Effect Color" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "لون التأثير" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Effektfarbe" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Color del efecto" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "رنگ جلوه" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Couleur de l’effet" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "צבע האפקט" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "प्रभाव का रंग" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Цвет эффекта" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "प्रभाववर्णः" + } + } + } + }, + "Glow" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "توهج" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Leuchten" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Resplandor" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "درخشش" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Lueur" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "זוהר" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "चमक" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Свечение" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "प्रभाः" + } + } + } + }, + "Green" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "أخضر" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Grün" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Verde" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "سبز" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Vert" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "ירוק" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "हरा" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Зелёный" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "हरितः" + } + } + } + }, + "Hide labels" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "إخفاء التسميات" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Beschriftungen ausblenden" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ocultar etiquetas" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "پنهان کردن برچسب‌ها" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Masquer les étiquettes" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הסתר תוויות" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "लेबल छुपाएं" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Скрыть подписи" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "लेबलानि गोपय" + } + } + } + }, + "Hide title" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "إخفاء العنوان" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Titel ausblenden" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ocultar título" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "پنهان کردن عنوان" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Masquer le titre" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הסתר כותרת" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "शीर्षक छुपाएं" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Скрыть заголовок" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "शीर्षकं गोपय" + } + } + } + }, + "Hides the title even when it isn't empty." : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "يخفي العنوان حتى لو لم يكن فارغاً." + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Blendet den Titel aus, auch wenn er nicht leer ist." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Oculta el título aunque no esté vacío." + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "عنوان را حتی وقتی خالی نیست پنهان می‌کند." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Masque le titre même lorsqu’il n’est pas vide." + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "מסתיר את הכותרת גם כשהיא לא ריקה." + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "शीर्षक को तब भी छुपाता है जब वह खाली न हो।" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Скрывает заголовок, даже если он не пустой." + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "शीर्षकं गोपयति यद्यपि तत् रिक्तं नास्ति।" + } + } + } + }, + "High" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "عالي" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hoch" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Alto" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "زیاد" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Élevée" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "גבוה" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "उच्च" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Высокая" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "उच्चम्" + } + } + } + }, + "Hours" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "ساعات" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Stunden" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Horas" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "ساعت‌ها" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Heures" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שעות" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "घंटे" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Часы" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "घण्टाः" + } + } + } + }, + "Indigo" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "نيلي" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Indigo" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Índigo" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "نیلی" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Indigo" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "אינדיגו" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "इंडिगो" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Индиго" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "इन्दिगो" + } + } + } + }, + "Inner Glow" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "توهج داخلي" + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Tag" + "value" : "Inneres Leuchten" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Día" + "value" : "Resplandor interior" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "درخشش داخلی" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Jour" + "value" : "Lueur intérieure" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "זוהר פנימי" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "आंतरिक चमक" } }, "ru" : { "stringUnit" : { "state" : "translated", - "value" : "День" + "value" : "Внутреннее свечение" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "आन्तरिकप्रभाः" } } } }, - "Days" : { + "It can be any future date for Timer Mode or any past date for Stopwatch Mode." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "يمكن أن يكون أي تاريخ مستقبلي لوضع المؤقت أو أي تاريخ ماضٍ لوضع ساعة الإيقاف." + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Tage" + "value" : "Es kann ein beliebiges zukünftiges Datum für den Timer-Modus oder ein vergangenes Datum für den Stoppuhr-Modus sein." } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Días" + "value" : "Puede ser cualquier fecha futura para el modo Temporizador o cualquier fecha pasada para el modo Cronómetro." + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "می‌تواند هر تاریخ آینده برای حالت تایمر یا هر تاریخ گذشته برای حالت کرونومتر باشد." } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Jours" + "value" : "Il peut s’agir de n’importe quelle date future pour le mode Minuteur ou de n’importe quelle date passée pour le mode Chronomètre." + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "יכול להיות כל תאריך עתידי למצב טיימר או כל תאריך עבר למצב שעון עצר." + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "टाइमर मोड के लिए कोई भी भविष्य की तारीख या स्टॉपवॉच मोड के लिए कोई भी पिछली तारीख हो सकती है।" } }, "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Дни" + "value" : "Это может быть любая будущая дата для режима таймера или любая прошедшая — для режима секундомера." + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "टाइमर-मोडस्य कृते भविष्यतिथिः वा स्टॉपवॉच-मोडस्य कृते अतीततिथिः भवितुं शक्यते।" } } } }, - "Defaults to midnight." : { + "Latin" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "لاتينية" + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Standardmäßig Mitternacht." + "value" : "Lateinisch" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Por defecto, medianoche." + "value" : "Latinos" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "لاتین" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Minuit par défaut." + "value" : "Latins" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "לטיני" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "लैटिन" } }, "ru" : { "stringUnit" : { "state" : "translated", - "value" : "По умолчанию — полночь." + "value" : "Латинские" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "लैटिन्" } } } }, - "Digits" : { + "Low" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "منخفض" + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Ziffern" + "value" : "Niedrig" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Dígitos" + "value" : "Bajo" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "کم" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Chiffres" + "value" : "Faible" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "נמוך" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "कम" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Низкая" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "अल्पम्" + } + } + } + }, + "Medium" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "متوسط" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mittel" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Medio" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "متوسط" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Moyenne" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "בינוני" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "मध्यम" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Средняя" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "मध्यम्" + } + } + } + }, + "Mint" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "نعناعي" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Minze" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Menta" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "نعناعی" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Menthe" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "מנטה" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "पुदीना" } }, "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Цифры" + "value" : "Мятный" + } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "पुदीना" + } + } + } + }, + "Minutes" : { + "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "دقائق" + } + }, + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Minuten" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Minutos" + } + }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "دقیقه‌ها" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Minutes" } - } - } - }, - "Effect" : { - "localizations" : { - "de" : { + }, + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Effekt" + "value" : "דקות" } }, - "es" : { + "hi" : { "stringUnit" : { "state" : "translated", - "value" : "Efecto" + "value" : "मिनट" } }, - "fr" : { + "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Effet" + "value" : "Минуты" } }, - "ru" : { + "sa" : { "stringUnit" : { "state" : "translated", - "value" : "Эффект" + "value" : "निमेषाः" } } } }, - "Effect Color" : { + "None" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "لا شيء" + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Effektfarbe" + "value" : "Keiner" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Color del efecto" + "value" : "Ninguno" } }, - "fr" : { + "fa" : { "stringUnit" : { "state" : "translated", - "value" : "Couleur de l’effet" + "value" : "هیچ" } }, - "ru" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Цвет эффекта" + "value" : "Aucun" } - } - } - }, - "Glow" : { - "localizations" : { - "de" : { + }, + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Leuchten" + "value" : "ללא" } }, - "es" : { + "hi" : { "stringUnit" : { "state" : "translated", - "value" : "Resplandor" + "value" : "कोई नहीं" } }, - "fr" : { + "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Lueur" + "value" : "Нет" } }, - "ru" : { + "sa" : { "stringUnit" : { "state" : "translated", - "value" : "Свечение" + "value" : "न किमपि" } } } }, - "Green" : { + "Numerals" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "الأعداد" + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Grün" + "value" : "Zahlen" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Verde" + "value" : "Números" } }, - "fr" : { + "fa" : { "stringUnit" : { "state" : "translated", - "value" : "Vert" + "value" : "سیستم ارقام" } }, - "ru" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Зелёный" + "value" : "Numéros" } - } - } - }, - "Hide labels" : { - "localizations" : { - "de" : { + }, + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Beschriftungen ausblenden" + "value" : "ספרות" } }, - "es" : { + "hi" : { "stringUnit" : { "state" : "translated", - "value" : "Ocultar etiquetas" + "value" : "अंक प्रणाली" } }, - "fr" : { + "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Masquer les étiquettes" + "value" : "Числа" } }, - "ru" : { + "sa" : { "stringUnit" : { "state" : "translated", - "value" : "Скрыть подписи" + "value" : "अङ्कप्रणाली" } } } }, - "Hide title" : { + "Orange" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "برتقالي" + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Titel ausblenden" + "value" : "Orange" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Ocultar título" + "value" : "Naranja" } }, - "fr" : { + "fa" : { "stringUnit" : { "state" : "translated", - "value" : "Masquer le titre" + "value" : "نارنجی" } }, - "ru" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Скрыть заголовок" + "value" : "Orange" } - } - } - }, - "Hides the title even when it isn't empty." : { - "localizations" : { - "de" : { + }, + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Blendet den Titel aus, auch wenn er nicht leer ist." + "value" : "כתום" } }, - "es" : { + "hi" : { "stringUnit" : { "state" : "translated", - "value" : "Oculta el título aunque no esté vacío." + "value" : "नारंगी" } }, - "fr" : { + "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Masque le titre même lorsqu’il n’est pas vide." + "value" : "Оранжевый" } }, - "ru" : { + "sa" : { "stringUnit" : { "state" : "translated", - "value" : "Скрывает заголовок, даже если он не пустой." + "value" : "नारङ्गः" } } } }, - "High" : { + "Persian" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "فارسية" + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Hoch" + "value" : "Persisch" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Alto" + "value" : "Persas" } }, - "fr" : { + "fa" : { "stringUnit" : { "state" : "translated", - "value" : "Élevée" + "value" : "فارسی" } }, - "ru" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Высокая" + "value" : "Persans" } - } - } - }, - "Hours" : { - "localizations" : { - "de" : { + }, + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Stunden" + "value" : "פרסי" } }, - "es" : { + "hi" : { "stringUnit" : { "state" : "translated", - "value" : "Horas" + "value" : "फारसी" } }, - "fr" : { + "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Heures" + "value" : "Персидские" } }, - "ru" : { + "sa" : { "stringUnit" : { "state" : "translated", - "value" : "Часы" + "value" : "फारसी" } } } }, - "Indigo" : { + "Pink" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "وردي" + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Indigo" + "value" : "Rosa" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Índigo" + "value" : "Rosa" } }, - "fr" : { + "fa" : { "stringUnit" : { "state" : "translated", - "value" : "Indigo" + "value" : "صورتی" } }, - "ru" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Индиго" + "value" : "Rose" } - } - } - }, - "Inner Glow" : { - "localizations" : { - "de" : { + }, + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Inneres Leuchten" + "value" : "ורוד" } }, - "es" : { + "hi" : { "stringUnit" : { "state" : "translated", - "value" : "Resplandor interior" + "value" : "गुलाबी" } }, - "fr" : { + "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Lueur intérieure" + "value" : "Розовый" } }, - "ru" : { + "sa" : { "stringUnit" : { "state" : "translated", - "value" : "Внутреннее свечение" + "value" : "गुलाबी" } } } }, - "It can be any future date for Timer Mode or any past date for Stopwatch Mode." : { + "Purple" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "بنفسجي" + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Es kann ein beliebiges zukünftiges Datum für den Timer-Modus oder ein vergangenes Datum für den Stoppuhr-Modus sein." + "value" : "Violett" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Puede ser cualquier fecha futura para el modo Temporizador o cualquier fecha pasada para el modo Cronómetro." + "value" : "Morado" } }, - "fr" : { + "fa" : { "stringUnit" : { "state" : "translated", - "value" : "Il peut s’agir de n’importe quelle date future pour le mode Minuteur ou de n’importe quelle date passée pour le mode Chronomètre." + "value" : "بنفش" } }, - "ru" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Это может быть любая будущая дата для режима таймера или любая прошедшая — для режима секундомера." + "value" : "Violet" } - } - } - }, - "Low" : { - "localizations" : { - "de" : { + }, + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Niedrig" + "value" : "סגול" } }, - "es" : { + "hi" : { "stringUnit" : { "state" : "translated", - "value" : "Bajo" + "value" : "बैंगनी" } }, - "fr" : { + "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Faible" + "value" : "Фиолетовый" } }, - "ru" : { + "sa" : { "stringUnit" : { "state" : "translated", - "value" : "Низкая" + "value" : "नीललोहितः" } } } }, - "Medium" : { + "Red" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "أحمر" + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Mittel" + "value" : "Rot" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Medio" + "value" : "Rojo" } }, - "fr" : { + "fa" : { "stringUnit" : { "state" : "translated", - "value" : "Moyenne" + "value" : "قرمز" } }, - "ru" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Средняя" + "value" : "Rouge" } - } - } - }, - "Mint" : { - "localizations" : { - "de" : { + }, + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Minze" + "value" : "אדום" } }, - "es" : { + "hi" : { "stringUnit" : { "state" : "translated", - "value" : "Menta" + "value" : "लाल" } }, - "fr" : { + "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Menthe" + "value" : "Красный" } }, - "ru" : { + "sa" : { "stringUnit" : { "state" : "translated", - "value" : "Мятный" + "value" : "रक्तः" } } } }, - "Minutes" : { + "Renders the digits with the Rounded design." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "يعرض الأرقام بالتصميم المُدوّر." + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Minuten" + "value" : "Stellt die Ziffern im abgerundeten Design dar." } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Minutos" + "value" : "Muestra los dígitos con el diseño Redondeado." } }, - "fr" : { + "fa" : { "stringUnit" : { "state" : "translated", - "value" : "Minutes" + "value" : "ارقام را با طراحی گرد نمایش می‌دهد." } }, - "ru" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Минуты" + "value" : "Affiche les chiffres avec le style arrondi." } - } - } - }, - "None" : { - "localizations" : { - "de" : { + }, + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Keiner" + "value" : "מציג את הספרות בעיצוב המעוגל." } }, - "es" : { + "hi" : { "stringUnit" : { "state" : "translated", - "value" : "Ninguno" + "value" : "अंकों को गोल डिज़ाइन में दिखाता है।" } }, - "fr" : { + "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Aucun" + "value" : "Отображает цифры со скруглённым начертанием." } }, - "ru" : { + "sa" : { "stringUnit" : { "state" : "translated", - "value" : "Нет" + "value" : "अङ्कान् वृत्ताकार-डिज़ाइन-रूपेण दर्शयति।" } } } }, - "Orange" : { + "Round digits" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "تدوير الأرقام" + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Orange" + "value" : "Ziffern runden" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Naranja" + "value" : "Redondear dígitos" } }, - "fr" : { + "fa" : { "stringUnit" : { "state" : "translated", - "value" : "Orange" + "value" : "گرد کردن ارقام" } }, - "ru" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Оранжевый" + "value" : "Arrondir les chiffres" } - } - } - }, - "Pink" : { - "localizations" : { - "de" : { + }, + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Rosa" + "value" : "עיגול ספרות" } }, - "es" : { + "hi" : { "stringUnit" : { "state" : "translated", - "value" : "Rosa" + "value" : "अंकों को गोल करें" } }, - "fr" : { + "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Rose" + "value" : "Скруглять цифры" } }, - "ru" : { + "sa" : { "stringUnit" : { "state" : "translated", - "value" : "Розовый" + "value" : "अङ्कानां वृत्ताकारः" } } } }, - "Purple" : { + "Seconds" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "ثوانٍ" + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Violett" + "value" : "Sekunden" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Morado" + "value" : "Segundos" } }, - "fr" : { + "fa" : { "stringUnit" : { "state" : "translated", - "value" : "Violet" + "value" : "ثانیه‌ها" } }, - "ru" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Фиолетовый" + "value" : "Secondes" } - } - } - }, - "Red" : { - "localizations" : { - "de" : { + }, + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Rot" + "value" : "שניות" } }, - "es" : { + "hi" : { "stringUnit" : { "state" : "translated", - "value" : "Rojo" + "value" : "सेकंड" } }, - "fr" : { + "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Rouge" + "value" : "Секунды" } }, - "ru" : { + "sa" : { "stringUnit" : { "state" : "translated", - "value" : "Красный" + "value" : "क्षणाः" } } } }, - "Renders the digits with the Rounded design." : { + "Sets the digit thickness from Ultra Light to Black." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "يحدّد سُمك الأرقام من رفيع جداً إلى أسود." + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Stellt die Ziffern im abgerundeten Design dar." + "value" : "Legt die Stärke der Ziffern von Ultraleicht bis Schwarz fest." } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Muestra los dígitos con el diseño Redondeado." + "value" : "Define el grosor de los dígitos, de Ultrafino a Negro." } }, - "fr" : { + "fa" : { "stringUnit" : { "state" : "translated", - "value" : "Affiche les chiffres avec le style arrondi." + "value" : "ضخامت ارقام را از خیلی روشن تا مشکی تنظیم می‌کند." } }, - "ru" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Отображает цифры со скруглённым начертанием." + "value" : "Définit l’épaisseur des chiffres, d’Ultrafine à Noire." } - } - } - }, - "Round digits" : { - "localizations" : { - "de" : { + }, + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Ziffern runden" + "value" : "מגדיר את עובי הספרות מבהיר במיוחד לשחור." } }, - "es" : { + "hi" : { "stringUnit" : { "state" : "translated", - "value" : "Redondear dígitos" + "value" : "डिजिट्स की मोटाई अल्ट्रा लाइट से ब्लैक तक सेट करता है।" } }, - "fr" : { + "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Arrondir les chiffres" + "value" : "Задаёт толщину цифр от сверхтонкой до чёрной." } }, - "ru" : { + "sa" : { "stringUnit" : { "state" : "translated", - "value" : "Скруглять цифры" + "value" : "अत्यन्तं सूक्ष्मतः कृष्णपर्यन्तं अङ्कानां स्थूलतां निर्धारयति।" } } } }, - "Seconds" : { + "Sets the numeral system used for the digits. Automatic follows your Mac's region." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "يحدّد نظام الأعداد المُستخدم للأرقام. يتبع الوضع التلقائي منطقة الـ Mac." + } + }, "de" : { "stringUnit" : { "state" : "translated", - "value" : "Sekunden" + "value" : "Legt das Zahlensystem für die Ziffern fest. Automatisch folgt der Region des Mac." } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Segundos" + "value" : "Define los números usados para los dígitos. Automático sigue la región del Mac." } }, - "fr" : { + "fa" : { "stringUnit" : { "state" : "translated", - "value" : "Secondes" + "value" : "سیستم ارقام مورد استفاده برای ارقام را تنظیم می‌کند. خودکار از منطقه مک شما پیروی می‌کند." } }, - "ru" : { + "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Секунды" + "value" : "Définit le système de numération utilisé pour les chiffres. Automatique suit la région du Mac." } - } - } - }, - "Sets the digit thickness from Ultra Light to Black." : { - "localizations" : { - "de" : { + }, + "he" : { "stringUnit" : { "state" : "translated", - "value" : "Legt die Stärke der Ziffern von Ultraleicht bis Schwarz fest." + "value" : "קובע את מערכת הספרות המשמשת את האותיות. אוטומטי עוקב אחר אזור ה-Mac שלך." } }, - "es" : { + "hi" : { "stringUnit" : { "state" : "translated", - "value" : "Define el grosor de los dígitos, de Ultrafino a Negro." + "value" : "अंकों के लिए उपयोग की जाने वाली अंक प्रणाली सेट करता है। स्वचालित आपके Mac के क्षेत्र का अनुसरण करता है।" } }, - "fr" : { + "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Définit l’épaisseur des chiffres, d’Ultrafine à Noire." + "value" : "Задаёт систему счисления для цифр. Автоматически следует региону Mac." } }, - "ru" : { + "sa" : { "stringUnit" : { "state" : "translated", - "value" : "Задаёт толщину цифр от сверхтонкой до чёрной." + "value" : "अङ्कानां कृते प्रयुक्तां अङ्कप्रणालीं निर्धारयति। स्वचालितं भवतः Mac-क्षेत्रस्य अनुसरणं करोति।" } } } }, "Show only digits, without any labels underneath." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "عرض الأرقام فقط، بدون تسميات أسفلها." + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1275,22 +3037,52 @@ "value" : "Mostrar solo los dígitos, sin etiquetas debajo." } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "فقط ارقام را نمایش بده، بدون برچسب زیر آن‌ها." + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Afficher uniquement les chiffres, sans étiquettes en dessous." } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הצג רק ספרות, ללא תוויות מתחת." + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "केवल अंक दिखाएं, नीचे कोई लेबल नहीं।" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Показывать только цифры, без подписей под ними." } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "केवलम् अङ्कान् दर्शय, अधः किमपि लेबलं नास्ति।" + } } } }, "The available range is one year before and after the current date." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "النطاق المتاح هو سنة واحدة قبل وبعد التاريخ الحالي." + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1303,22 +3095,52 @@ "value" : "El intervalo disponible es de un año antes y después de la fecha actual." } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "محدوده موجود یک سال قبل و بعد از تاریخ فعلی است." + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "La plage disponible est d’un an avant et après la date actuelle." } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הטווח הזמין הוא שנה אחת לפני ואחרי התאריך הנוכחי." + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "उपलब्ध सीमा वर्तमान तारीख से एक वर्ष पहले और बाद की है।" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Доступный диапазон — один год до и после текущей даты." } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "उपलब्धः परिसरः वर्तमानतिथेः एकवर्षपूर्वं च एकवर्षोत्तरं च अस्ति।" + } } } }, "Theme" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "السمة" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1331,22 +3153,52 @@ "value" : "Tema" } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "تم" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Thème" } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "ערכת נושא" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "थीम" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Тема" } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "विषयः" + } } } }, "Think of a cool idea for a screen saver title and write it here" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "فكّر في فكرة رائعة لعنوان شاشة التوقف واكتبها هنا" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1359,22 +3211,52 @@ "value" : "Piensa en una genial idea para el título y escríbelo aquí" } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "یک ایده عالی برای عنوان محافظ صفحه فکر کن و اینجا بنویس" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Trouvez un titre sympa pour l’économiseur d’écran et écrivez-le ici" } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "חשוב על רעיון מגניב לכותרת שומר המסך וכתוב אותו כאן" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "स्क्रीन सेवर के लिए एक शानदार शीर्षक का विचार करें और यहां लिखें" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Придумайте классный заголовок для заставки и напишите его здесь" } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "स्क्रीनसेवर-शीर्षकस्य कृते उत्तमं विचारं चिन्तय तत्र लिख।" + } } } }, "Time" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "الوقت" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1387,22 +3269,52 @@ "value" : "Hora" } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "زمان" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Heure" } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שעה" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "समय" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Время" } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "कालः" + } } } }, "Title" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "العنوان" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1415,22 +3327,52 @@ "value" : "Título" } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "عنوان" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Titre" } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "כותרת" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "शीर्षक" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Заголовок" } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "शीर्षकम्" + } } } }, "Weight" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "السمك" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1443,23 +3385,53 @@ "value" : "Grosor" } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "ضخامت" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Épaisseur" } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "עובי" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "मोटाई" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Толщина цифр" } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "स्थौल्यम्" + } } } }, "Weight.black" : { "extractionState" : "extracted_with_value", "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "أسود" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1478,23 +3450,53 @@ "value" : "Negro" } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "سیاه" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Noire" } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "שחור" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "काला (मोटाई)" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Чёрная" } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "कृष्णः" + } } } }, "Weight.bold" : { "extractionState" : "extracted_with_value", "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "عريض" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1513,23 +3515,53 @@ "value" : "Negrito" } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "ضخیم" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Grasse" } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "מודגש" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "मोटा" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Жирная" } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "स्थूलः" + } } } }, "Weight.heavy" : { "extractionState" : "extracted_with_value", "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "ثقيل" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1548,23 +3580,53 @@ "value" : "Grueso" } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "سنگین" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Lourde" } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "כבד" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "भारी" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Сверхжирная" } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "गुरुः" + } } } }, "Weight.light" : { "extractionState" : "extracted_with_value", "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "خفيف" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1583,23 +3645,53 @@ "value" : "Ligero" } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "سبک" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Légère" } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "קל" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "हल्का" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Светлая" } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "लघुः" + } } } }, "Weight.medium" : { "extractionState" : "extracted_with_value", "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "متوسط" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1618,23 +3710,53 @@ "value" : "Medio" } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "متوسط" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Moyenne" } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "בינוני" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "मध्यम (मोटाई)" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Средняя" } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "मध्यमः" + } } } }, "Weight.regular" : { "extractionState" : "extracted_with_value", "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "عادي" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1653,23 +3775,53 @@ "value" : "Normal" } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "معمولی" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Normale" } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "רגיל" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "नियमित" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Обычная" } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "सामान्यः" + } } } }, "Weight.semibold" : { "extractionState" : "extracted_with_value", "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "شبه عريض" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1688,23 +3840,53 @@ "value" : "Seminegrito" } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "نیمه‌ضخیم" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Demi-grasse" } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "בינוני-מודגש" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "अर्ध मोटा" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Полужирная" } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "अर्धस्थूलः" + } } } }, "Weight.thin" : { "extractionState" : "extracted_with_value", "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "رفيع" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1723,23 +3905,53 @@ "value" : "Fino" } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "نازک" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Fine" } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "דק" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "पतला" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Тонкая" } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "सूक्ष्मः" + } } } }, "Weight.ultraLight" : { "extractionState" : "extracted_with_value", "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "رفيع جداً" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1758,22 +3970,52 @@ "value" : "Ultrafino" } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "بسیار نازک" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Ultrafine" } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "דק במיוחד" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "अति पतला" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Сверхтонкая" } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "अतिसूक्ष्मः" + } } } }, "When the countdown reaches zero, it automatically switches to Stopwatch Mode and starts counting up." : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "عندما يصل العد التنازلي إلى الصفر، يتحول تلقائياً إلى وضع ساعة الإيقاف ويبدأ العد التصاعدي." + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1786,22 +4028,52 @@ "value" : "Cuando la cuenta atrás llega a cero, cambia automáticamente al modo Cronómetro y empieza a contar hacia arriba." } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "وقتی شمارش معکوس به صفر برسد، به طور خودکار به حالت کرونومتر تغییر می‌کند و شروع به شمارش رو به بالا می‌کند." + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Lorsque le compte à rebours atteint zéro, il passe automatiquement en mode Chronomètre et commence à compter le temps écoulé." } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "כאשר הספירה לאחור מגיעה לאפס, הוא עובר אוטומטית למצב שעון עצר ומתחיל לספור כלפי מעלה." + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "जब काउंटडाउन शून्य पर पहुंचे, तो यह स्वचालित रूप से स्टॉपवॉच मोड में बदल जाता है और ऊपर की ओर गिनना शुरू कर देता है।" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Когда отсчёт достигает нуля, автоматически включается режим секундомера и он начинает идти вперёд." } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "यदा गणना शून्यं प्राप्नोति, तदा स्वयमेव स्टॉपवॉच-मोडं प्राप्नोति ऊर्ध्वं गणयितुं च आरभते।" + } } } }, "White" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "أبيض" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1814,22 +4086,52 @@ "value" : "Blanco" } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "سفید" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Blanc" } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "לבן" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "सफेद" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Белый" } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "श्वेतः" + } } } }, "Yellow" : { "localizations" : { + "ar" : { + "stringUnit" : { + "state" : "translated", + "value" : "أصفر" + } + }, "de" : { "stringUnit" : { "state" : "translated", @@ -1842,20 +4144,44 @@ "value" : "Amarillo" } }, + "fa" : { + "stringUnit" : { + "state" : "translated", + "value" : "زرد" + } + }, "fr" : { "stringUnit" : { "state" : "translated", "value" : "Jaune" } }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "צהוב" + } + }, + "hi" : { + "stringUnit" : { + "state" : "translated", + "value" : "पीला" + } + }, "ru" : { "stringUnit" : { "state" : "translated", "value" : "Жёлтый" } + }, + "sa" : { + "stringUnit" : { + "state" : "translated", + "value" : "पीतः" + } } } } }, "version" : "1.2" -} +} \ No newline at end of file diff --git a/MinimalCountdown/Resources/Resources.swift b/MinimalCountdown/Resources/Resources.swift index c350193..90490a0 100644 --- a/MinimalCountdown/Resources/Resources.swift +++ b/MinimalCountdown/Resources/Resources.swift @@ -72,6 +72,14 @@ enum Resources { static let purple = LocalizedStringResource("Purple", bundle: .app) static let black = LocalizedStringResource("Black", bundle: .app) } + + enum NumeralSystem { + static let automatic = LocalizedStringResource("Automatic", bundle: .app) + static let latin = LocalizedStringResource("Latin", bundle: .app) + static let arabic = LocalizedStringResource("Arabic", bundle: .app) + static let persian = LocalizedStringResource("Persian", bundle: .app) + static let devanagari = LocalizedStringResource("Devanagari", bundle: .app) + } } enum Appearance { @@ -127,6 +135,11 @@ enum Resources { ) static let rounded = LocalizedStringResource("Round digits", bundle: .app) static let roundedHint = LocalizedStringResource("Renders the digits with the Rounded design.", bundle: .app) + static let numerals = LocalizedStringResource("Numerals", bundle: .app) + static let numeralsHint = LocalizedStringResource( + "Sets the numeral system used for the digits. Automatic follows your Mac's region.", + bundle: .app + ) } enum Title { diff --git a/MinimalCountdown/Views/CountdownRootView.swift b/MinimalCountdown/Views/CountdownRootView.swift index 1143ed0..c35a020 100644 --- a/MinimalCountdown/Views/CountdownRootView.swift +++ b/MinimalCountdown/Views/CountdownRootView.swift @@ -12,11 +12,13 @@ struct CountdownRootView: View { let isPreview: Bool @Environment(SettingsManager.self) private var settingsManager + @Environment(\.locale) private var locale var body: some View { CountdownWindow( now: clock.now, settings: settingsManager.settings, + locale: locale, isPreview: isPreview ) } diff --git a/MinimalCountdown/Views/CountdownView.swift b/MinimalCountdown/Views/CountdownView.swift index 4b26b4e..7d22fba 100644 --- a/MinimalCountdown/Views/CountdownView.swift +++ b/MinimalCountdown/Views/CountdownView.swift @@ -41,12 +41,13 @@ private extension CountdownView { } func digits(for style: AppearanceStyle) -> String { - switch style { - case .days: settings.schedule.target.daysString(relativeTo: now) - case .hours: settings.schedule.target.hoursString(relativeTo: now) - case .minutes: settings.schedule.target.minutesString(relativeTo: now) - case .seconds: settings.schedule.target.secondsString(relativeTo: now) + let value = switch style { + case .days: settings.schedule.target.days(relativeTo: now) + case .hours: settings.schedule.target.hours(relativeTo: now) + case .minutes: settings.schedule.target.minutes(relativeTo: now) + case .seconds: settings.schedule.target.seconds(relativeTo: now) } + return UIModel.formattedDigits(value, in: render.digitLocale) } } diff --git a/MinimalCountdown/Views/CountdownWindow.swift b/MinimalCountdown/Views/CountdownWindow.swift index 745fa02..b3835f9 100644 --- a/MinimalCountdown/Views/CountdownWindow.swift +++ b/MinimalCountdown/Views/CountdownWindow.swift @@ -9,40 +9,56 @@ import SwiftUI struct CountdownWindow: View { let now: Date - let settings: SaverSettings + var settings: SaverSettings + var locale: Locale = .current var isPreview: Bool = false + @State private var render: UIModel.RenderSettings? + @State private var titleText = String() var body: some View { - let render = UIModel.RenderSettings(settings) - let titleText = UIModel.formattedTitle(settings.title) - GeometryReader { geo in - let digitsSize = geo.size.width.digitsSize(isPreview: isPreview) - - ZStack { - settings.theme.background.color - .ignoresSafeArea() + settings.theme.background.color + .ignoresSafeArea() + if let render { VStack(spacing: .zero) { - TitleView( - element: .init( - text: titleText, - size: digitsSize * .titleToDigitsRatio, - color: render.textsColor, - weight: .thin - ) - ) - CountdownView( - now: now, - settings: settings, - render: render, - digitsSize: digitsSize, - spacing: geo.size.width * .elementsSpacingRatio - ) + showTitle(width: geo.size.width, with: render) + showCountdown(width: geo.size.width, with: render) } .frame(width: geo.size.width, height: geo.size.height) } } + .task(id: settings, applySettings) + } +} + +private extension CountdownWindow { + func applySettings() { + render = UIModel.RenderSettings(settings, locale: locale) + titleText = UIModel.formattedTitle(settings.title) + } + + func showTitle(width: CGFloat, with render: UIModel.RenderSettings) -> some View { + TitleView( + element: .init( + text: titleText, + size: width.digitsSize(isPreview: isPreview) * .titleToDigitsRatio, + color: render.textsColor, + weight: .thin + ) + ) + } + func showCountdown(width: CGFloat, with render: UIModel.RenderSettings) -> some View { + CountdownView( + now: now, + settings: settings, + render: render, + digitsSize: width.digitsSize(isPreview: isPreview), + spacing: width * .elementsSpacingRatio + ) + // The countdown is a clock/number — keep it left-to-right even under an RTL (Arabic) locale + // (HIG: don't reverse the digits in a number). The settings window still mirrors normally. + .environment(\.layoutDirection, .leftToRight) } } diff --git a/MinimalCountdown/Views/ElementView.swift b/MinimalCountdown/Views/ElementView.swift index 4f8d802..3482854 100644 --- a/MinimalCountdown/Views/ElementView.swift +++ b/MinimalCountdown/Views/ElementView.swift @@ -37,7 +37,7 @@ private extension ElementView { var labelElement: UIModel.TextElement? { element.render.isLabelHidden ? nil : .init( text: element.label, - size: element.size * .labelsToDigitsRatio, + size: element.size * (element.render.isNeedFixLabelSize ? .nonLatinLabelsToDigitsRatio : .labelsToDigitsRatio), color: element.render.textsColor ) } diff --git a/MinimalCountdown/Views/UIModel.swift b/MinimalCountdown/Views/UIModel.swift index 8e1e020..4385261 100644 --- a/MinimalCountdown/Views/UIModel.swift +++ b/MinimalCountdown/Views/UIModel.swift @@ -16,8 +16,10 @@ enum UIModel { let isLabelHidden: Bool let effect: EffectStyle let effectGlowColor: Color + let digitLocale: Locale + let isNeedFixLabelSize: Bool - init(_ settings: SaverSettings) { + init(_ settings: SaverSettings, locale: Locale = .autoupdatingCurrent) { let theme = settings.theme digitsColor = theme.accent.color.opacity(theme.brightness.digitsOpacity) textsColor = theme.accent.color.opacity(theme.brightness.textsOpacity) @@ -28,7 +30,17 @@ enum UIModel { // Glow dimmed by brightness, matching the digit fill: effectColor for glow, accent otherwise. effectGlowColor = (theme.effect == .glow ? theme.effectColor : theme.accent) .color.opacity(theme.brightness.digitsOpacity) + + // Numerals: an explicit pick overrides; `.automatic` falls back to the locale's own + // numbering system (UAE → Latin, Egypt → Arabic). + let numbering = settings.typography.numeralSystem.numberingSystem ?? locale.numberingSystem + var components = Locale.Components(locale: locale) + components.numberingSystem = numbering + digitLocale = Locale(components: components) + isNeedFixLabelSize = !nonCapitalizedLanguages.map { $0.contains(locale.identifier.lowercased()) }.isEmpty } + + private let nonCapitalizedLanguages = ["ar", "he", "fa"] } struct Element { @@ -54,6 +66,12 @@ enum UIModel { return words.joined(separator: separator) } + /// Countdown digit string: zero-padded (min 2, grows for 3-digit day counts) and rendered + /// in `locale`'s numeral system (the resolved `RenderSettings.digitLocale`). + static func formattedDigits(_ value: Int, in locale: Locale) -> String { + value.formatted(.number.precision(.integerLength(2...)).grouping(.never).locale(locale)) + } + /// Effect-section subtitle/tooltip: the base hint + a localized "or"-list of the available /// effect names (lowercased). static var effectsHint: String { diff --git a/MinimalDevApp/PreviewWindow.swift b/MinimalDevApp/PreviewWindow.swift index fa657dd..2ee9a1b 100644 --- a/MinimalDevApp/PreviewWindow.swift +++ b/MinimalDevApp/PreviewWindow.swift @@ -11,6 +11,7 @@ struct PreviewWindow: View { @Binding var isAnimating: Bool @Binding var isTestPreview: Bool @Environment(SettingsManager.self) private var settingsManager + @Environment(\.locale) private var locale var body: some View { if isAnimating { @@ -18,6 +19,7 @@ struct PreviewWindow: View { CountdownWindow( now: context.date, settings: settingsManager.settings, + locale: locale, isPreview: isTestPreview ) } @@ -25,24 +27,31 @@ struct PreviewWindow: View { CountdownWindow( now: Date(), settings: settingsManager.settings, + locale: locale, isPreview: isTestPreview ) } } } +#if DEBUG #Preview("Animated") { + @State @Previewable var manager = SettingsManager(saver: MockInMemoryLocalStore(initial: .preview)) PreviewWindow( isAnimating: .constant(true), isTestPreview: .constant(false) ) - .environment(SettingsManager(saver: MockInMemoryLocalStore(initial: .preview))) + .environment(manager) + .onAppear(perform: manager.load) } #Preview("Static") { + @State @Previewable var manager = SettingsManager(saver: MockInMemoryLocalStore(initial: .preview)) PreviewWindow( isAnimating: .constant(false), isTestPreview: .constant(false) ) - .environment(SettingsManager(saver: MockInMemoryLocalStore(initial: .preview))) + .environment(manager) + .onAppear(perform: manager.load) } +#endif