mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
0f4766e131
* fix(map): fit MapLibre routes reliably * fix(map): default planner map to world view * fix(map): only await route geometry when a route is actually pending The fit armed a pending route-refit slot on every fitKey change, even with no route drawn, and only ever cleared it when a route arrived. So a route toggled on much later — after the user had panned elsewhere — was mistaken for the awaited geometry and yanked the camera back, and only on the first toggle. Arm the slot only when a route is already on screen: updateRouteForDay lays down straight lines in the same batch as the fit and upgrades them to real geometry a moment later, so an empty route at fit time means none is coming. * fix(collections): open the empty collection map on the world view A collection with no mappable places centred on Paris, the same hardcoded default this branch removes everywhere else. * feat(map): open the map framed on its places A trip in Japan opened on the world view at 0,0 and only then animated a fitBounds flight across the planet — the hardcoded default was the map's answer to a question its own places already answer. Each renderer now derives its opening camera from the places it receives, at construction: MapView for Leaflet, MapViewGL for MapLibre and Mapbox (whose zoom runs one level below Leaflet's, measuring against a 512px world tile rather than 256px). Doing it at construction is what confines it to load — the map is built once, and by then the trip's places are in hand. Nothing recomputes it afterwards, so the camera stays where the user leaves it, and the opening fit stands down rather than overruling the gentler zoom a lone place opens at. A trip with no coordinates still falls back to the world view. Collections and the public shared-trip page frame themselves the same way. * refactor(settings): drop the default map centre and zoom Nothing reads them now that every map frames itself on its own places, and a home-city default was the wrong answer for the next trip on the other side of the world. The style preview keeps a fixed location of its own: it needs a city to show label density and 3D buildings, which open ocean cannot. * fix(map): frame the map the way each renderer can actually draw Two defects the unit tests missed and running the app exposed. MapLibre and Mapbox opened on Null Island at zoom 2 regardless of the places: the effect that mirrors an external centre prop onto the camera also ran on mount, so it jumped straight to the default nobody passed and threw away the camera the map had just been built with. It now only responds to actual changes, which is what it was for. Leaflet was unaffected — its controller already guarded on the centre changing. A trip spanning Sydney, Reykjavik and Santiago lost Sydney's marker entirely. The narrowest arc containing all three crosses the antimeridian, and framing there is only sound on a renderer that repeats the world: MapLibre and Mapbox draw a marker on whichever copy is nearest the camera, Leaflet draws one world and puts the marker at its absolute position — off-screen. Leaflet now spans the long way round, as L.latLngBounds would. The test that should have caught this wrapped the x-offset in its own projection helper, quietly assuming behaviour Leaflet does not have; it now models each renderer's real wrapping. --------- Co-authored-by: Azalea <noreply@aza.moe>
483 lines
36 KiB
TypeScript
483 lines
36 KiB
TypeScript
import type { TranslationStrings } from '../types';
|
|
|
|
const settings: TranslationStrings = {
|
|
'settings.title': 'الإعدادات',
|
|
'settings.subtitle': 'ضبط إعداداتك الشخصية',
|
|
'settings.tabs.display': 'العرض',
|
|
'settings.tabs.map': 'الخريطة',
|
|
'settings.tabs.notifications': 'الإشعارات',
|
|
'settings.tabs.integrations': 'التكاملات',
|
|
'settings.plugins.oauth.connected': 'متصل',
|
|
'settings.plugins.oauth.notConnected': 'غير متصل',
|
|
'settings.plugins.oauth.connect': 'اتصال',
|
|
'settings.plugins.oauth.disconnect': 'قطع الاتصال',
|
|
'settings.tabs.plugins': 'الإضافات',
|
|
'settings.plugins.title': 'إعدادات الإضافات',
|
|
'settings.plugins.subtitle': 'إعداداتك الشخصية للإضافات التي تستخدمها (مفاتيح API، التفضيلات).',
|
|
'settings.plugins.empty': 'لا توجد إضافات نشطة.',
|
|
'settings.plugins.saved': 'تم حفظ الإعدادات',
|
|
'settings.tabs.account': 'الحساب',
|
|
'settings.tabs.about': 'حول',
|
|
'settings.map': 'الخريطة',
|
|
'settings.mapTemplate': 'قالب الخريطة',
|
|
'settings.mapTemplatePlaceholder.select': 'اختر قالبًا...',
|
|
'settings.mapDefaultHint': 'اتركه فارغًا لاستخدام OpenStreetMap افتراضيًا',
|
|
'settings.mapHint': 'قالب URL لبلاطات الخريطة',
|
|
'settings.mapProvider': 'مزود الخريطة',
|
|
'settings.mapProviderHint': 'يؤثر على خرائط Trip Planner و Journey. يستخدم Atlas دائمًا Leaflet.',
|
|
'settings.mapLeafletSubtitle': '2D كلاسيكي، أي بلاطات نقطية',
|
|
'settings.mapMapboxSubtitle': 'بلاطات متجهية ومبانٍ ثلاثية الأبعاد وتضاريس',
|
|
'settings.mapMapLibreSubtitle': 'بلاطات متجهية من OpenFreeMap، بدون رمز',
|
|
'settings.mapExperimental': 'تجريبي',
|
|
'settings.mapMapboxToken': 'رمز وصول Mapbox',
|
|
'settings.mapMapboxTokenHint': 'الرمز العام (pk.*) من',
|
|
'settings.mapMapboxTokenLink': 'mapbox.com ← رموز الوصول',
|
|
'settings.mapStyle': 'نمط الخريطة',
|
|
'settings.mapStylePlaceholder': 'اختر نمط Mapbox',
|
|
'settings.mapStyleHint': 'إعداد مسبق أو عنوان URL mapbox://styles/USER/ID خاص بك',
|
|
'settings.mapOpenFreeMapStylePlaceholder': 'اختر نمط OpenFreeMap',
|
|
'settings.mapOpenFreeMapStyleHint': 'إعداد مسبق أو عنوان URL لنمط OpenFreeMap. تعمل أنماط OpenFreeMap بدون رمز.',
|
|
'settings.map3dBuildings': 'مبانٍ ثلاثية الأبعاد وتضاريس',
|
|
'settings.map3dHint': 'إمالة + مبانٍ ثلاثية الأبعاد حقيقية — يعمل مع كل نمط بما في ذلك الأقمار الصناعية.',
|
|
'settings.mapHighQuality': 'وضع الجودة العالية',
|
|
'settings.mapHighQualityHint': 'تحسين الحواف + إسقاط كروي لحواف أكثر حدة وعرض واقعي للعالم.',
|
|
'settings.mapHighQualityWarning': 'قد يؤثر على الأداء في الأجهزة الأقل قدرة.',
|
|
'settings.mapTipLabel': 'نصيحة:',
|
|
'settings.mapTip':
|
|
'انقر بزر الماوس الأيمن واسحب لتدوير/إمالة الخريطة. النقر الأوسط لإضافة مكان (النقر الأيمن مخصص للتدوير).',
|
|
'settings.saveMap': 'حفظ الخريطة',
|
|
'settings.apiKeys': 'مفاتيح API',
|
|
'settings.mapsKey': 'مفتاح Google Maps API',
|
|
'settings.mapsKeyHint': 'للبحث عن الأماكن. يتطلب Places API (New).',
|
|
'settings.weatherKey': 'مفتاح OpenWeatherMap API',
|
|
'settings.weatherKeyHint': 'لبيانات الطقس.',
|
|
'settings.keyPlaceholder': 'أدخل المفتاح...',
|
|
'settings.configured': 'مُعدّ',
|
|
'settings.saveKeys': 'حفظ المفاتيح',
|
|
'settings.display': 'العرض',
|
|
'settings.colorMode': 'نمط الألوان',
|
|
'settings.light': 'فاتح',
|
|
'settings.dark': 'داكن',
|
|
'settings.auto': 'تلقائي',
|
|
'settings.language': 'اللغة',
|
|
'settings.temperature': 'وحدة الحرارة',
|
|
'settings.distance': 'وحدة المسافة',
|
|
'settings.timeFormat': 'تنسيق الوقت',
|
|
'settings.bookingLabels': 'تسميات مسارات الحجوزات',
|
|
'settings.bookingLabelsHint': 'عرض أسماء المحطات/المطارات على الخريطة. عند الإيقاف، يتم عرض الرمز فقط.',
|
|
'settings.blurBookingCodes': 'إخفاء رموز الحجز',
|
|
'settings.aiAlwaysRetry': 'Always retry booking imports with AI',
|
|
'settings.aiAlwaysRetryHint': 'When a file cannot be read by the standard parser, automatically retry it with AI.',
|
|
'settings.optimizeFromAccommodation': 'تحسين المسار انطلاقًا من مكان الإقامة',
|
|
'settings.optimizeFromAccommodationHint':
|
|
'عند تحسين يوم ما، يبدأ المسار من الفندق الذي تستيقظ فيه وينتهي عند الفندق الذي تسجّل الوصول إليه في تلك الليلة.',
|
|
'settings.notifications': 'الإشعارات',
|
|
'settings.notifyTripInvite': 'دعوات الرحلات',
|
|
'settings.notifyBookingChange': 'تغييرات الحجز',
|
|
'settings.notifyTripReminder': 'تذكيرات الرحلات',
|
|
'settings.notifyTodoDue': 'مهمة مستحقة',
|
|
'settings.notifyVacayInvite': 'دعوات دمج الإجازات',
|
|
'settings.notifyPhotosShared': 'صور مشتركة (Immich)',
|
|
'settings.notifyCollabMessage': 'رسائل الدردشة (Collab)',
|
|
'settings.notifyPackingTagged': 'قائمة الأمتعة: التعيينات',
|
|
'settings.notifyWebhook': 'إشعارات Webhook',
|
|
'settings.notifyVersionAvailable': 'إصدار جديد متاح',
|
|
'settings.notificationPreferences.noChannels':
|
|
'لم يتم تكوين قنوات إشعارات. اطلب من المسؤول إعداد إشعارات البريد الإلكتروني أو webhook.',
|
|
'settings.webhookUrl.label': 'رابط Webhook',
|
|
'settings.webhookUrl.hint': 'أدخل رابط Webhook الخاص بـ Discord أو Slack أو المخصص لتلقي الإشعارات.',
|
|
'settings.webhookUrl.saved': 'تم حفظ رابط Webhook',
|
|
'settings.webhookUrl.test': 'اختبار',
|
|
'settings.webhookUrl.testSuccess': 'تم إرسال Webhook الاختباري بنجاح',
|
|
'settings.webhookUrl.testFailed': 'فشل إرسال Webhook الاختباري',
|
|
'settings.ntfyUrl.topicLabel': 'موضوع Ntfy',
|
|
'settings.ntfyUrl.serverLabel': 'عنوان URL خادم Ntfy (اختياري)',
|
|
'settings.ntfyUrl.hint':
|
|
'أدخل موضوع Ntfy الخاص بك لتلقي الإشعارات الفورية. اترك حقل الخادم فارغاً لاستخدام الإعداد الافتراضي الذي حدده المسؤول.',
|
|
'settings.ntfyUrl.tokenLabel': 'رمز الوصول (اختياري)',
|
|
'settings.ntfyUrl.tokenHint': 'مطلوب للمواضيع المحمية بكلمة مرور.',
|
|
'settings.ntfyUrl.saved': 'تم حفظ إعدادات Ntfy',
|
|
'settings.ntfyUrl.test': 'اختبار',
|
|
'settings.ntfyUrl.testSuccess': 'تم إرسال إشعار Ntfy التجريبي بنجاح',
|
|
'settings.ntfyUrl.testFailed': 'فشل إشعار Ntfy التجريبي',
|
|
'settings.ntfyUrl.tokenCleared': 'تم مسح رمز الوصول',
|
|
'settings.notificationsDisabled': 'الإشعارات غير مكوّنة. اطلب من المسؤول تفعيل إشعارات البريد الإلكتروني أو Webhook.',
|
|
'settings.notificationsActive': 'القناة النشطة',
|
|
'settings.notificationsManagedByAdmin': 'يتم تكوين أحداث الإشعارات بواسطة المسؤول.',
|
|
'settings.on': 'تشغيل',
|
|
'settings.off': 'إيقاف',
|
|
'settings.mcp.title': 'إعداد MCP',
|
|
'settings.mcp.endpoint': 'نقطة نهاية MCP',
|
|
'settings.mcp.clientConfig': 'إعداد العميل',
|
|
'settings.mcp.clientConfigHint':
|
|
'استبدل <your_token> برمز API من القائمة أدناه. قد يحتاج مسار npx إلى ضبط وفق نظامك (مثلاً C:\\PROGRA~1\\nodejs\\npx.cmd على Windows).',
|
|
'settings.mcp.clientConfigHintOAuth':
|
|
'استبدل <your_client_id> و<your_client_secret> ببيانات الاعتماد المعروضة في عميل OAuth 2.1 الذي أنشأته أعلاه. سيفتح mcp-remote متصفحك لإتمام التفويض في أول اتصال. قد يحتاج مسار npx إلى تعديل حسب نظامك (مثال: C:PROGRA~1\nodejs\npx.cmd على Windows).',
|
|
'settings.mcp.copy': 'نسخ',
|
|
'settings.mcp.copied': 'تم النسخ!',
|
|
'settings.mcp.apiTokens': 'رموز API',
|
|
'settings.mcp.createToken': 'إنشاء رمز جديد',
|
|
'settings.mcp.noTokens': 'لا توجد رموز بعد. أنشئ رمزاً للاتصال بعملاء MCP.',
|
|
'settings.mcp.tokenCreatedAt': 'أُنشئ',
|
|
'settings.mcp.tokenUsedAt': 'استُخدم',
|
|
'settings.mcp.deleteTokenTitle': 'حذف الرمز',
|
|
'settings.mcp.deleteTokenMessage': 'سيتوقف هذا الرمز عن العمل فوراً. أي عميل MCP يستخدمه سيفقد الوصول.',
|
|
'settings.mcp.modal.createTitle': 'إنشاء رمز API',
|
|
'settings.mcp.modal.tokenName': 'اسم الرمز',
|
|
'settings.mcp.modal.tokenNamePlaceholder': 'مثال: Claude Desktop، حاسوب العمل',
|
|
'settings.mcp.modal.creating': 'جارٍ الإنشاء…',
|
|
'settings.mcp.modal.create': 'إنشاء الرمز',
|
|
'settings.mcp.modal.createdTitle': 'تم إنشاء الرمز',
|
|
'settings.mcp.modal.createdWarning': 'سيُعرض هذا الرمز مرة واحدة فقط. انسخه واحفظه الآن — لا يمكن استرداده.',
|
|
'settings.mcp.modal.done': 'تم',
|
|
'settings.mcp.toast.created': 'تم إنشاء الرمز',
|
|
'settings.mcp.toast.createError': 'فشل إنشاء الرمز',
|
|
'settings.mcp.toast.deleted': 'تم حذف الرمز',
|
|
'settings.mcp.toast.deleteError': 'فشل حذف الرمز',
|
|
'settings.mcp.apiTokensDeprecated':
|
|
'رموز API قديمة وستُزال في إصدار مستقبلي. يُرجى استخدام عملاء OAuth 2.1 بدلاً منها.',
|
|
'settings.oauth.clients': 'عملاء OAuth 2.1',
|
|
'settings.oauth.clientsHint':
|
|
'سجّل عملاء OAuth 2.1 للسماح لتطبيقات MCP الخارجية (Claude Web وCursor وغيرها) بالاتصال دون رموز ثابتة.',
|
|
'settings.oauth.createClient': 'عميل جديد',
|
|
'settings.oauth.noClients': 'لا يوجد عملاء OAuth مسجلون.',
|
|
'settings.oauth.clientId': 'معرّف العميل',
|
|
'settings.oauth.clientSecret': 'سر العميل',
|
|
'settings.oauth.deleteClient': 'حذف العميل',
|
|
'settings.oauth.deleteClientMessage':
|
|
'سيتم حذف هذا العميل وجميع الجلسات النشطة بشكل دائم. ستفقد أي تطبيق يستخدمه وصوله فوراً.',
|
|
'settings.oauth.rotateSecret': 'تجديد السر',
|
|
'settings.oauth.rotateSecretMessage':
|
|
'سيتم إنشاء سر عميل جديد وإبطال جميع الجلسات الحالية فوراً. حدّث تطبيقك قبل إغلاق هذا الحوار.',
|
|
'settings.oauth.rotateSecretConfirm': 'تجديد',
|
|
'settings.oauth.rotateSecretConfirming': 'جارٍ التجديد…',
|
|
'settings.oauth.rotateSecretDoneTitle': 'تم إنشاء سر جديد',
|
|
'settings.oauth.rotateSecretDoneWarning':
|
|
'يُعرض هذا السر مرة واحدة فقط. انسخه الآن وحدّث تطبيقك — تم إبطال جميع الجلسات السابقة.',
|
|
'settings.oauth.activeSessions': 'جلسات OAuth النشطة',
|
|
'settings.oauth.sessionScopes': 'النطاقات',
|
|
'settings.oauth.sessionExpires': 'تنتهي',
|
|
'settings.oauth.revoke': 'إلغاء',
|
|
'settings.oauth.revokeSession': 'إلغاء الجلسة',
|
|
'settings.oauth.revokeSessionMessage': 'سيؤدي هذا إلى إلغاء الوصول لهذه الجلسة OAuth فوراً.',
|
|
'settings.oauth.modal.createTitle': 'تسجيل عميل OAuth',
|
|
'settings.oauth.modal.presets': 'إعدادات سريعة',
|
|
'settings.oauth.modal.clientName': 'اسم التطبيق',
|
|
'settings.oauth.modal.clientNamePlaceholder': 'مثال: Claude Web، تطبيق MCP الخاص بي',
|
|
'settings.oauth.modal.redirectUris': 'عناوين URI لإعادة التوجيه',
|
|
'settings.oauth.modal.redirectUrisHint': 'عنوان URI واحد لكل سطر. يُطلب HTTPS (localhost مستثنى). يُطبق تطابق دقيق.',
|
|
'settings.oauth.modal.scopes': 'النطاقات المسموح بها',
|
|
'settings.oauth.modal.scopesHint':
|
|
'list_trips وget_trip_summary متاحان دائماً — لا يُطلب نطاق. يساعدان الذكاء الاصطناعي في اكتشاف معرّفات الرحلات.',
|
|
'settings.oauth.modal.selectAll': 'تحديد الكل',
|
|
'settings.oauth.modal.deselectAll': 'إلغاء تحديد الكل',
|
|
'settings.oauth.modal.creating': 'جارٍ التسجيل…',
|
|
'settings.oauth.modal.create': 'تسجيل العميل',
|
|
'settings.oauth.modal.createdTitle': 'تم تسجيل العميل',
|
|
'settings.oauth.modal.createdWarning': 'يُعرض سر العميل مرة واحدة فقط. انسخه الآن — لا يمكن استرداده.',
|
|
'settings.oauth.toast.createError': 'فشل تسجيل عميل OAuth',
|
|
'settings.oauth.toast.deleted': 'تم حذف عميل OAuth',
|
|
'settings.oauth.toast.deleteError': 'فشل حذف عميل OAuth',
|
|
'settings.oauth.toast.revoked': 'تم إلغاء الجلسة',
|
|
'settings.oauth.toast.revokeError': 'فشل إلغاء الجلسة',
|
|
'settings.oauth.toast.rotateError': 'فشل تجديد سر العميل',
|
|
'settings.oauth.modal.machineClient': 'عميل آلي (بدون تسجيل دخول عبر المتصفح)',
|
|
'settings.oauth.modal.machineClientHint':
|
|
'استخدام منحة client_credentials — لا تحتاج إلى عناوين إعادة التوجيه. يُصدر الرمز المميز مباشرةً عبر client_id + client_secret ويعمل بصلاحياتك ضمن النطاقات المحددة.',
|
|
'settings.oauth.modal.machineClientUsage':
|
|
'للحصول على رمز مميز: POST /oauth/token مع grant_type=client_credentials وclient_id وclient_secret. بدون متصفح، بدون رمز تحديث.',
|
|
'settings.oauth.badge.machine': 'آلي',
|
|
'settings.account': 'الحساب',
|
|
'settings.about': 'حول',
|
|
'settings.about.reportBug': 'الإبلاغ عن خطأ',
|
|
'settings.about.reportBugHint': 'وجدت مشكلة؟ أخبرنا',
|
|
'settings.about.featureRequest': 'اقتراح ميزة',
|
|
'settings.about.featureRequestHint': 'اقترح ميزة جديدة',
|
|
'settings.about.wikiHint': 'التوثيق والأدلة',
|
|
'settings.about.supporters.badge': 'الداعمون الشهريون',
|
|
'settings.about.supporters.title': 'رفاق رحلة TREK',
|
|
'settings.about.supporters.subtitle':
|
|
'بينما تخطّط لمسارك التالي، يساعد هؤلاء الأشخاص في التخطيط لمستقبل TREK. تذهب مساهمتهم الشهرية مباشرةً إلى التطوير والساعات الفعلية المبذولة — حتى يظلّ TREK مفتوح المصدر.',
|
|
'settings.about.supporters.since': 'داعم منذ {date}',
|
|
'settings.about.supporters.tierEmpty': 'كن الأول',
|
|
'settings.about.description':
|
|
'TREK هو مخطط سفر مستضاف ذاتيًا يساعدك على تنظيم رحلاتك من أول فكرة حتى آخر ذكرى. تخطيط يومي، ميزانية، قوائم تعبئة، صور والمزيد — كل شيء في مكان واحد، على خادمك الخاص.',
|
|
'settings.about.madeWith': 'صُنع بـ',
|
|
'settings.about.madeBy': 'بواسطة موريس ومجتمع مفتوح المصدر متنامٍ.',
|
|
'settings.username': 'اسم المستخدم',
|
|
'settings.email': 'البريد الإلكتروني',
|
|
'settings.role': 'الدور',
|
|
'settings.roleAdmin': 'مسؤول',
|
|
'settings.oidcLinked': 'مرتبط مع',
|
|
'settings.changePassword': 'تغيير كلمة المرور',
|
|
'settings.currentPassword': 'كلمة المرور الحالية',
|
|
'settings.currentPasswordRequired': 'كلمة المرور الحالية مطلوبة',
|
|
'settings.newPassword': 'كلمة المرور الجديدة',
|
|
'settings.confirmPassword': 'تأكيد كلمة المرور الجديدة',
|
|
'settings.updatePassword': 'تحديث كلمة المرور',
|
|
'settings.passwordRequired': 'أدخل كلمة المرور الحالية والجديدة',
|
|
'settings.passwordTooShort': 'يجب أن تتكون كلمة المرور من 8 أحرف على الأقل',
|
|
'settings.passwordMismatch': 'كلمتا المرور غير متطابقتين',
|
|
'settings.passwordWeak': 'يجب أن تحتوي كلمة المرور على حرف كبير وحرف صغير ورقم ورمز خاص',
|
|
'settings.passwordChanged': 'تم تغيير كلمة المرور بنجاح',
|
|
'settings.mustChangePassword': 'يجب عليك تغيير كلمة المرور قبل المتابعة. يرجى تعيين كلمة مرور جديدة أدناه.',
|
|
'settings.deleteAccount': 'حذف الحساب',
|
|
'settings.deleteAccountTitle': 'هل تريد حذف حسابك؟',
|
|
'settings.deleteAccountWarning': 'سيتم حذف حسابك وجميع رحلاتك وأماكنك وملفاتك نهائيًا. لا يمكن التراجع عن ذلك.',
|
|
'settings.deleteAccountConfirm': 'حذف نهائي',
|
|
'settings.deleteBlockedTitle': 'الحذف غير ممكن',
|
|
'settings.deleteBlockedMessage': 'أنت المسؤول الوحيد. قم بترقية مستخدم آخر إلى مسؤول قبل حذف حسابك.',
|
|
'settings.roleUser': 'مستخدم',
|
|
'settings.saveProfile': 'حفظ الملف الشخصي',
|
|
'settings.toast.mapSaved': 'تم حفظ إعدادات الخريطة',
|
|
'settings.toast.keysSaved': 'تم حفظ مفاتيح API',
|
|
'settings.toast.displaySaved': 'تم حفظ إعدادات العرض',
|
|
'settings.toast.profileSaved': 'تم حفظ الملف الشخصي',
|
|
'settings.uploadAvatar': 'رفع صورة الملف الشخصي',
|
|
'settings.removeAvatar': 'إزالة صورة الملف الشخصي',
|
|
'settings.avatarUploaded': 'تم تحديث صورة الملف الشخصي',
|
|
'settings.avatarRemoved': 'تمت إزالة صورة الملف الشخصي',
|
|
'settings.avatarError': 'فشل الرفع',
|
|
'settings.mfa.title': 'المصادقة الثنائية (2FA)',
|
|
'settings.mfa.description':
|
|
'تضيف خطوة ثانية عند تسجيل الدخول. استخدم تطبيق مصادقة (Google Authenticator، Authy، إلخ).',
|
|
'settings.mfa.requiredByPolicy': 'المسؤول يتطلب المصادقة الثنائية. اضبط تطبيق المصادقة أدناه قبل المتابعة.',
|
|
'settings.mfa.backupTitle': 'رموز النسخ الاحتياطي',
|
|
'settings.mfa.backupDescription': 'استخدم هذه الرموز لمرة واحدة إذا فقدت الوصول إلى تطبيق المصادقة.',
|
|
'settings.mfa.backupWarning': 'احفظ هذه الرموز الآن. كل رمز يمكن استخدامه مرة واحدة فقط.',
|
|
'settings.mfa.backupCopy': 'نسخ الرموز',
|
|
'settings.mfa.backupDownload': 'تنزيل TXT',
|
|
'settings.mfa.backupPrint': 'طباعة / PDF',
|
|
'settings.mfa.backupCopied': 'تم نسخ رموز النسخ الاحتياطي',
|
|
'settings.mfa.enabled': 'المصادقة الثنائية مفعّلة على حسابك.',
|
|
'settings.mfa.disabled': 'المصادقة الثنائية غير مفعّلة.',
|
|
'settings.mfa.setup': 'إعداد المصادقة',
|
|
'settings.mfa.scanQr': 'امسح رمز QR بتطبيقك أو أدخل المفتاح يدويًا.',
|
|
'settings.mfa.secretLabel': 'المفتاح السري (إدخال يدوي)',
|
|
'settings.mfa.codePlaceholder': 'رمز من 6 أرقام',
|
|
'settings.mfa.enable': 'تفعيل 2FA',
|
|
'settings.mfa.cancelSetup': 'إلغاء',
|
|
'settings.mfa.disableTitle': 'تعطيل 2FA',
|
|
'settings.mfa.disableHint': 'أدخل كلمة مرور حسابك ورمزًا حاليًا من المصادقة.',
|
|
'settings.mfa.disable': 'تعطيل 2FA',
|
|
'settings.mfa.toastEnabled': 'تم تفعيل المصادقة الثنائية',
|
|
'settings.mfa.toastDisabled': 'تم تعطيل المصادقة الثنائية',
|
|
'settings.mfa.demoBlocked': 'غير متاح في الوضع التجريبي',
|
|
'settings.tabs.offline': 'Offline', // en-fallback
|
|
'settings.mapTemplatePlaceholder': 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', // en-fallback
|
|
'settings.notificationPreferences.email': 'Email', // en-fallback
|
|
'settings.notificationPreferences.webhook': 'Webhook', // en-fallback
|
|
'settings.notificationPreferences.inapp': 'In-App', // en-fallback
|
|
'settings.notificationPreferences.notConfigured': 'لم يتم الإعداد بعد — قم بإعداده من إعدادات الإضافة',
|
|
'settings.plugins.actions': 'الإجراءات',
|
|
'settings.plugins.actions.confirm': 'تنفيذ هذا الإجراء؟',
|
|
'settings.notificationPreferences.sendTest': 'إرسال اختبار',
|
|
'settings.notificationPreferences.configure': 'تهيئة',
|
|
'settings.notificationPreferences.testSuccess': 'تم إرسال إشعار اختباري.',
|
|
'settings.notificationPreferences.testFailed': 'فشل الاختبار.',
|
|
'settings.notificationPreferences.pluginConfigured': 'تم الإعداد. أدر بيانات الاعتماد من صفحة إعدادات الإضافة.',
|
|
'settings.notificationPreferences.ntfy': 'Ntfy', // en-fallback
|
|
'settings.webhookUrl.placeholder': 'https://discord.com/api/webhooks/...', // en-fallback
|
|
'settings.ntfyUrl.topicPlaceholder': 'my-trek-alerts', // en-fallback
|
|
'settings.ntfyUrl.serverPlaceholder': 'https://ntfy.sh', // en-fallback
|
|
'settings.oauth.modal.redirectUrisPlaceholder': 'https://your-app.com/callback\nhttps://your-app.com/auth', // en-fallback
|
|
'settings.about.supporter.tier.noReturnTicket': 'No Return Ticket', // en-fallback
|
|
'settings.about.supporter.tier.lostLuggageVip': 'Lost Luggage VIP', // en-fallback
|
|
'settings.about.supporter.tier.businessClassDreamer': 'Business Class Dreamer', // en-fallback
|
|
'settings.about.supporter.tier.budgetTraveller': 'Budget Traveller', // en-fallback
|
|
'settings.about.supporter.tier.hostelBunkmate': 'Hostel Bunkmate', // en-fallback
|
|
'settings.currency': 'Currency',
|
|
'settings.currencyHint': 'All amounts in Costs are converted to and shown in this currency.',
|
|
'settings.currencyTrip': 'عملة الرحلة',
|
|
'settings.passkey.title': 'مفاتيح المرور',
|
|
'settings.passkey.description':
|
|
'سجّل الدخول بشكل أسرع وأكثر مقاومة للتصيّد باستخدام مفتاح مرور — ببصمة إصبعك أو وجهك أو رمز PIN أو مفتاح أمان مادي. تبقى كلمة المرور كنسخة احتياطية.',
|
|
'settings.passkey.notConfigured':
|
|
'مفاتيح المرور مفعّلة لكنها لم تُهيّأ بالكامل على هذا الخادم بعد. اطلب من المسؤول تعيين نطاق WebAuthn.',
|
|
'settings.passkey.add': 'إضافة مفتاح مرور',
|
|
'settings.passkey.addTitle': 'إضافة مفتاح مرور',
|
|
'settings.passkey.passwordPrompt': 'أكّد كلمة المرور الحالية، ثم اتبع التعليمات على جهازك.',
|
|
'settings.passkey.passwordRequired': 'كلمة المرور الحالية مطلوبة.',
|
|
'settings.passkey.namePlaceholder': 'الاسم (اختياري، مثل "iPhone")',
|
|
'settings.passkey.addedToast': 'تمت إضافة مفتاح المرور',
|
|
'settings.passkey.added': 'تمت الإضافة',
|
|
'settings.passkey.addError': 'تعذّرت إضافة مفتاح المرور',
|
|
'settings.passkey.cancelled': 'تم إلغاء إعداد مفتاح المرور',
|
|
'settings.passkey.deleted': 'تمت إزالة مفتاح المرور',
|
|
'settings.passkey.deleteConfirm': 'إزالة مفتاح المرور هذا؟ أكّد بكلمة المرور الخاصة بك.',
|
|
'settings.passkey.rename': 'إعادة التسمية',
|
|
'settings.passkey.defaultName': 'مفتاح المرور',
|
|
'settings.passkey.synced': 'متزامن',
|
|
'settings.passkey.deviceBound': 'هذا الجهاز',
|
|
'settings.passkey.lastUsed': 'آخر استخدام',
|
|
'settings.passkey.neverUsed': 'لم يُستخدم قط',
|
|
'settings.mapPoiPill': 'استكشاف الأماكن على الخريطة',
|
|
'settings.mapPoiPillHint':
|
|
'أظهر شريط فئات على خريطة الرحلة للعثور على المطاعم والفنادق والمزيد القريبة من OpenStreetMap.',
|
|
'settings.airtrail.title': 'AirTrail',
|
|
'settings.airtrail.hint':
|
|
'اربط نسخة AirTrail المُستضافة ذاتيًا لاستيراد الرحلات ومزامنتها. أنشئ مفتاح API في AirTrail ضمن الإعدادات ← الأمان.',
|
|
'settings.airtrail.url': 'رابط النسخة',
|
|
'settings.airtrail.apiKey': 'مفتاح API',
|
|
'settings.airtrail.apiKeyPlaceholder': 'مفتاح API من نوع Bearer',
|
|
'settings.airtrail.apiKeyHint': 'يُنشأ في AirTrail ضمن الإعدادات ← الأمان. يُخزَّن مشفّرًا.',
|
|
'settings.airtrail.allowInsecureTls': 'السماح بالشهادات الموقّعة ذاتيًا',
|
|
'settings.airtrail.allowInsecureTlsHint': 'فعّل هذا فقط لنسخة موثوقة على شبكتك الخاصة.',
|
|
'settings.airtrail.writeBack': 'كتابة التغييرات إلى AirTrail',
|
|
'settings.airtrail.writeBackHint':
|
|
'مُعطّل افتراضيًا: AirTrail هو مصدر الحقيقة وTREK يقرأ منه فقط. فعّله لإرسال التعديلات التي تجريها في TREK إلى AirTrail.',
|
|
'settings.airtrail.connected': 'متصل',
|
|
'settings.airtrail.notConnected': 'غير متصل',
|
|
'settings.airtrail.toast.saved': 'تم حفظ اتصال AirTrail',
|
|
'settings.airtrail.toast.saveError': 'تعذّر حفظ الاتصال',
|
|
'settings.airtrail.test.button': 'اختبار الاتصال',
|
|
'settings.airtrail.test.success': 'متصل — تم العثور على {count} رحلة/رحلات',
|
|
'settings.airtrail.test.failed': 'فشل الاتصال',
|
|
'settings.aiParsing.title': 'التحليل بالذكاء الاصطناعي',
|
|
'settings.aiParsing.hint':
|
|
'استخدم نموذج الذكاء الاصطناعي الخاص بك لاستخراج الحجوزات من الملفات المرفوعة. لا يسري هذا إلا عندما لا يكون المسؤول قد أعدّ نموذجًا للنظام بأكمله.',
|
|
'settings.aiParsing.provider': 'المزوّد',
|
|
'settings.aiParsing.providerLocal': 'محلي (Ollama)',
|
|
'settings.aiParsing.providerOpenai': 'OpenAI',
|
|
'settings.aiParsing.providerAnthropic': 'Anthropic',
|
|
'settings.aiParsing.model': 'النموذج',
|
|
'settings.aiParsing.baseUrl': 'عنوان URL الأساسي',
|
|
'settings.aiParsing.baseUrlHint': 'المكان الذي يعمل فيه النموذج — خادم Ollama محلي أو نقطة نهاية متوافقة مع OpenAI.',
|
|
'settings.aiParsing.apiKey': 'مفتاح API',
|
|
'settings.aiParsing.apiKeyHint': 'يُخزَّن مشفّرًا. اتركه فارغًا للإبقاء على المفتاح الحالي.',
|
|
'settings.aiParsing.multimodal': 'إرسال المستندات كصور',
|
|
'settings.aiParsing.multimodalHint': 'للنماذج القادرة على الرؤية — يرسل ملف PDF الأصلي بدلًا من النص المستخرج.',
|
|
'settings.aiParsing.toast.saved': 'تم حفظ إعدادات الذكاء الاصطناعي',
|
|
'settings.aiParsing.toast.saveError': 'تعذّر حفظ إعدادات الذكاء الاصطناعي',
|
|
'settings.tabs.appearance': 'Appearance',
|
|
'settings.appearance.theme': 'Theme',
|
|
'settings.appearance.scheme': 'Color scheme',
|
|
'settings.appearance.scheme.default': 'Default',
|
|
'settings.appearance.scheme.highContrast': 'High contrast',
|
|
'settings.appearance.scheme.indigo': 'Indigo',
|
|
'settings.appearance.scheme.teal': 'Teal',
|
|
'settings.appearance.scheme.rose': 'Rose',
|
|
'settings.appearance.scheme.amber': 'Amber',
|
|
'settings.appearance.scheme.violet': 'Violet',
|
|
'settings.appearance.scheme.custom': 'Custom',
|
|
'settings.appearance.customAccent': 'Custom accent',
|
|
'settings.appearance.contrastOk': 'Good contrast',
|
|
'settings.appearance.contrastLow': 'Low contrast',
|
|
'settings.appearance.readability': 'Readability',
|
|
'settings.appearance.transparency': 'Transparency',
|
|
'settings.appearance.transparencyHint':
|
|
'Glassy translucent surfaces. Turn off for solid, higher-contrast backgrounds.',
|
|
'settings.appearance.reduceMotion': 'Reduce motion',
|
|
'settings.appearance.reduceMotionHint': 'Minimize animations and transitions.',
|
|
'settings.appearance.density': 'Density',
|
|
'settings.appearance.comfortable': 'Comfortable',
|
|
'settings.appearance.compact': 'Compact',
|
|
'settings.appearance.textSize': 'Text size',
|
|
'settings.appearance.advancedTextSizes': 'Advanced text sizes',
|
|
'settings.appearance.hideAdvanced': 'Hide advanced',
|
|
'settings.appearance.tier.title': 'Titles',
|
|
'settings.appearance.tier.subtitle': 'Subtitles',
|
|
'settings.appearance.tier.body': 'Body',
|
|
'settings.appearance.tier.caption': 'Captions',
|
|
'settings.appearance.dashboardWidgets': 'Dashboard widgets',
|
|
'settings.appearance.dashboardWidgetsHint': 'Show or hide dashboard widgets independently on desktop and mobile.',
|
|
'settings.appearance.desktop': 'Desktop',
|
|
'settings.appearance.mobile': 'Mobile',
|
|
'settings.appearance.widget.sidebar': 'Right sidebar',
|
|
'settings.appearance.widget.currency': 'Currency',
|
|
'settings.appearance.widget.collections': 'المجموعات',
|
|
'settings.appearance.widget.timezones': 'Timezones',
|
|
'settings.appearance.widget.upcomingReservations': 'Upcoming reservations',
|
|
'settings.appearance.widget.atlas': 'Atlas / countries',
|
|
'settings.appearance.widget.tripsTotal': 'Trips total',
|
|
'settings.appearance.widget.daysTraveled': 'Days traveled',
|
|
'settings.appearance.widget.distanceFlown': 'Distance flown',
|
|
'settings.appearance.reset': 'Reset to defaults',
|
|
'settings.appearance.group.belowHero': 'Below the hero',
|
|
'settings.appearance.group.bottomOfPage': 'Bottom of page',
|
|
'settings.appearance.sidebarHint': 'The whole right column. Turn off and the dashboard centers.',
|
|
'settings.appearance.densityHint':
|
|
'Compact tightens spacing and padding for a denser layout that fits more on screen.',
|
|
'settings.appearance.textSizeAll': 'Everything',
|
|
'settings.appearance.perSize': 'Adjust each size separately',
|
|
'settings.appearance.size.large': 'Large',
|
|
'settings.appearance.size.medium': 'Medium',
|
|
'settings.appearance.size.normal': 'Normal',
|
|
'settings.appearance.size.small': 'Small',
|
|
'settings.appearance.preview.large': 'Large heading',
|
|
'settings.appearance.preview.medium': 'Medium subtitle',
|
|
'settings.appearance.preview.normal': 'Normal body text',
|
|
'settings.appearance.preview.small': 'Small caption / address',
|
|
'settings.appearance.example.large': 'Headings, big numbers',
|
|
'settings.appearance.example.medium': 'Sub-headings',
|
|
'settings.appearance.example.normal': 'Place names, descriptions',
|
|
'settings.appearance.example.small': 'Addresses, labels',
|
|
'settings.appearance.experimental': 'Experimental',
|
|
'settings.general.languageRegion': 'Language & region',
|
|
'settings.general.travelMap': 'Travel & map',
|
|
|
|
// ── Offline (#1135)
|
|
'settings.offline.cache.title': 'ذاكرة التخزين المؤقت دون اتصال',
|
|
'settings.offline.mode.title': 'وضع عدم الاتصال',
|
|
'settings.offline.mode.force': 'فرض وضع عدم الاتصال',
|
|
'settings.offline.mode.forceHint':
|
|
'اعمل من البيانات المخزّنة مؤقتًا فقط وضع تغييراتك في قائمة الانتظار. أوقفه لإعادة الاتصال والمزامنة.',
|
|
'settings.offline.mode.active': 'وضع عدم الاتصال مفعّل — تغييراتك في قائمة الانتظار وستتم مزامنتها عند إيقافه.',
|
|
'settings.offline.prepare.title': 'التحضير للعمل دون اتصال',
|
|
'settings.offline.prepare.hint':
|
|
'نزّل كل ما تحتاجه — بيانات الرحلة والمستندات وبلاطات الخريطة — قبل أن تفقد الاتصال.',
|
|
'settings.offline.prepare.button': 'تنزيل للاستخدام دون اتصال',
|
|
'settings.offline.prepare.running': 'جارٍ التنزيل…',
|
|
'settings.offline.prepare.done': 'جاهز للاستخدام دون اتصال',
|
|
'settings.offline.prepare.phase.trips': 'بيانات الرحلة',
|
|
'settings.offline.prepare.phase.files': 'المستندات',
|
|
'settings.offline.prepare.phase.tiles': 'بلاطات الخريطة',
|
|
'settings.offline.resync': 'أعد المزامنة الآن',
|
|
'settings.offline.resyncing': 'جارٍ المزامنة…',
|
|
'settings.offline.storage.title': 'ما يتم تخزينه دون اتصال',
|
|
'settings.offline.storage.tiles': 'تخزين بلاطات الخريطة دون اتصال',
|
|
'settings.offline.storage.tilesHint':
|
|
'تستهلك بلاطات الخريطة أكبر مساحة تخزين. أوقف هذا للاحتفاظ ببيانات الرحلة والمستندات فقط دون اتصال.',
|
|
'settings.offline.storage.tripsTitle': 'الرحلات',
|
|
'settings.offline.storage.tripOn': 'مخزّن دون اتصال',
|
|
'settings.offline.storage.tripOff': 'غير مخزّن',
|
|
'settings.offline.clear': 'مسح ذاكرة التخزين المؤقت',
|
|
'settings.offline.clearConfirm':
|
|
'هل تريد مسح جميع بيانات الرحلة المخزّنة دون اتصال؟ يمكنك إعادة المزامنة في أي وقت أثناء الاتصال.',
|
|
'settings.offline.stats.trips': 'الرحلات المخزّنة مؤقتًا',
|
|
'settings.offline.stats.pending': 'تغييرات معلّقة',
|
|
'settings.offline.stats.failed': 'تغييرات فاشلة',
|
|
'settings.offline.stats.conflicts': 'تعارضات',
|
|
'settings.offline.empty': 'لا توجد رحلات مخزّنة بعد. اتصل بالإنترنت للمزامنة.',
|
|
'settings.offline.loading': 'جارٍ التحميل…',
|
|
'settings.offline.conflicts.title': 'تعارضات المزامنة',
|
|
'settings.offline.conflicts.hint':
|
|
'تتعارض التغييرات التي أجريتها دون اتصال مع تغييرات أحدث على الخادم. اختر الإصدار الذي تريد الاحتفاظ به.',
|
|
'settings.offline.conflicts.keepMine': 'الاحتفاظ بنسختي',
|
|
'settings.offline.conflicts.keepServer': 'الاحتفاظ بنسخة الخادم',
|
|
'settings.offline.conflicts.mine': 'نسختك',
|
|
'settings.offline.conflicts.server': 'نسخة الخادم',
|
|
'settings.offline.conflicts.item': 'تغيير على “{name}”',
|
|
'settings.offline.conflicts.strategyTitle': 'عند حدوث تعارض',
|
|
'settings.offline.conflicts.strategy.ask': 'اسألني في كل مرة',
|
|
'settings.offline.conflicts.strategy.mine': 'الاحتفاظ بنسختي دائمًا',
|
|
'settings.offline.conflicts.strategy.server': 'الاحتفاظ بنسخة الخادم دائمًا',
|
|
'settings.offline.banner.offline': 'دون اتصال',
|
|
'settings.offline.banner.forced': 'وضع عدم الاتصال',
|
|
'settings.offline.banner.queued': 'دون اتصال · {count} في قائمة الانتظار',
|
|
'settings.offline.banner.syncing': 'جارٍ مزامنة {count}…',
|
|
'settings.offline.banner.failed': 'فشلت المزامنة: {count}',
|
|
'settings.offline.banner.conflicts': 'تعارضات: {count}',
|
|
'settings.pluginActivity.title': 'نشاط الإضافات',
|
|
'settings.pluginActivity.description': 'كل إجراء نفّذته إضافة نيابةً عنك، الأحدث أولاً.',
|
|
'settings.pluginActivity.empty': 'لا يوجد نشاط للإضافات بعد.',
|
|
'settings.pluginActivity.refresh': 'تحديث',
|
|
'settings.pluginActivity.columns.plugin': 'الإضافة',
|
|
'settings.pluginActivity.columns.action': 'الإجراء',
|
|
'settings.pluginActivity.columns.resource': 'المورد',
|
|
'settings.pluginActivity.columns.when': 'الوقت',
|
|
'settings.pluginActivity.columns.status': 'النتيجة',
|
|
};
|
|
|
|
export default settings;
|