Skip to content

Commit 60e397d

Browse files
committed
Add RTL and additional website translations
1 parent 82ef03e commit 60e397d

10 files changed

Lines changed: 1144 additions & 13 deletions

File tree

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ Implemented now:
4646
Danish, Latin, Swiss German, Korean, Russian, Ukrainian, Flemish, Belgian
4747
French, Canadian French, Canadian English, Turkish, Lithuanian, Latvian,
4848
Polish, Greek, Hungarian, Estonian, Elfdalian, Bulgarian, Czech, Croatian,
49-
Belarusian, Irish, Luxembourgish, Romanian, and Serbian.
49+
Belarusian, Irish, Luxembourgish, Romanian, Serbian, Neapolitan, Slovak,
50+
Slovene, West Frisian, Northern Sami, Sicilian, Modern Standard Arabic,
51+
Emirati Arabic, Egyptian Arabic, and Saudi Arabic.
5052
- Local gates for formatting, clippy, tests, security invariants, dependency
5153
policy, RustSec advisories, local smoke testing, SBOM generation, and
5254
reproducible release builds.
@@ -305,6 +307,16 @@ other website locales use stable prefixes:
305307
- `/lb/` for Luxembourgish
306308
- `/ro/` for Romanian
307309
- `/sr/` for Serbian
310+
- `/nap/` for Neapolitan
311+
- `/sk/` for Slovak
312+
- `/sl/` for Slovene
313+
- `/fy/` for West Frisian
314+
- `/se/` for Northern Sami
315+
- `/scn/` for Sicilian
316+
- `/ar/` for Modern Standard Arabic
317+
- `/ar-ae/` for Emirati Arabic
318+
- `/ar-eg/` for Egyptian Arabic
319+
- `/ar-sa/` for Saudi Arabic
308320

309321
Locale configuration lives in [config/locales.toml](config/locales.toml), and
310322
translated website keys live in [config/i18n/keys](config/i18n/keys). The
@@ -314,6 +326,10 @@ identity values, and rendering parameters stay unchanged.
314326

315327
The Elfdalian (`/ovd/`) locale is a best-effort translation and should be
316328
reviewed by a native speaker before being treated as authoritative.
329+
The West Frisian (`/fy/`) and Northern Sami (`/se/`) locales are also
330+
best-effort translations and should be reviewed by native speakers.
331+
Arabic locales render right-to-left. API examples, generated URLs, and code
332+
snippets remain left-to-right so copied endpoint text stays readable.
317333

318334
## Testing And Release Evidence
319335

