feat(transit): let an admin route transit search through Google

Transitous has no GTFS coverage for much of Asia, so a search between two
Osaka subway stops finds nothing — the stops are not in the feed at all.
Add Google as an optional backend behind an admin setting, reusing the
install's existing Places key, and fall back to Transitous whenever no
key resolves.

Uses the Routes API rather than the legacy Directions endpoint the
request named: every other Google call here already speaks the
v1/X-Goog-Api-Key family, and Google closed the legacy endpoint to Cloud
projects created after March 2025.

Google returns walking as turn-by-turn navigation steps where MOTIS
returns one leg per walking segment, so consecutive walk steps are
coalesced into a single leg — otherwise a finely-sliced walk pushed a
real journey past the 20-leg cap and the whole itinerary was dropped.

Both responses now name the backend that answered. The fallback is
silent by design, which left an empty result ambiguous between "no data
here" and "the provider you picked never ran", and the admin panel warns
when Google is selected but no key resolves — or when only the admin's
own key is set, which serves them and nobody else.

Cost shaped the implementation, since Google bills where Transitous does
not: both field masks are cut to the cheapest SKU tier that still
answers the question, cache TTLs are longer than the Transitous path's,
and route alternatives ride along inside the already-billed request.

Addresses #1699
This commit is contained in:
Konstantinos Thermos
2026-09-03 19:35:23 +03:00
committed by Maurice
parent 8e2840b29d
commit 2a0ceb2687
72 changed files with 2065 additions and 35 deletions
+25
View File
@@ -110,3 +110,28 @@ export const adminTestNotificationRequestSchema = z.object({
inApp: z.union([z.boolean(), z.record(z.string(), z.unknown())]).optional(),
});
export type AdminTestNotificationRequest = z.infer<typeof adminTestNotificationRequestSchema>;
// Which backend answers /api/transit (#1699). Transitous stays the default and
// the fallback: it is free and keyless, so an install that never opens this
// switch — or that picks Google without a key — keeps costing nothing.
export const TRANSIT_PROVIDERS = ['transitous', 'google'] as const;
export type TransitProvider = (typeof TRANSIT_PROVIDERS)[number];
export const adminTransitProviderRequestSchema = z.object({
provider: z.enum(TRANSIT_PROVIDERS),
});
export type AdminTransitProviderRequest = z.infer<typeof adminTransitProviderRequestSchema>;
/**
* Which of the three credential slots a third-party key resolved out of —
* operator env, the instance-wide row, or the caller's own. The server's
* ApiKeySource aliases this rather than restating it: the admin transit
* response puts the value on the wire, and two copies of the union would be
* exactly the hand-mirrored contract the project forbids.
*
* `null` on the wire means no key resolved at all.
*/
export const API_KEY_SOURCES = ['operator-env', 'instance', 'user-row'] as const;
export type ApiKeySource = (typeof API_KEY_SOURCES)[number];
/** The nullable form the admin transit-provider response carries. */
export type TransitKeySource = ApiKeySource | null;
+8
View File
@@ -145,6 +145,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': 'إثراء الأماكن',
'admin.placesEnrich.subtitle':
'يعرض صورًا ووصفًا أثناء إضافة مكان. تُستخدم ويكيبيديا وOpenStreetMap دائمًا، وتُضاف Google عند تفعيل صور الأماكن أو تفاصيل الأماكن.',
'admin.transitProvider.title': 'مزود النقل العام',
'admin.transitProvider.subtitle': 'الخدمة التي تجيب على بحث النقل العام.',
'admin.transitProvider.transitous': 'Transitous (مجاني)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'تغذيات GTFS مجتمعية. مجانية وبدون مفتاح، وأفضل تغطية في أوروبا.',
'admin.transitProvider.googleHint': 'يستخدم مفتاح Google أعلاه للمناطق التي لا تتوفر لها بيانات في Transitous. يُحاسب على كل بحث — ويُستخدم Transitous ما دام لا يوجد مفتاح.',
'admin.transitProvider.noKeyWarning': 'تم اختيار Google، لكن لا يوجد مفتاح Google مُهيأ — لا يزال بحث النقل يستخدم Transitous. أضف مفتاحًا ضمن مفاتيح API أعلاه.',
'admin.transitProvider.personalKeyWarning': 'مفتاح Google الخاص بك وحده مضبوط، لذا يعود بحث النقل لبقية الأعضاء إلى Transitous. احفظ المفتاح أعلاه كمسؤول لتطبيقه على مستوى المثيل.',
'admin.bagTracking.title': 'تتبع الأمتعة',
'admin.bagTracking.subtitle': 'تفعيل الوزن وتعيين الأمتعة للعناصر',
'admin.collab.chat.title': 'الدردشة',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': 'بحث',
'transit.searching': 'جارٍ البحث…',
'transit.searchError': 'فشل البحث عن المسار. يُرجى المحاولة مرة أخرى.',
'transit.noResultsVia': 'لم يتم العثور على أي رحلات عبر {provider}. جرّب وقتًا أو عوامل تصفية مختلفة.',
'transit.noResults': 'لم يُعثر على أي رحلات. جرّب وقتًا أو عوامل تصفية مختلفة.',
'transit.direct': 'مباشر',
'transit.transfers': '{count} تحويلات',
+8
View File
@@ -124,6 +124,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': 'Enriquecimento de lugares',
'admin.placesEnrich.subtitle':
'Mostra imagens e uma descrição ao adicionar um lugar. Wikipédia e OpenStreetMap são sempre usados; o Google entra quando Fotos de lugares ou Detalhes de lugares estão ativos.',
'admin.transitProvider.title': 'Provedor de transporte público',
'admin.transitProvider.subtitle': 'Qual serviço responde à busca de transporte público.',
'admin.transitProvider.transitous': 'Transitous (grátis)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'Feeds GTFS da comunidade. Gratuito e sem chave, com a melhor cobertura na Europa.',
'admin.transitProvider.googleHint': 'Usa a chave do Google acima, para regiões sem dados no Transitous. Cobrado por busca — o Transitous é usado enquanto nenhuma chave estiver configurada.',
'admin.transitProvider.noKeyWarning': 'O Google está selecionado, mas nenhuma chave do Google está configurada — a busca de transporte ainda usa o Transitous. Adicione uma chave em Chaves de API acima.',
'admin.transitProvider.personalKeyWarning': 'Apenas a sua própria chave do Google está definida, então a busca dos outros membros ainda cai no Transitous. Salve a chave acima como admin para aplicá-la a toda a instância.',
'admin.bagTracking.title': 'Rastreamento de malas',
'admin.bagTracking.subtitle': 'Ativar peso e atribuição de mala para itens da lista',
'admin.collab.chat.title': 'Chat',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': 'Buscar',
'transit.searching': 'Buscando…',
'transit.searchError': 'Falha na busca de rota. Tente novamente.',
'transit.noResultsVia': 'Nenhuma conexão encontrada via {provider}. Tente outro horário ou outros filtros.',
'transit.noResults': 'Nenhuma conexão encontrada. Tente outro horário ou filtros.',
'transit.direct': 'Direto',
'transit.transfers': '{count} baldeações',
+8
View File
@@ -128,6 +128,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': 'Enriquiment de llocs',
'admin.placesEnrich.subtitle':
"Mostra imatges i una descripció en afegir un lloc. Wikipedia i OpenStreetMap s'usen sempre; Google s'hi afegeix si Fotos de llocs o Detalls de llocs estan actius.",
'admin.transitProvider.title': 'Proveïdor de transport públic',
'admin.transitProvider.subtitle': 'Quin servei respon la cerca de transport públic.',
'admin.transitProvider.transitous': 'Transitous (gratuït)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'Fluxos GTFS de la comunitat. Gratuït i sense clau, amb la millor cobertura a Europa.',
'admin.transitProvider.googleHint': 'Utilitza la clau de Google anterior, per a regions sense dades a Transitous. Es factura per cerca: mentre no hi hagi clau s\'utilitza Transitous.',
'admin.transitProvider.noKeyWarning': 'Google està seleccionat, però no hi ha cap clau de Google configurada: la cerca de transport encara utilitza Transitous. Afegeix una clau a Claus d\'API a dalt.',
'admin.transitProvider.personalKeyWarning': 'Només hi ha la teva pròpia clau de Google, de manera que la cerca dels altres membres continua recorrent a Transitous. Desa la clau a dalt com a administrador per aplicar-la a tota la instància.',
'admin.bagTracking.title': "Seguiment d'equipatge",
'admin.bagTracking.subtitle': "Activar pes i assignació d'equipatge per a articles de la llista",
'admin.collab.chat.title': 'Xat',
+1
View File
@@ -59,6 +59,7 @@ const trip: TranslationStrings = {
'transit.search': 'Cercar',
'transit.searching': 'Cercant…',
'transit.searchError': 'Ha fallat la cerca de la ruta. Torna-ho a provar.',
'transit.noResultsVia': 'No s\'ha trobat cap connexió mitjançant {provider}. Prova una altra hora o altres filtres.',
'transit.noResults': "No s'han trobat connexions. Prova amb un altre horari o filtres.",
'transit.direct': 'Directe',
'transit.transfers': '{count} transbords',
+8
View File
@@ -125,6 +125,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': 'Obohacení míst',
'admin.placesEnrich.subtitle':
'Zobrazí obrázky a popis při přidávání místa. Wikipedie a OpenStreetMap se používají vždy; Google se přidá, když jsou zapnuté Fotky míst nebo Detaily míst.',
'admin.transitProvider.title': 'Poskytovatel veřejné dopravy',
'admin.transitProvider.subtitle': 'Která služba odpovídá na vyhledávání veřejné dopravy.',
'admin.transitProvider.transitous': 'Transitous (zdarma)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'Komunitní GTFS zdroje. Zdarma a bez klíče, s nejlepším pokrytím v Evropě.',
'admin.transitProvider.googleHint': 'Použije výše uvedený klíč Google pro regiony, pro které Transitous nemá data. Účtuje se za každé hledání – dokud není klíč nastaven, používá se Transitous.',
'admin.transitProvider.noKeyWarning': 'Je vybrán Google, ale není nastaven žádný klíč Google – vyhledávání dopravy stále používá Transitous. Přidejte klíč v sekci API klíče výše.',
'admin.transitProvider.personalKeyWarning': 'Je nastaven jen váš vlastní klíč Google, takže ostatním členům se vyhledávání stále vrací k Transitous. Uložte klíč výše jako správce, aby platil pro celou instanci.',
'admin.bagTracking.title': 'Sledování zavazadel',
'admin.bagTracking.subtitle': 'Povolit váhu a přiřazení k zavazadlům u položek balení',
'admin.collab.chat.title': 'Chat',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': 'Hledat',
'transit.searching': 'Hledání…',
'transit.searchError': 'Vyhledání spojení selhalo. Zkuste to prosím znovu.',
'transit.noResultsVia': 'Přes {provider} nebylo nalezeno žádné spojení. Zkuste jiný čas nebo filtry.',
'transit.noResults': 'Nebyla nalezena žádná spojení. Zkuste jiný čas nebo filtry.',
'transit.direct': 'Přímé',
'transit.transfers': '{count} přestupů',
+8
View File
@@ -127,6 +127,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': 'Ortsanreicherung',
'admin.placesEnrich.subtitle':
'Bilder und eine Beschreibung beim Hinzufügen eines Ortes anzeigen. Wikipedia und OpenStreetMap werden immer genutzt; Google kommt zusätzlich dazu, wenn Ortsfotos oder Ortsdetails aktiv sind.',
'admin.transitProvider.title': 'Verkehrsanbieter',
'admin.transitProvider.subtitle': 'Welcher Dienst die ÖPNV-Suche beantwortet.',
'admin.transitProvider.transitous': 'Transitous (kostenlos)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'Community-GTFS-Feeds. Kostenlos und ohne Schlüssel, mit der besten Abdeckung in Europa.',
'admin.transitProvider.googleHint': 'Nutzt den obigen Google-Schlüssel, für Regionen ohne Transitous-Daten. Wird pro Suche abgerechnet – solange kein Schlüssel gesetzt ist, wird Transitous verwendet.',
'admin.transitProvider.noKeyWarning': 'Google ist ausgewählt, aber es ist kein Google-Schlüssel hinterlegt — die ÖPNV-Suche nutzt weiterhin Transitous. Trage oben unter API-Schlüssel einen Schlüssel ein.',
'admin.transitProvider.personalKeyWarning': 'Es ist nur dein eigener Google-Schlüssel gesetzt, daher fällt die Suche der anderen Mitglieder weiterhin auf Transitous zurück. Speichere den Schlüssel oben als Admin, damit er instanzweit gilt.',
'admin.bagTracking.title': 'Gepäck-Tracking',
'admin.bagTracking.subtitle': 'Gewicht und Gepäckstück-Zuordnung für Packlisteneinträge aktivieren',
'admin.collab.chat.title': 'Chat',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': 'Suchen',
'transit.searching': 'Suche …',
'transit.searchError': 'Routensuche fehlgeschlagen. Bitte erneut versuchen.',
'transit.noResultsVia': 'Keine Verbindungen über {provider} gefunden. Versuche eine andere Zeit oder andere Filter.',
'transit.noResults': 'Keine Verbindungen gefunden. Andere Zeit oder Filter probieren.',
'transit.direct': 'Direkt',
'transit.transfers': '{count} Umstiege',
+8
View File
@@ -166,6 +166,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': 'Place Enrichment',
'admin.placesEnrich.subtitle':
'Show pictures and a description while adding a place. Wikipedia and OpenStreetMap are always used; Google is added on top when Place Photos or Place Details are on.',
'admin.transitProvider.title': 'Transit Provider',
'admin.transitProvider.subtitle': 'Which service answers public transit search.',
'admin.transitProvider.transitous': 'Transitous (free)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'Community GTFS feeds. Free and keyless, with the best coverage in Europe.',
'admin.transitProvider.googleHint': 'Uses the Google API key above, for regions Transitous has no data for. Billed per search — Transitous is used while no key is set.',
'admin.transitProvider.noKeyWarning': 'Google is selected, but no Google API key is configured — transit search is still using Transitous. Add a key under API Keys above.',
'admin.transitProvider.personalKeyWarning': 'Only your own Google key is set, so other members\' transit searches still fall back to Transitous. Save the key above as an admin to apply it instance-wide.',
'admin.bagTracking.title': 'Bag Tracking',
'admin.bagTracking.subtitle': 'Enable weight and bag assignment for packing items',
'admin.collab.chat.title': 'Chat',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': 'Search',
'transit.searching': 'Searching…',
'transit.searchError': 'Route search failed. Please try again.',
'transit.noResultsVia': 'No connections found via {provider}. Try a different time or filters.',
'transit.noResults': 'No connections found. Try a different time or filters.',
'transit.direct': 'Direct',
'transit.transfers': '{count} transfers',
+8
View File
@@ -126,6 +126,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': 'Enriquecimiento de lugares',
'admin.placesEnrich.subtitle':
'Muestra imágenes y una descripción al añadir un lugar. Wikipedia y OpenStreetMap se usan siempre; Google se añade cuando Fotos de lugares o Detalles de lugares están activados.',
'admin.transitProvider.title': 'Proveedor de transporte público',
'admin.transitProvider.subtitle': 'Qué servicio responde a la búsqueda de transporte público.',
'admin.transitProvider.transitous': 'Transitous (gratis)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'Fuentes GTFS de la comunidad. Gratis y sin clave, con la mejor cobertura en Europa.',
'admin.transitProvider.googleHint': 'Usa la clave de Google anterior, para regiones sin datos en Transitous. Se cobra por búsqueda: mientras no haya clave se usa Transitous.',
'admin.transitProvider.noKeyWarning': 'Google está seleccionado, pero no hay ninguna clave de Google configurada: la búsqueda de transporte sigue usando Transitous. Añade una clave en Claves de API arriba.',
'admin.transitProvider.personalKeyWarning': 'Solo está configurada tu propia clave de Google, así que la búsqueda de los demás miembros sigue recurriendo a Transitous. Guarda la clave arriba como administrador para aplicarla a toda la instancia.',
'admin.bagTracking.title': 'Seguimiento de equipaje',
'admin.bagTracking.subtitle': 'Activar peso y asignación de equipaje para artículos de la lista',
'admin.collab.chat.title': 'Chat',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': 'Buscar',
'transit.searching': 'Buscando…',
'transit.searchError': 'No se pudo buscar la ruta. Inténtalo de nuevo.',
'transit.noResultsVia': 'No se han encontrado conexiones mediante {provider}. Prueba con otra hora u otros filtros.',
'transit.noResults': 'No se encontraron conexiones. Prueba con otra hora u otros filtros.',
'transit.direct': 'Directo',
'transit.transfers': '{count} transbordos',
+8
View File
@@ -128,6 +128,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': 'Enrichissement des lieux',
'admin.placesEnrich.subtitle':
"Affiche des images et une description lors de l'ajout d'un lieu. Wikipédia et OpenStreetMap sont toujours utilisés ; Google s'y ajoute si Photos de lieux ou Détails de lieux sont activés.",
'admin.transitProvider.title': 'Fournisseur de transports en commun',
'admin.transitProvider.subtitle': 'Quel service répond à la recherche de transports en commun.',
'admin.transitProvider.transitous': 'Transitous (gratuit)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'Flux GTFS communautaires. Gratuit et sans clé, avec la meilleure couverture en Europe.',
'admin.transitProvider.googleHint': 'Utilise la clé Google ci-dessus, pour les régions sans données Transitous. Facturé à la recherche — tant qu\'aucune clé n\'est définie, Transitous est utilisé.',
'admin.transitProvider.noKeyWarning': 'Google est sélectionné, mais aucune clé Google n\'est configurée — la recherche de transports utilise toujours Transitous. Ajoutez une clé dans Clés d\'API ci-dessus.',
'admin.transitProvider.personalKeyWarning': 'Seule votre propre clé Google est définie : la recherche des autres membres continue de basculer sur Transitous. Enregistrez la clé ci-dessus en tant qu\'administrateur pour l\'appliquer à toute l\'instance.',
'admin.bagTracking.title': 'Suivi des bagages',
'admin.bagTracking.subtitle': "Activer le poids et l'attribution de bagages pour les articles",
'admin.collab.chat.title': 'Chat',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': 'Rechercher',
'transit.searching': 'Recherche…',
'transit.searchError': "Échec de la recherche d'itinéraire. Veuillez réessayer.",
'transit.noResultsVia': 'Aucune liaison trouvée via {provider}. Essayez une autre heure ou d\'autres filtres.',
'transit.noResults': "Aucune connexion trouvée. Essayez un autre horaire ou d'autres filtres.",
'transit.direct': 'Direct',
'transit.transfers': '{count} correspondances',
+8
View File
@@ -173,6 +173,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': 'Εμπλουτισμός τοποθεσιών',
'admin.placesEnrich.subtitle':
'Εμφανίζει εικόνες και περιγραφή κατά την προσθήκη τοποθεσίας. Η Wikipedia και το OpenStreetMap χρησιμοποιούνται πάντα· η Google προστίθεται όταν είναι ενεργές οι Φωτογραφίες ή οι Λεπτομέρειες τοποθεσίας.',
'admin.transitProvider.title': 'Πάροχος μέσων μεταφοράς',
'admin.transitProvider.subtitle': 'Ποια υπηρεσία απαντά στην αναζήτηση μέσων μεταφοράς.',
'admin.transitProvider.transitous': 'Transitous (δωρεάν)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'Κοινοτικές ροές GTFS. Δωρεάν και χωρίς κλειδί, με την καλύτερη κάλυψη στην Ευρώπη.',
'admin.transitProvider.googleHint': 'Χρησιμοποιεί το παραπάνω κλειδί Google, για περιοχές χωρίς δεδομένα στο Transitous. Χρεώνεται ανά αναζήτηση — όσο δεν υπάρχει κλειδί, χρησιμοποιείται το Transitous.',
'admin.transitProvider.noKeyWarning': 'Έχει επιλεγεί το Google, αλλά δεν έχει ρυθμιστεί κλειδί Google — η αναζήτηση μέσων μεταφοράς εξακολουθεί να χρησιμοποιεί το Transitous. Προσθέστε κλειδί στα Κλειδιά API παραπάνω.',
'admin.transitProvider.personalKeyWarning': 'Έχει οριστεί μόνο το δικό σας κλειδί Google, οπότε η αναζήτηση των υπόλοιπων μελών επιστρέφει στο Transitous. Αποθηκεύστε το κλειδί παραπάνω ως διαχειριστής για να ισχύει σε όλη την εγκατάσταση.',
'admin.bagTracking.title': 'Παρακολούθηση Αποσκευών',
'admin.bagTracking.subtitle': 'Ενεργοποίηση βάρους και ανάθεσης τσάντας για αντικείμενα πακεταρίσματος',
'admin.collab.chat.title': 'Συνομιλία',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': 'Αναζήτηση',
'transit.searching': 'Αναζήτηση…',
'transit.searchError': 'Η αναζήτηση διαδρομής απέτυχε. Δοκιμάστε ξανά.',
'transit.noResultsVia': 'Δεν βρέθηκαν συνδέσεις μέσω {provider}. Δοκιμάστε άλλη ώρα ή άλλα φίλτρα.',
'transit.noResults': 'Δεν βρέθηκαν συνδέσεις. Δοκιμάστε άλλη ώρα ή φίλτρα.',
'transit.direct': 'Απευθείας',
'transit.transfers': '{count} μετεπιβιβάσεις',
+8
View File
@@ -127,6 +127,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': 'Helyek gazdagítása',
'admin.placesEnrich.subtitle':
'Képeket és leírást mutat hely hozzáadásakor. A Wikipédia és az OpenStreetMap mindig használatban van; a Google akkor jön hozzá, ha a Helyfotók vagy a Helyadatok be vannak kapcsolva.',
'admin.transitProvider.title': 'Tömegközlekedési szolgáltató',
'admin.transitProvider.subtitle': 'Melyik szolgáltatás válaszol a tömegközlekedési keresésre.',
'admin.transitProvider.transitous': 'Transitous (ingyenes)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'Közösségi GTFS adatforrások. Ingyenes és kulcs nélküli, Európában a legjobb lefedettséggel.',
'admin.transitProvider.googleHint': 'A fenti Google-kulcsot használja azokhoz a régiókhoz, amelyekhez a Transitousnak nincs adata. Keresésenként számlázódik – amíg nincs kulcs, a Transitous fut.',
'admin.transitProvider.noKeyWarning': 'A Google van kiválasztva, de nincs beállítva Google-kulcs – a közlekedési keresés továbbra is a Transitous-t használja. Adj hozzá kulcsot a fenti API-kulcsoknál.',
'admin.transitProvider.personalKeyWarning': 'Csak a saját Google-kulcsod van beállítva, így a többi tag keresése továbbra is a Transitous-ra esik vissza. Mentsd a kulcsot fent adminként, hogy az egész példányra érvényes legyen.',
'admin.bagTracking.title': 'Poggyászkövetés',
'admin.bagTracking.subtitle': 'Súly- és táskahozzárendelés engedélyezése csomagolási tételeknél',
'admin.collab.chat.title': 'Chat',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': 'Keresés',
'transit.searching': 'Keresés…',
'transit.searchError': 'Az útvonalkeresés nem sikerült. Kérjük, próbáld újra.',
'transit.noResultsVia': 'Nem található összeköttetés a következőn keresztül: {provider}. Próbálj más időpontot vagy szűrőket.',
'transit.noResults': 'Nem található kapcsolat. Próbálj másik időpontot vagy szűrőket.',
'transit.direct': 'Közvetlen',
'transit.transfers': '{count} átszállás',
+8
View File
@@ -169,6 +169,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': 'Pengayaan tempat',
'admin.placesEnrich.subtitle':
'Menampilkan gambar dan deskripsi saat menambahkan tempat. Wikipedia dan OpenStreetMap selalu digunakan; Google ditambahkan bila Foto Tempat atau Detail Tempat aktif.',
'admin.transitProvider.title': 'Penyedia transportasi umum',
'admin.transitProvider.subtitle': 'Layanan mana yang menjawab pencarian transportasi umum.',
'admin.transitProvider.transitous': 'Transitous (gratis)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'Umpan GTFS komunitas. Gratis dan tanpa kunci, dengan cakupan terbaik di Eropa.',
'admin.transitProvider.googleHint': 'Menggunakan kunci Google di atas, untuk wilayah yang tidak memiliki data Transitous. Ditagih per pencarian — selama belum ada kunci, Transitous yang dipakai.',
'admin.transitProvider.noKeyWarning': 'Google dipilih, tetapi belum ada kunci Google yang dikonfigurasi — pencarian transportasi masih memakai Transitous. Tambahkan kunci di Kunci API di atas.',
'admin.transitProvider.personalKeyWarning': 'Hanya kunci Google milikmu yang disetel, sehingga pencarian anggota lain tetap kembali ke Transitous. Simpan kunci di atas sebagai admin agar berlaku untuk seluruh instance.',
'admin.bagTracking.title': 'Pelacak Tas',
'admin.bagTracking.subtitle': 'Aktifkan berat dan penugasan tas untuk item packing',
'admin.collab.chat.title': 'Chat',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': 'Cari',
'transit.searching': 'Mencari…',
'transit.searchError': 'Pencarian rute gagal. Silakan coba lagi.',
'transit.noResultsVia': 'Tidak ada koneksi yang ditemukan via {provider}. Coba waktu atau filter lain.',
'transit.noResults': 'Tidak ada koneksi ditemukan. Coba waktu atau filter lain.',
'transit.direct': 'Langsung',
'transit.transfers': '{count} transit',
+8
View File
@@ -126,6 +126,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': 'Arricchimento luoghi',
'admin.placesEnrich.subtitle':
'Mostra immagini e una descrizione mentre aggiungi un luogo. Wikipedia e OpenStreetMap sono sempre usati; Google si aggiunge se Foto luoghi o Dettagli luoghi sono attivi.',
'admin.transitProvider.title': 'Provider del trasporto pubblico',
'admin.transitProvider.subtitle': 'Quale servizio risponde alla ricerca di trasporto pubblico.',
'admin.transitProvider.transitous': 'Transitous (gratuito)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'Feed GTFS della comunità. Gratuito e senza chiave, con la migliore copertura in Europa.',
'admin.transitProvider.googleHint': 'Usa la chiave Google qui sopra, per le regioni senza dati Transitous. Addebitato per ricerca: finché non è impostata una chiave viene usato Transitous.',
'admin.transitProvider.noKeyWarning': 'Google è selezionato, ma non è configurata alcuna chiave Google: la ricerca del trasporto usa ancora Transitous. Aggiungi una chiave in Chiavi API qui sopra.',
'admin.transitProvider.personalKeyWarning': 'È impostata solo la tua chiave Google, quindi la ricerca degli altri membri continua a ripiegare su Transitous. Salva la chiave qui sopra come amministratore per applicarla all\'intera istanza.',
'admin.bagTracking.title': 'Tracciamento valigia',
'admin.bagTracking.subtitle': "Abilita il peso e l'assegnazione della valigia per gli elementi della lista valigia",
'admin.collab.chat.title': 'Chat',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': 'Cerca',
'transit.searching': 'Ricerca in corso…',
'transit.searchError': 'Ricerca del percorso non riuscita. Riprova.',
'transit.noResultsVia': 'Nessun collegamento trovato tramite {provider}. Prova un altro orario o altri filtri.',
'transit.noResults': 'Nessun collegamento trovato. Prova un altro orario o filtri.',
'transit.direct': 'Diretto',
'transit.transfers': '{count} cambi',
+8
View File
@@ -158,6 +158,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': '場所の情報補完',
'admin.placesEnrich.subtitle':
'場所を追加するときに写真と説明を表示します。WikipediaとOpenStreetMapは常に使用され、「場所の写真」または「場所の詳細」が有効な場合はGoogleも追加されます。',
'admin.transitProvider.title': '公共交通のプロバイダー',
'admin.transitProvider.subtitle': '公共交通の検索に応答するサービス。',
'admin.transitProvider.transitous': 'Transitous(無料)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'コミュニティの GTFS フィード。無料でキー不要、ヨーロッパのカバー率が最も高い。',
'admin.transitProvider.googleHint': '上記の Google キーを使用し、Transitous にデータがない地域に対応します。検索ごとに課金されます。キーが未設定の間は Transitous を使用します。',
'admin.transitProvider.noKeyWarning': 'Google が選択されていますが、Google キーが設定されていません。公共交通の検索は引き続き Transitous を使用します。上の「API キー」でキーを追加してください。',
'admin.transitProvider.personalKeyWarning': 'あなた自身の Google キーのみが設定されているため、他のメンバーの検索は引き続き Transitous になります。インスタンス全体に適用するには、管理者として上でキーを保存してください。',
'admin.bagTracking.title': 'バッグ管理',
'admin.bagTracking.subtitle': '持ち物の重量とバッグ割り当てを有効化',
'admin.collab.chat.title': 'チャット',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': '検索',
'transit.searching': '検索中…',
'transit.searchError': 'ルート検索に失敗しました。もう一度お試しください。',
'transit.noResultsVia': '{provider} では経路が見つかりませんでした。時間やフィルターを変えてお試しください。',
'transit.noResults': '接続が見つかりませんでした。時間やフィルターを変更してお試しください。',
'transit.direct': '直通',
'transit.transfers': '乗り換え{count}回',
+8
View File
@@ -164,6 +164,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': '장소 정보 보강',
'admin.placesEnrich.subtitle':
'장소를 추가할 때 사진과 설명을 표시합니다. Wikipedia와 OpenStreetMap은 항상 사용되며, 장소 사진 또는 장소 세부정보가 켜져 있으면 Google도 함께 사용됩니다.',
'admin.transitProvider.title': '대중교통 제공자',
'admin.transitProvider.subtitle': '대중교통 검색에 응답하는 서비스입니다.',
'admin.transitProvider.transitous': 'Transitous (무료)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': '커뮤니티 GTFS 피드. 무료이며 키가 필요 없고 유럽 커버리지가 가장 좋습니다.',
'admin.transitProvider.googleHint': '위의 Google 키를 사용하여 Transitous에 데이터가 없는 지역을 처리합니다. 검색당 과금되며, 키가 없으면 Transitous를 사용합니다.',
'admin.transitProvider.noKeyWarning': 'Google이 선택되었지만 Google 키가 설정되지 않았습니다 — 대중교통 검색은 여전히 Transitous를 사용합니다. 위의 API 키에서 키를 추가하세요.',
'admin.transitProvider.personalKeyWarning': '본인의 Google 키만 설정되어 있어 다른 멤버의 검색은 여전히 Transitous로 대체됩니다. 인스턴스 전체에 적용하려면 관리자로 위에서 키를 저장하세요.',
'admin.bagTracking.title': '가방 추적',
'admin.bagTracking.subtitle': '짐 항목에 무게 및 가방 배정을 활성화합니다',
'admin.collab.chat.title': '채팅',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': '검색',
'transit.searching': '검색 중…',
'transit.searchError': '경로 검색에 실패했습니다. 다시 시도해 주세요.',
'transit.noResultsVia': '{provider}에서 연결편을 찾지 못했습니다. 다른 시간이나 필터를 사용해 보세요.',
'transit.noResults': '연결편을 찾을 수 없습니다. 시간이나 필터를 변경해 보세요.',
'transit.direct': '직행',
'transit.transfers': '환승 {count}회',
+8
View File
@@ -127,6 +127,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': 'Plaatsverrijking',
'admin.placesEnrich.subtitle':
"Toont afbeeldingen en een beschrijving bij het toevoegen van een plaats. Wikipedia en OpenStreetMap worden altijd gebruikt; Google komt erbij als Plaatsfoto's of Plaatsdetails aanstaan.",
'admin.transitProvider.title': 'Ov-provider',
'admin.transitProvider.subtitle': 'Welke dienst het ov-zoeken beantwoordt.',
'admin.transitProvider.transitous': 'Transitous (gratis)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'GTFS-feeds van de community. Gratis en zonder sleutel, met de beste dekking in Europa.',
'admin.transitProvider.googleHint': 'Gebruikt de Google-sleutel hierboven, voor regio\'s zonder Transitous-data. Wordt per zoekopdracht afgerekend — zolang er geen sleutel is, wordt Transitous gebruikt.',
'admin.transitProvider.noKeyWarning': 'Google is geselecteerd, maar er is geen Google-sleutel ingesteld — het ov-zoeken gebruikt nog steeds Transitous. Voeg hierboven een sleutel toe bij API-sleutels.',
'admin.transitProvider.personalKeyWarning': 'Alleen je eigen Google-sleutel is ingesteld, dus het zoeken van andere leden valt nog steeds terug op Transitous. Sla de sleutel hierboven op als beheerder om hem instantiebreed toe te passen.',
'admin.bagTracking.title': 'Bagagetracking',
'admin.bagTracking.subtitle': 'Gewicht en bagagetoewijzing inschakelen voor paklijstitems',
'admin.collab.chat.title': 'Chat',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': 'Zoeken',
'transit.searching': 'Zoeken…',
'transit.searchError': 'Routezoeken mislukt. Probeer het opnieuw.',
'transit.noResultsVia': 'Geen verbindingen gevonden via {provider}. Probeer een andere tijd of andere filters.',
'transit.noResults': 'Geen verbindingen gevonden. Probeer een andere tijd of andere filters.',
'transit.direct': 'Direct',
'transit.transfers': '{count} keer overstappen',
+8
View File
@@ -120,6 +120,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': 'Wzbogacanie miejsc',
'admin.placesEnrich.subtitle':
'Pokazuje zdjęcia i opis podczas dodawania miejsca. Wikipedia i OpenStreetMap są używane zawsze; Google dochodzi, gdy włączone są Zdjęcia miejsc lub Szczegóły miejsc.',
'admin.transitProvider.title': 'Dostawca transportu publicznego',
'admin.transitProvider.subtitle': 'Która usługa odpowiada na wyszukiwanie transportu publicznego.',
'admin.transitProvider.transitous': 'Transitous (bezpłatnie)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'Społecznościowe źródła GTFS. Bezpłatne i bez klucza, z najlepszym zasięgiem w Europie.',
'admin.transitProvider.googleHint': 'Używa powyższego klucza Google w regionach, dla których Transitous nie ma danych. Rozliczane za wyszukiwanie — dopóki nie ustawiono klucza, działa Transitous.',
'admin.transitProvider.noKeyWarning': 'Wybrano Google, ale nie skonfigurowano klucza Google — wyszukiwanie transportu nadal korzysta z Transitous. Dodaj klucz w sekcji Klucze API powyżej.',
'admin.transitProvider.personalKeyWarning': 'Ustawiono tylko Twój własny klucz Google, więc wyszukiwanie pozostałych członków nadal wraca do Transitous. Zapisz klucz powyżej jako administrator, aby obowiązywał w całej instancji.',
'admin.bagTracking.title': 'Kontrola bagażu',
'admin.bagTracking.subtitle': 'Włącz wagę i przypisywanie do toreb dla przedmiotów do pakowania',
'admin.collab.chat.title': 'Czat',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': 'Szukaj',
'transit.searching': 'Wyszukiwanie…',
'transit.searchError': 'Wyszukiwanie trasy nie powiodło się. Spróbuj ponownie.',
'transit.noResultsVia': 'Nie znaleziono połączeń przez {provider}. Spróbuj innej godziny lub innych filtrów.',
'transit.noResults': 'Nie znaleziono połączeń. Zmień godzinę lub filtry.',
'transit.direct': 'Bezpośrednio',
'transit.transfers': 'Przesiadki: {count}',
+8
View File
@@ -127,6 +127,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': 'Обогащение мест',
'admin.placesEnrich.subtitle':
'Показывает изображения и описание при добавлении места. Wikipedia и OpenStreetMap используются всегда; Google добавляется, если включены «Фото мест» или «Детали мест».',
'admin.transitProvider.title': 'Поставщик общественного транспорта',
'admin.transitProvider.subtitle': 'Какая служба отвечает на поиск общественного транспорта.',
'admin.transitProvider.transitous': 'Transitous (бесплатно)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'GTFS-фиды сообщества. Бесплатно и без ключа, с лучшим покрытием в Европе.',
'admin.transitProvider.googleHint': 'Использует указанный выше ключ Google для регионов, по которым у Transitous нет данных. Оплачивается за каждый поиск — пока ключ не задан, используется Transitous.',
'admin.transitProvider.noKeyWarning': 'Выбран Google, но ключ Google не настроен — поиск транспорта по-прежнему использует Transitous. Добавьте ключ в разделе «Ключи API» выше.',
'admin.transitProvider.personalKeyWarning': 'Задан только ваш собственный ключ Google, поэтому поиск других участников по-прежнему возвращается к Transitous. Сохраните ключ выше от имени администратора, чтобы он действовал для всей установки.',
'admin.bagTracking.title': 'Отслеживание багажа',
'admin.bagTracking.subtitle': 'Включить вес и привязку к багажу для вещей',
'admin.collab.chat.title': 'Чат',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': 'Поиск',
'transit.searching': 'Поиск…',
'transit.searchError': 'Не удалось найти маршрут. Попробуйте снова.',
'transit.noResultsVia': 'Через {provider} маршруты не найдены. Попробуйте другое время или фильтры.',
'transit.noResults': 'Маршруты не найдены. Измените время или фильтры.',
'transit.direct': 'Без пересадок',
'transit.transfers': 'Пересадок: {count}',
+8
View File
@@ -170,6 +170,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': 'Platsberikning',
'admin.placesEnrich.subtitle':
'Visar bilder och en beskrivning när du lägger till en plats. Wikipedia och OpenStreetMap används alltid; Google tillkommer när Platsfoton eller Platsdetaljer är på.',
'admin.transitProvider.title': 'Kollektivtrafikleverantör',
'admin.transitProvider.subtitle': 'Vilken tjänst som besvarar sökningar i kollektivtrafiken.',
'admin.transitProvider.transitous': 'Transitous (gratis)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'GTFS-flöden från communityn. Gratis och utan nyckel, med bäst täckning i Europa.',
'admin.transitProvider.googleHint': 'Använder Google-nyckeln ovan, för regioner som Transitous saknar data för. Debiteras per sökning – så länge ingen nyckel är angiven används Transitous.',
'admin.transitProvider.noKeyWarning': 'Google är valt, men ingen Google-nyckel är konfigurerad – kollektivtrafiksökningen använder fortfarande Transitous. Lägg till en nyckel under API-nycklar ovan.',
'admin.transitProvider.personalKeyWarning': 'Bara din egen Google-nyckel är angiven, så andra medlemmars sökningar faller fortfarande tillbaka på Transitous. Spara nyckeln ovan som administratör för att den ska gälla hela instansen.',
'admin.bagTracking.title': 'Spårning av väskor',
'admin.bagTracking.subtitle': 'Aktivera vikt- och väskfördelning för packningsartiklar',
'admin.collab.chat.title': 'Chatt',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': 'Sök',
'transit.searching': 'Söker…',
'transit.searchError': 'Reseökningen misslyckades. Försök igen.',
'transit.noResultsVia': 'Inga förbindelser hittades via {provider}. Prova en annan tid eller andra filter.',
'transit.noResults': 'Inga förbindelser hittades. Prova en annan tid eller andra filter.',
'transit.direct': 'Direkt',
'transit.transfers': '{count} byten',
+8
View File
@@ -171,6 +171,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': 'Yer zenginleştirme',
'admin.placesEnrich.subtitle':
'Bir yer eklerken görseller ve açıklama gösterir. Wikipedia ve OpenStreetMap her zaman kullanılır; Yer Fotoğrafları veya Yer Ayrıntıları açıkken Google da eklenir.',
'admin.transitProvider.title': 'Toplu taşıma sağlayıcısı',
'admin.transitProvider.subtitle': 'Toplu taşıma aramasını hangi hizmetin yanıtlayacağı.',
'admin.transitProvider.transitous': 'Transitous (ücretsiz)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'Topluluk GTFS akışları. Ücretsiz ve anahtarsız, Avrupa\'da en iyi kapsama.',
'admin.transitProvider.googleHint': 'Transitous\'un verisi olmayan bölgeler için yukarıdaki Google anahtarını kullanır. Arama başına ücretlendirilir — anahtar ayarlanmadığı sürece Transitous kullanılır.',
'admin.transitProvider.noKeyWarning': 'Google seçili, ancak yapılandırılmış bir Google anahtarı yok — toplu taşıma araması hâlâ Transitous kullanıyor. Yukarıdaki API Anahtarları bölümünden bir anahtar ekleyin.',
'admin.transitProvider.personalKeyWarning': 'Yalnızca kendi Google anahtarınız ayarlı, bu yüzden diğer üyelerin araması hâlâ Transitous\'a düşüyor. Tüm kuruluma uygulamak için anahtarı yukarıda yönetici olarak kaydedin.',
'admin.bagTracking.title': 'Çanta Takibi',
'admin.bagTracking.subtitle': 'Paketleme öğeleri için ağırlık ve torba atamasını etkinleştirin',
'admin.collab.chat.title': 'Sohbet',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': 'Ara',
'transit.searching': 'Aranıyor…',
'transit.searchError': 'Rota araması başarısız oldu. Lütfen tekrar deneyin.',
'transit.noResultsVia': '{provider} üzerinden bağlantı bulunamadı. Farklı bir saat veya filtre deneyin.',
'transit.noResults': 'Bağlantı bulunamadı. Farklı bir saat veya filtre deneyin.',
'transit.direct': 'Aktarmasız',
'transit.transfers': '{count} aktarma',
+8
View File
@@ -127,6 +127,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': 'Збагачення місць',
'admin.placesEnrich.subtitle':
'Показує зображення та опис під час додавання місця. Wikipedia та OpenStreetMap використовуються завжди; Google додається, якщо ввімкнено «Фото місць» або «Деталі місць».',
'admin.transitProvider.title': 'Постачальник громадського транспорту',
'admin.transitProvider.subtitle': 'Яка служба відповідає на пошук громадського транспорту.',
'admin.transitProvider.transitous': 'Transitous (безкоштовно)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'Спільнотні GTFS-стрічки. Безкоштовно та без ключа, з найкращим покриттям у Європі.',
'admin.transitProvider.googleHint': 'Використовує наведений вище ключ Google для регіонів, де Transitous не має даних. Оплата за кожен пошук — доки ключ не задано, використовується Transitous.',
'admin.transitProvider.noKeyWarning': 'Вибрано Google, але ключ Google не налаштовано — пошук транспорту досі використовує Transitous. Додайте ключ у розділі «Ключі API» вище.',
'admin.transitProvider.personalKeyWarning': 'Задано лише ваш власний ключ Google, тож пошук інших учасників усе одно повертається до Transitous. Збережіть ключ вище як адміністратор, щоб він діяв для всієї інсталяції.',
'admin.bagTracking.title': 'Відстеження багажу',
'admin.bagTracking.subtitle': 'Увімкнути вагу та прив’язку до багажу для речей',
'admin.collab.chat.title': 'Чат',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': 'Пошук',
'transit.searching': 'Пошук…',
'transit.searchError': 'Не вдалося знайти маршрут. Спробуйте ще раз.',
'transit.noResultsVia': 'Через {provider} сполучень не знайдено. Спробуйте інший час або фільтри.',
'transit.noResults': "З'єднань не знайдено. Спробуйте інший час або фільтри.",
'transit.direct': 'Прямий',
'transit.transfers': 'Пересадок: {count}',
+8
View File
@@ -169,6 +169,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': 'Làm giàu địa điểm',
'admin.placesEnrich.subtitle':
'Hiển thị hình ảnh và mô tả khi thêm địa điểm. Wikipedia và OpenStreetMap luôn được dùng; Google được thêm vào khi bật Ảnh địa điểm hoặc Chi tiết địa điểm.',
'admin.transitProvider.title': 'Nhà cung cấp giao thông công cộng',
'admin.transitProvider.subtitle': 'Dịch vụ nào trả lời tìm kiếm giao thông công cộng.',
'admin.transitProvider.transitous': 'Transitous (miễn phí)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'Nguồn GTFS cộng đồng. Miễn phí và không cần khóa, phủ sóng tốt nhất ở châu Âu.',
'admin.transitProvider.googleHint': 'Dùng khóa Google ở trên, cho những khu vực Transitous không có dữ liệu. Tính phí theo mỗi lượt tìm kiếm — khi chưa đặt khóa thì vẫn dùng Transitous.',
'admin.transitProvider.noKeyWarning': 'Đã chọn Google, nhưng chưa cấu hình khóa Google — tìm kiếm giao thông vẫn dùng Transitous. Thêm khóa ở mục Khóa API phía trên.',
'admin.transitProvider.personalKeyWarning': 'Chỉ khóa Google của riêng bạn được đặt, nên tìm kiếm của các thành viên khác vẫn quay về Transitous. Lưu khóa ở trên với quyền quản trị để áp dụng cho toàn bộ máy chủ.',
'admin.bagTracking.title': 'Theo dõi túi',
'admin.bagTracking.subtitle': 'Cho phép phân bổ trọng lượng và túi để đóng gói các mặt hàng',
'admin.collab.chat.title': 'Trò chuyện',
+1
View File
@@ -63,6 +63,7 @@ const trip: TranslationStrings = {
'transit.search': 'Tìm kiếm',
'transit.searching': 'Đang tìm…',
'transit.searchError': 'Tìm tuyến thất bại. Vui lòng thử lại.',
'transit.noResultsVia': 'Không tìm thấy tuyến nào qua {provider}. Hãy thử giờ khác hoặc bộ lọc khác.',
'transit.noResults': 'Không tìm thấy tuyến. Hãy thử thời gian hoặc bộ lọc khác.',
'transit.direct': 'Trực tiếp',
'transit.transfers': '{count} lần chuyển tuyến',
+8
View File
@@ -161,6 +161,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': '地點資訊補充',
'admin.placesEnrich.subtitle':
'新增地點時顯示圖片與描述。一律使用維基百科與 OpenStreetMap;開啟「地點照片」或「地點詳細資料」時會額外使用 Google。',
'admin.transitProvider.title': '公共運輸資料來源',
'admin.transitProvider.subtitle': '由哪個服務回應大眾運輸搜尋。',
'admin.transitProvider.transitous': 'Transitous(免費)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': '社群 GTFS 資料來源。免費且免金鑰,在歐洲的涵蓋率最佳。',
'admin.transitProvider.googleHint': '使用上方的 Google 金鑰,涵蓋 Transitous 沒有資料的地區。依每次搜尋計費——未設定金鑰時仍使用 Transitous。',
'admin.transitProvider.noKeyWarning': '已選擇 Google,但尚未設定 Google 金鑰——大眾運輸搜尋仍在使用 Transitous。請在上方的 API 金鑰中新增金鑰。',
'admin.transitProvider.personalKeyWarning': '只設定了你自己的 Google 金鑰,因此其他成員的搜尋仍會回退到 Transitous。請以管理員身分在上方儲存金鑰,使其套用至整個執行個體。',
'admin.bagTracking.title': '行李追蹤',
'admin.bagTracking.subtitle': '為打包物品啟用重量和行李分配',
'admin.collab.chat.title': '聊天',
+1
View File
@@ -62,6 +62,7 @@ const trip: TranslationStrings = {
'transit.search': '搜尋',
'transit.searching': '搜尋中…',
'transit.searchError': '路線搜尋失敗,請重試。',
'transit.noResultsVia': '透過 {provider} 找不到路線。請嘗試其他時間或篩選條件。',
'transit.noResults': '找不到路線。請嘗試其他時間或篩選條件。',
'transit.direct': '直達',
'transit.transfers': '轉乘 {count} 次',
+8
View File
@@ -122,6 +122,14 @@ const admin: TranslationStrings = {
'admin.placesEnrich.title': '地点信息补充',
'admin.placesEnrich.subtitle':
'添加地点时显示图片和描述。始终使用维基百科和 OpenStreetMap;开启「地点照片」或「地点详情」时会额外使用 Google。',
'admin.transitProvider.title': '公共交通数据源',
'admin.transitProvider.subtitle': '由哪个服务响应公共交通搜索。',
'admin.transitProvider.transitous': 'Transitous(免费)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': '社区 GTFS 数据源。免费且无需密钥,在欧洲覆盖最好。',
'admin.transitProvider.googleHint': '使用上方的 Google 密钥,覆盖 Transitous 没有数据的地区。按每次搜索计费——未设置密钥时仍使用 Transitous。',
'admin.transitProvider.noKeyWarning': '已选择 Google,但未配置 Google 密钥——公共交通搜索仍在使用 Transitous。请在上方的 API 密钥中添加密钥。',
'admin.transitProvider.personalKeyWarning': '只设置了你自己的 Google 密钥,因此其他成员的搜索仍会回退到 Transitous。请以管理员身份在上方保存密钥,使其对整个实例生效。',
'admin.bagTracking.title': '行李追踪',
'admin.bagTracking.subtitle': '为打包物品启用重量和行李分配',
'admin.collab.chat.title': '聊天',
+1
View File
@@ -62,6 +62,7 @@ const trip: TranslationStrings = {
'transit.search': '搜索',
'transit.searching': '搜索中…',
'transit.searchError': '路线搜索失败,请重试。',
'transit.noResultsVia': '通过 {provider} 未找到线路。请尝试其他时间或筛选条件。',
'transit.noResults': '未找到线路,请尝试其他时间或筛选条件。',
'transit.direct': '直达',
'transit.transfers': '换乘 {count} 次',