config/i18n/keys/ar-001.toml

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
locale_id = "ar-001"
2+
3+
[nav]
4+
help = "المساعدة"
5+
docs = "التوثيق"
6+
terms = "الشروط"
7+
privacy = "الخصوصية"
8+
repository = "المستودع"
9+
rust_crate = "حزمة Rust"
10+
11+
[language]
12+
selector_label = "اللغة"
13+
14+
[hero]
15+
eyebrow = "hashavatar.app"
16+
title = "إنشاء أفاتار عام خلال ثوان"
17+
description = "حوّل أي user id مبهم أو اسم مستخدم ثابت أو hash أحادي الاتجاه إلى avatar URL حتمي. اختر النمط والخلفية والحجم، ثم انسخ WebP URL أو نزّل النتيجة أو أنشئ رابط object-storage موقّعا."
18+
privacy_tip = "نصيحة للخصوصية: نقبل المعرّفات التي تشبه البريد الإلكتروني للسهولة، لكن استخدام id داخلي ثابت أو hash أحادي الاتجاه أفضل عندما تريد تقليل البيانات الشخصية في URL logs."
19+
20+
[form]
21+
identity = "الهوية"
22+
namespace_tenant = "Namespace Tenant"
23+
style_version = "إصدار النمط"
24+
avatar_type = "نوع الأفاتار"
25+
background = "الخلفية"
26+
accessory = "الملحق"
27+
accent_color = "لون التمييز"
28+
expression = "التعبير"
29+
shape = "الشكل"
30+
size = "الحجم"
31+
copy_url = "نسخ URL"
32+
copy_signed_link = "نسخ الرابط الموقّع"
33+
download = "تنزيل"
34+
open_raw = "فتح مباشرة"
35+
copied = "تم النسخ"
36+
copy_failed = "فشل النسخ"
37+
direct_url = "URL مباشر"
38+
signed_storage_link = "رابط تخزين موقّع"
39+
machine_readable_api = "API قابل للقراءة آليا"
40+
signed_unavailable = "فعّل إعدادات S3 على الخادم لاستخدام الروابط الموقّعة."
41+
signed_unavailable_runtime = "روابط التخزين الموقّعة غير متاحة إلى أن يتم إعداد S3 على الخادم."
42+
43+
[preview]
44+
api = "API"
45+
storage = "التخزين"
46+
storage_text = "S3 persistence اختياري مع presigned links عبر"
47+
cache = "Cache"
48+
cache_text = "cache headers طويلة ومناسبة لـ Cloudflare"
49+
tip = "نصيحة"
50+
tip_text = "كل URL حتمي، لذلك يمكنك تضمينه مباشرة في تطبيقك."
51+
presets = "أمثلة جاهزة"
52+
preset_suffix = "مثال"
53+
54+
[footer]
55+
copy = "hashavatar.app هو avatar API حتمي وخدمة عرض تجريبية مبنية على حزمة Rust مفتوحة المصدر hashavatar."
56+
57+
[pages.help]
58+
title = "المساعدة"
59+
description = "دليل تكامل لاستخدام hashavatar.app avatar API في web apps وfrontends وbackends."
60+
eyebrow = "دليل التكامل"
61+
lead = "استخدم hashavatar.app مباشرة من المتصفح أو من frontend أو backend. كل avatar URL حتمي، لذلك يعطي المعرّف نفسه والخيارات نفسها النتيجة نفسها دائما."
62+
basic_url = "URL أساسي"
63+
basic_url_text = "استخدم query endpoint عندما تريد image URL عاما وبسيطا."
64+
path_style = "Path Style URL"
65+
path_style_text = "استخدم صيغة path إذا كنت تفضل embed URLs أنظف."
66+
html_example = "مثال HTML"
67+
javascript_example = "مثال JavaScript"
68+
supported_parameters = "المعاملات المدعومة"
69+
style_layer_note = "تنطبق accessory وexpression layers على character-style families. أما object-style families مثل planet وrocket وpaws وmushroom وcactus وcupcake وpizza وicecream وdiamond وcoffee-cup وshield فتتم تسويتها إلى accessory=none وexpression=default."
70+
signed_storage_links = "روابط التخزين الموقّعة"
71+
signed_storage_links_text = "إذا كان هذا deployment يحتوي على object storage معد، فاطلب presigned storage link من /v1/avatar/link. يخزّن ذلك endpoint الكائن generated object ويعيد JSON يحتوي على signed URL وobject key وhashed cache key. لا تعرض avatar responses العادية signed-link metadata في response headers."
72+
open_source = "مفتوح المصدر"
73+
open_source_text = "مصدر الموقع العام موجود في API repository، ومحرك reusable avatar renderer منشور على crates.io."
74+
75+
[pages.docs]
76+
title = "التوثيق"
77+
description = "Reference documentation لـ hashavatar.app public avatar API وstorage link endpoint وnamespace-aware identity contract."
78+
eyebrow = "API Reference"
79+
lead = "هذا هو product-facing reference لـ public API. من المفترض أن تبقى identity وtenant وstyle version وavatar family وstyle options وsize وWebP output مستقرة ضمن major release."
80+
core_endpoints = "Core Endpoints"
81+
operational_endpoints = "Operational Endpoints"
82+
operational_text = "GET /healthz عام لاستخدام load balancers وuptime checks. أما GET /metrics فهو loopback-only ويعيد 404 للـ non-local peers."
83+
namespace_support = "دعم Namespace"
84+
namespace_text = "استخدم tenant وstyle_version لإبقاء visual identity spaces منفصلة بين المنتجات أو rollout phases."
85+
anonymous_ids = "معرّفات مجهولة"
86+
anonymous_text = "أرسل internal stable id أو one-way application hash بدلا من raw personal data."
87+
rate_limits = "Rate Limits"
88+
rate_limits_text = "تطبق public service حدود origin-side rate limits، مع حدود أشد على /v1/avatar/link وdirect avatar requests التي تستخدم persist=true و/og.png، لأن object storage writes وOpen Graph image rendering أعلى تكلفة من direct rendering."
89+
timeouts = "Timeouts"
90+
timeouts_text = "تخضع avatar generation وstorage operations إلى server-side timeouts حتى لا تستطيع الطلبات المكلفة احتكار origin بلا حد."
91+
errors = "الأخطاء"
92+
error_bad_request = "kind غير صالح، أو unsupported algorithm أو format، أو size، أو missing identity"
93+
error_timeout = "generation أو storage timeout"
94+
error_rate_limit = "rate limit exceeded"
95+
error_internal = "rendering أو storage failure"
96+
openapi = "OpenAPI"
97+
openapi_text = "لـ generated clients أو tooling، استخدم"
98+
99+
[pages.terms]
100+
title = "الشروط"
101+
description = "Best-effort service terms لـ public hashavatar.app avatar API وdemo website."
102+
eyebrow = "شروط الخدمة"
103+
lead = "تقدّم هذه public service لأغراض معلوماتية وعلى أساس best-effort. استخدمها فقط إذا كان هذا risk profile مناسبا لتطبيقك."
104+
no_warranty = "لا ضمان"
105+
no_warranty_text = "تقدّم هذه الخدمة وكل generated outputs كما هي as-is وبحسب التوفر as-available، من دون أي ضمانات. لا نعد بـ availability أو correctness أو fitness for a particular purpose أو uninterrupted operation أو compatibility with your systems."
106+
no_liability = "لا مسؤولية"
107+
no_liability_text = "لسنا مسؤولين عن downtime أو outages أو degraded performance أو broken links أو cache behavior أو lost data أو corrupted objects أو third-party provider failures أو أي damages مباشرة أو غير مباشرة ناتجة عن استخدامك للخدمة."
108+
fallback_text = "إذا كنت تعتمد على هذه الأفاتارات في production، فعليك تنفيذ fallback behavior وcaching strategy وavailability plan خاصة بك."
109+
acceptable_use = "الاستخدام المقبول"
110+
acceptable_use_text = "لا تستخدم الخدمة لإرهاق infrastructure أو تجاوز rate limits أو cache controls أو اختبار abusive traffic patterns أو تخزين illegal material عبر persistence features."
111+
changes = "التغييرات"
112+
changes_text = "قد نغيّر public service أو نحدها أو نعلّقها أو نوقفها في أي وقت ومن دون إشعار. قد تتغير public endpoints أو output details أو operational limits مع تطور الخدمة."
113+
legal_note = "هذه الصفحة operational guidance وليست legal advice. إذا احتجت إلى formal legal terms من أجل business deployment، فانشر reviewed version مناسبة لـ jurisdiction وoperator entity لديك."
114+
115+
[pages.privacy]
116+
title = "الخصوصية"
117+
description = "Privacy notice لـ hashavatar.app حول request data وlogs وoptional object storage behavior."
118+
eyebrow = "إشعار الخصوصية"
119+
lead = "الخدمة بسيطة عمدا، لكن public avatar API يستقبل بعض request data حتى يعمل. تشرح هذه الصفحة ذلك baseline العملي."
120+
receives = "ما تستقبله الخدمة"
121+
receives_identity = "opaque identifier الذي تضعه في request، مثل internal id أو username أو one-way hash"
122+
receives_parameters = "request parameters مثل avatar type وstyle options وsize وformat وbackground"
123+
receives_http_metadata = "standard HTTP metadata التي يعالجها server وreverse proxy وCDN، مثل IP address وuser agent وreferrer وrequest timing"
124+
stores = "ما يخزنه التطبيق نفسه"
125+
stores_text = "لا يتطلب التطبيق user accounts ولا يضبط application cookies افتراضيا. في basic request flow يولّد الأفاتار on demand ويعيده مباشرة."
126+
storage_text = "إذا كان object storage support مفعلا واستُخدم signed-link أو persistence route، فقد يتم تخزين generated avatar file وobject key في S3-compatible bucket المعد."
127+
telemetry = "Telemetry يحافظ على الخصوصية"
128+
telemetry_text = "إذا فعّل operator ميزة telemetry، يرسل التطبيق aggregate OpenTelemetry metrics عن page views وvisible page time ونقرات repository وcrate وdemo actions وavatar generation counts، مجمعة حسب bounded style choices مثل kind وbackground وaccessory وcolor وexpression وshape وsize bucket."
129+
telemetry_limits = "لا يتضمن telemetry أي raw identifiers أو tenant أو style namespace values أو IP addresses أو user agents أو referrers أو full URLs أو cookies أو free-form text. تقبل telemetry endpoints فقط allow-listed aggregate labels."
130+
logging = "السجلات والبنية التحتية"
131+
logging_text = "بحسب deployment، قد تحتفظ infrastructure components مثل nginx وCaddy وCloudflare وhosting providers أو S3-compatible storage بـ access logs وoperational metadata. هذه logs جزء من تشغيل public service وقد تحتوي على requested identifier إذا ظهر في URL."
132+
avoid = "ما ينبغي تجنب إرساله"
133+
avoid_text = "تُقبل email-shaped identifiers لأجل compatibility، لكن URLs قد تظهر في infrastructure logs. أرسل stable internal id أو one-way application hash عندما تريد تجنب وضع personal data في request URL."
134+
repository = "Repository وCrate"
135+
repository_text = "يمكنك مراجعة implementation في public API repository ومحرك reusable avatar renderer في Rust crate."

0 commit comments

Comments
 (0)