Add layer translation files

This commit is contained in:
pietervdvn 2021-05-19 20:47:41 +02:00
parent caba824a54
commit d2d0209ead
9 changed files with 6060 additions and 227 deletions

57
langs/layers/ca.json Normal file
View file

@ -0,0 +1,57 @@
{
"defibrillator": {
"name": "Desfibril·ladors",
"title": {
"render": "Desfibril·lador"
},
"presets": {
"0": {
"title": "Desfibril·lador"
}
},
"tagRenderings": {
"1": {
"question": "Està el desfibril·lador a l'interior?",
"mappings": {
"0": {
"then": "Aquest desfibril·lador està a l'interior"
},
"1": {
"then": "Aquest desfibril·lador està a l'exterior"
}
}
},
"2": {
"question": "Està el desfibril·lador accessible lliurement?",
"render": "L'accés és {access}",
"mappings": {
"0": {
"then": "Accés lliure"
},
"1": {
"then": "Publicament accessible"
},
"2": {
"then": "Només accessible a clients"
},
"3": {
"then": "No accessible al públic en general (ex. només accesible a treballadors, propietaris, ...)"
}
}
},
"4": {
"question": "A quina planta està el desfibril·lador localitzat?",
"render": "Aquest desfibril·lador és a la planta {level}"
},
"5": {
"question": "Dóna detalls d'on es pot trobar el desfibril·lador"
},
"6": {
"question": "Dóna detalls d'on es pot trobar el desfibril·lador"
},
"7": {
"question": "Dóna detalls d'on es pot trobar el desfibril·lador"
}
}
}
}

824
langs/layers/de.json Normal file
View file

@ -0,0 +1,824 @@
{
"bench": {
"name": "Sitzbänke",
"title": {
"render": "Sitzbank"
},
"tagRenderings": {
"1": {
"render": "Rückenlehne",
"mappings": {
"0": {
"then": "Rückenlehne: Ja"
},
"1": {
"then": "Rückenlehne: Nein"
}
},
"question": "Hat diese Bank eine Rückenlehne?"
},
"2": {
"render": "{seats} Sitzplätze",
"question": "Wie viele Sitzplätze hat diese Bank?"
},
"3": {
"render": "Material: {material}",
"mappings": {
"0": {
"then": "Material: Holz"
},
"1": {
"then": "Material: Metall"
},
"2": {
"then": "Material: Stein"
},
"3": {
"then": "Material: Beton"
},
"4": {
"then": "Material: Kunststoff"
},
"5": {
"then": "Material: Stahl"
}
},
"question": "Aus welchem Material besteht die Sitzbank (Sitzfläche)?"
},
"4": {
"question": "In welche Richtung schaut man, wenn man auf der Bank sitzt?",
"render": "Wenn man auf der Bank sitzt, schaut man in Richtung {direction}°."
},
"5": {
"render": "Farbe: {colour}",
"question": "Welche Farbe hat diese Sitzbank?",
"mappings": {
"0": {
"then": "Farbe: braun"
},
"1": {
"then": "Farbe: grün"
},
"2": {
"then": "Farbe: grau"
},
"3": {
"then": "Farbe: weiß"
},
"4": {
"then": "Farbe: rot"
},
"5": {
"then": "Farbe: schwarz"
},
"6": {
"then": "Farbe: blau"
},
"7": {
"then": "Farbe: gelb"
}
}
}
},
"presets": {
"0": {
"title": "Sitzbank",
"description": "Neue Sitzbank eintragen"
}
}
},
"bench_at_pt": {
"name": "Sitzbänke bei Haltestellen",
"title": {
"render": "Sitzbank",
"mappings": {
"0": {
"then": "Sitzbank bei Haltestelle"
},
"1": {
"then": "Sitzbank in Unterstand"
}
}
},
"tagRenderings": {
"1": {
"render": "{name}"
},
"2": {
"render": "Stehbank"
}
}
},
"bike_cafe": {
"name": "Fahrrad-Café",
"title": {
"render": "Fahrrad-Café",
"mappings": {
"0": {
"then": "Fahrrad-Café <i>{name}</i>"
}
}
},
"tagRenderings": {
"1": {
"question": "Wie heißt dieses Fahrrad-Café?",
"render": "Dieses Fahrrad-Café heißt {name}"
},
"2": {
"question": "Bietet dieses Fahrrad-Café eine Fahrradpumpe an, die von jedem benutzt werden kann?",
"mappings": {
"0": {
"then": "Dieses Fahrrad-Café bietet eine Fahrradpumpe an, die von jedem benutzt werden kann"
},
"1": {
"then": "Dieses Fahrrad-Café bietet keine Fahrradpumpe an, die von jedem benutzt werden kann"
}
}
},
"3": {
"question": "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?",
"mappings": {
"0": {
"then": "Dieses Fahrrad-Café bietet Werkzeuge für die selbständige Reparatur an."
},
"1": {
"then": "Dieses Fahrrad-Café bietet keine Werkzeuge für die selbständige Reparatur an."
}
}
},
"4": {
"question": "Repariert dieses Fahrrad-Café Fahrräder?",
"mappings": {
"0": {
"then": "Dieses Fahrrad-Café repariert Fahrräder"
},
"1": {
"then": "Dieses Fahrrad-Café repariert keine Fahrräder"
}
}
},
"5": {
"question": "Was ist die Webseite von {name}?"
},
"6": {
"question": "Wie lautet die Telefonnummer von {name}?"
},
"7": {
"question": "Wie lautet die E-Mail-Adresse von {name}?"
}
},
"presets": {
"0": {
"title": "Fahrrad-Café"
}
}
},
"bike_parking": {
"name": "Fahrrad-Parkplätze",
"presets": {
"0": {
"title": "Fahrrad-Parkplätze"
}
},
"title": {
"render": "Fahrrad-Parkplätze"
},
"tagRenderings": {
"1": {
"question": "Was ist die Art dieses Fahrrad-Parkplatzes?",
"render": "Dies ist ein Fahrrad-Parkplatz der Art: {bicycle_parking}",
"mappings": {
"0": {
"then": "Fahrradbügel <img style='width: 25%'' src='./assets/layers/bike_parking/staple.svg'>"
},
"1": {
"then": "Metallgestänge <img style='width: 25%'' src='./assets/layers/bike_parking/wall_loops.svg'>"
},
"2": {
"then": "Halter für Fahrradlenker <img style='width: 25%'' src='./assets/layers/bike_parking/handlebar_holder.svg'>"
},
"3": {
"then": "Gestell <img style='width: 25%'' src='./assets/layers/bike_parking/rack.svg'>"
},
"4": {
"then": "Zweistufig <img style='width: 25%'' src='./assets/layers/bike_parking/two_tier.svg'>"
},
"5": {
"then": "Schuppen <img style='width: 25%'' src='./assets/layers/bike_parking/shed.svg'>"
}
}
},
"3": {
"question": "Ist dieser Parkplatz überdacht? Wählen Sie auch \"überdacht\" für Innenparkplätze.",
"mappings": {
"0": {
"then": "Dieser Parkplatz ist überdacht (er hat ein Dach)"
},
"1": {
"then": "Dieser Parkplatz ist nicht überdacht."
}
}
},
"4": {
"question": "Wie viele Fahrräder passen auf diesen Fahrrad-Parkplatz (einschließlich möglicher Lastenfahrräder)?",
"render": "Platz für {capacity} Fahrräder"
},
"6": {
"question": "Gibt es auf diesem Fahrrad-Parkplatz Plätze für Lastenfahrräder?",
"mappings": {
"0": {
"then": "Dieser Parkplatz bietet Platz für Lastenfahrräder"
},
"1": {
"then": "Dieser Parkplatz verfügt über ausgewiesene (offizielle) Plätze für Lastenfahrräder."
},
"2": {
"then": "Es ist nicht erlaubt, Lastenfahrräder zu parken"
}
}
},
"7": {
"question": "Wie viele Lastenfahrräder passen auf diesen Fahrrad-Parkplatz?",
"render": "Auf diesen Parkplatz passen {capacity:cargo_bike} Lastenfahrräder"
}
}
},
"bike_repair_station": {
"name": "Fahrradstationen (Reparatur, Pumpe oder beides)",
"title": {
"render": "Fahrradstation (Pumpe & Reparatur)",
"mappings": {
"0": {
"then": "Fahrrad-Reparaturstation"
},
"1": {
"then": "Fahrrad-Reparaturstation"
},
"2": {
"then": "Kaputte Pumpe"
},
"3": {
"then": "Fahrradpumpe <i>{name}</i>"
},
"4": {
"then": "Fahrradpumpe"
}
}
},
"tagRenderings": {
"1": {
"question": "Welche Einrichtungen stehen an dieser Fahrradstation zur Verfügung?",
"mappings": {
"0": {
"then": "Es ist nur eine Pumpe vorhanden"
},
"1": {
"then": "Es sind nur Werkzeuge (Schraubenzieher, Zangen...) vorhanden"
},
"2": {
"then": "Es sind sowohl Werkzeuge als auch eine Pumpe vorhanden"
}
}
},
"4": {
"question": "Verfügt diese Fahrrad-Reparaturstation über Spezialwerkzeug zur Reparatur von Fahrradketten?",
"mappings": {
"0": {
"then": "Es gibt ein Kettenwerkzeug"
},
"1": {
"then": "Es gibt kein Kettenwerkzeug"
}
}
},
"5": {
"question": "Hat diese Fahrradstation einen Haken, an dem Sie Ihr Fahrrad aufhängen können, oder einen Ständer, um es anzuheben?",
"mappings": {
"0": {
"then": "Es gibt einen Haken oder Ständer"
},
"1": {
"then": "Es gibt keinen Haken oder Ständer"
}
}
},
"6": {
"question": "Ist die Fahrradpumpe noch funktionstüchtig?",
"mappings": {
"0": {
"then": "Die Fahrradpumpe ist kaputt"
},
"1": {
"then": "Die Fahrradpumpe ist betriebsbereit"
}
}
},
"7": {
"question": "Welche Ventile werden unterstützt?",
"render": "Diese Pumpe unterstützt die folgenden Ventile: {valves}",
"mappings": {
"0": {
"then": "Sklaverand (auch bekannt als Presta)"
},
"1": {
"then": "Dunlop"
},
"2": {
"then": "Schrader (Autos)"
}
}
},
"8": {
"question": "Ist dies eine elektrische Fahrradpumpe?",
"mappings": {
"0": {
"then": "Manuelle Pumpe"
},
"1": {
"then": "Elektrische Pumpe"
}
}
},
"9": {
"question": "Verfügt die Pumpe über einen Druckanzeiger oder ein Manometer?",
"mappings": {
"0": {
"then": "Es gibt ein Manometer"
},
"1": {
"then": "Es gibt kein Manometer"
},
"2": {
"then": "Es gibt ein Manometer, aber es ist kaputt"
}
}
}
},
"presets": {
"0": {
"title": "Fahrradpumpe"
},
"1": {
"title": "Fahrrad-Reparaturstation und Pumpe"
},
"2": {
"title": "Fahrrad-Reparaturstation ohne Pumpe"
}
}
},
"bike_shop": {
"name": "Fahrradwerkstatt/geschäft",
"title": {
"render": "Fahrradwerkstatt/geschäft",
"mappings": {
"3": {
"then": "Fahrradwerkstatt <i>{name}</i>"
},
"4": {
"then": "Fahrradgeschäft <i>{name}</i>"
},
"5": {
"then": "Fahrradwerkstatt/geschäft <i>{name}</i>"
}
}
},
"tagRenderings": {
"2": {
"question": "Wie heißt dieser Fahrradladen?",
"render": "Dieses Fahrradgeschäft heißt {name}"
},
"9": {
"question": "Verkauft dieser Laden Fahrräder?",
"mappings": {
"0": {
"then": "Dieses Geschäft verkauft Fahrräder"
},
"1": {
"then": "Dieses Geschäft verkauft keine Fahrräder"
}
}
},
"10": {
"question": "Repariert dieses Geschäft Fahrräder?",
"mappings": {
"0": {
"then": "Dieses Geschäft repariert Fahrräder"
},
"1": {
"then": "Dieses Geschäft repariert keine Fahrräder"
},
"2": {
"then": "Dieses Geschäft repariert nur hier gekaufte Fahrräder"
},
"3": {
"then": "Dieses Geschäft repariert nur Fahrräder einer bestimmten Marke"
}
}
},
"11": {
"question": "Vermietet dieser Laden Fahrräder?",
"mappings": {
"0": {
"then": "Dieses Geschäft vermietet Fahrräder"
},
"1": {
"then": "Dieses Geschäft vermietet keine Fahrräder"
}
}
},
"12": {
"question": "Verkauft dieses Geschäft gebrauchte Fahrräder?",
"mappings": {
"0": {
"then": "Dieses Geschäft verkauft gebrauchte Fahrräder"
},
"1": {
"then": "Dieses Geschäft verkauft keine gebrauchten Fahrräder"
},
"2": {
"then": "Dieses Geschäft verkauft nur gebrauchte Fahrräder"
}
}
},
"13": {
"question": "Bietet dieses Geschäft eine Fahrradpumpe zur Benutzung für alle an?",
"mappings": {
"0": {
"then": "Dieses Geschäft bietet eine Fahrradpumpe für alle an"
},
"1": {
"then": "Dieses Geschäft bietet für niemanden eine Fahrradpumpe an"
}
}
},
"14": {
"question": "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?",
"mappings": {
"0": {
"then": "Dieses Geschäft bietet Werkzeuge für die Heimwerkerreparatur an"
},
"1": {
"then": "Dieses Geschäft bietet keine Werkzeuge für Heimwerkerreparaturen an"
}
}
}
},
"presets": {
"0": {
"title": "Fahrradwerkstatt/geschäft"
}
}
},
"bike_themed_object": {
"name": "Mit Fahrrad zusammenhängendes Objekt",
"title": {
"render": "Mit Fahrrad zusammenhängendes Objekt"
}
},
"defibrillator": {
"name": "Defibrillatoren",
"title": {
"render": "Defibrillator"
},
"presets": {
"0": {
"title": "Defibrillator"
}
},
"tagRenderings": {
"1": {
"question": "Befindet sich dieser Defibrillator im Gebäude?",
"mappings": {
"0": {
"then": "Dieser Defibrillator befindet sich im Gebäude"
},
"1": {
"then": "Dieser Defibrillator befindet sich im Freien"
}
}
},
"2": {
"question": "Ist dieser Defibrillator frei zugänglich?",
"render": "Zugang ist {access}",
"mappings": {
"0": {
"then": "Öffentlich zugänglich"
},
"1": {
"then": "Öffentlich zugänglich"
},
"2": {
"then": "Nur für Kunden zugänglich"
},
"3": {
"then": "Nicht für die Öffentlichkeit zugänglich (z.B. nur für das Personal, die Eigentümer, ...)"
}
}
},
"4": {
"question": "In welchem Stockwerk befindet sich dieser Defibrillator?",
"render": "Dieser Defibrallator befindet sich im {level}. Stockwerk"
},
"5": {
"question": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (in der lokalen Sprache)"
},
"6": {
"question": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Englisch)"
},
"7": {
"question": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Französisch)"
}
}
},
"drinking_water": {
"name": "Trinkwasser",
"title": {
"render": "Trinkwasser"
},
"presets": {
"0": {
"title": "Trinkwasser"
}
},
"tagRenderings": {
"2": {
"question": "Wie einfach ist es, Wasserflaschen zu füllen?",
"mappings": {
"0": {
"then": "Es ist einfach, Wasserflaschen nachzufüllen"
},
"1": {
"then": "Wasserflaschen passen möglicherweise nicht"
}
}
}
}
},
"ghost_bike": {
"name": "Geisterrad",
"title": {
"render": "Geisterrad",
"mappings": {
"0": {
"then": "Geisterrad im Gedenken an {name}"
}
}
},
"presets": {
"0": {
"title": "Geisterrad"
}
},
"tagRenderings": {
"0": {
"render": "Ein <b>Geisterrad</b> ist ein Denkmal für einen Radfahrer, der bei einem Verkehrsunfall ums Leben kam, in Form eines weißen Fahrrades, das dauerhaft in der Nähe des Unfallortes aufgestellt wird."
},
"2": {
"question": "An wen erinnert dieses Geisterrad?<span class='question-subtext'><br/>Bitte respektieren Sie die Privatsphäre - geben Sie den Namen nur an, wenn er weit verbreitet oder auf dem Fahrrad markiert ist. Den Familiennamen können Sie weglassen.</span>",
"render": "Im Gedenken an {name}",
"mappings": {
"0": {
"then": "Auf dem Fahrrad ist kein Name angegeben"
}
}
},
"3": {
"question": "Auf welcher Webseite kann man mehr Informationen über das Geisterrad oder den Unfall finden?",
"render": "<a href='{source}' target='_blank'>Mehr Informationen</a>"
},
"4": {
"question": "Wie lautet die Inschrift auf diesem Geisterrad?",
"render": "<i>{inscription}</i>"
}
}
},
"public_bookcase": {
"name": "Bücherschränke",
"description": "Ein Bücherschrank am Straßenrand mit Büchern, für jedermann zugänglich",
"title": {
"render": "Bücherschrank",
"mappings": {
"0": {
"then": "Öffentlicher Bücherschrank <i>{name}</i>"
}
}
},
"presets": {
"0": {
"title": "Bücherschrank"
}
},
"tagRenderings": {
"1": {
"render": "Der Name dieses Bücherschrank lautet {name}",
"question": "Wie heißt dieser öffentliche Bücherschrank?",
"mappings": {
"0": {
"then": "Dieser Bücherschrank hat keinen Namen"
}
}
},
"2": {
"render": "{capacity} Bücher passen in diesen Bücherschrank",
"question": "Wie viele Bücher passen in diesen öffentlichen Bücherschrank?"
},
"3": {
"question": "Welche Art von Büchern sind in diesem öffentlichen Bücherschrank zu finden?",
"mappings": {
"0": {
"then": "Vorwiegend Kinderbücher"
},
"1": {
"then": "Vorwiegend Bücher für Erwachsene"
},
"2": {
"then": "Sowohl Bücher für Kinder als auch für Erwachsene"
}
}
},
"4": {
"question": "Befindet sich dieser Bücherschrank im Freien?",
"mappings": {
"0": {
"then": "Dieser Bücherschrank befindet sich im Innenbereich"
},
"1": {
"then": "Dieser Bücherschrank befindet sich im Freien"
},
"2": {
"then": "Dieser Bücherschrank befindet sich im Freien"
}
}
},
"5": {
"question": "Ist dieser öffentliche Bücherschrank frei zugänglich?",
"mappings": {
"0": {
"then": "Öffentlich zugänglich"
},
"1": {
"then": "Nur für Kunden zugänglich"
}
}
},
"6": {
"question": "Wer unterhält diesen öffentlichen Bücherschrank?",
"render": "Betrieben von {operator}"
},
"7": {
"question": "Ist dieser öffentliche Bücherschrank Teil eines größeren Netzwerks?",
"render": "Dieser Bücherschrank ist Teil von {brand}",
"mappings": {
"0": {
"then": "Teil des Netzwerks 'Little Free Library'"
},
"1": {
"then": "Dieser öffentliche Bücherschrank ist nicht Teil eines größeren Netzwerks"
}
}
},
"8": {
"render": "Die Referenznummer dieses öffentlichen Bücherschranks innerhalb {brand} lautet {ref}",
"question": "Wie lautet die Referenznummer dieses öffentlichen Bücherschranks?",
"mappings": {
"0": {
"then": "Dieser Bücherschrank ist nicht Teil eines größeren Netzwerks"
}
}
},
"9": {
"question": "Wann wurde dieser öffentliche Bücherschrank installiert?",
"render": "Installiert am {start_date}"
},
"10": {
"render": "Weitere Informationen auf <a href='{website}' target='_blank'>der Webseite</a>",
"question": "Gibt es eine Webseite mit weiteren Informationen über diesen öffentlichen Bücherschrank?"
}
}
},
"toilet": {
"name": "Toiletten",
"title": {
"render": "Toilette"
},
"presets": {
"0": {
"title": "Toilette",
"description": "Eine öffentlich zugängliche Toilette"
},
"1": {
"title": "Toiletten mit rollstuhlgerechter Toilette",
"description": "Eine Toilettenanlage mit mindestens einer rollstuhlgerechten Toilette"
}
},
"tagRenderings": {
"1": {
"question": "Sind diese Toiletten öffentlich zugänglich?",
"render": "Zugang ist {access}",
"mappings": {
"0": {
"then": "Öffentlicher Zugang"
},
"1": {
"then": "Nur Zugang für Kunden"
},
"2": {
"then": "Nicht zugänglich"
},
"3": {
"then": "Zugänglich, aber man muss einen Schlüssel für die Eingabe verlangen"
}
}
},
"2": {
"question": "Können diese Toiletten kostenlos benutzt werden?",
"mappings": {
"0": {
"then": "Dies sind bezahlte Toiletten"
},
"1": {
"then": "Kostenlose Nutzung"
}
}
},
"3": {
"question": "Wie viel muss man für diese Toiletten bezahlen?",
"render": "Die Gebühr beträgt {charge}"
},
"4": {
"question": "Gibt es eine Toilette für Rollstuhlfahrer?",
"mappings": {
"0": {
"then": "Es gibt eine Toilette für Rollstuhlfahrer"
},
"1": {
"then": "Kein Zugang für Rollstuhlfahrer"
}
}
},
"5": {
"question": "Welche Art von Toiletten sind das?",
"mappings": {
"0": {
"then": "Es gibt nur Sitztoiletten"
},
"1": {
"then": "Hier gibt es nur Pissoirs"
},
"2": {
"then": "Es gibt hier nur Hocktoiletten."
},
"3": {
"then": "Sowohl Sitztoiletten als auch Pissoirs sind hier verfügbar"
}
}
},
"6": {
"question": "Ist ein Wickeltisch (zum Wechseln der Windeln) vorhanden?",
"mappings": {
"0": {
"then": "Ein Wickeltisch ist verfügbar"
},
"1": {
"then": "Es ist kein Wickeltisch verfügbar"
}
}
},
"7": {
"question": "Wo befindet sich der Wickeltisch?",
"render": "Die Wickeltabelle befindet sich in {changing_table:location}",
"mappings": {
"0": {
"then": "Der Wickeltisch befindet sich in der Damentoilette. "
},
"1": {
"then": "Der Wickeltisch befindet sich in der Herrentoilette. "
},
"2": {
"then": "Der Wickeltisch befindet sich in der Toilette für Rollstuhlfahrer. "
},
"3": {
"then": "Der Wickeltisch befindet sich in einem eigenen Raum. "
}
}
}
}
},
"viewpoint": {
"name": "Aussichtspunkt",
"description": "Ein schöner Aussichtspunkt oder eine schöne Aussicht. Ideal zum Hinzufügen eines Bildes, wenn keine andere Kategorie passt",
"presets": {
"0": {
"title": "Aussichtspunkt"
}
},
"title": {
"render": "Aussichtspunkt"
},
"tagRenderings": {
"1": {
"question": "Möchten Sie eine Beschreibung hinzufügen?"
}
}
}
}

1785
langs/layers/en.json Normal file

File diff suppressed because it is too large Load diff

57
langs/layers/es.json Normal file
View file

@ -0,0 +1,57 @@
{
"defibrillator": {
"name": "Desfibriladores",
"title": {
"render": "Desfibrilador"
},
"presets": {
"0": {
"title": "Desfibrilador"
}
},
"tagRenderings": {
"1": {
"question": "¿Esté el desfibrilador en interior?",
"mappings": {
"0": {
"then": "Este desfibrilador está en interior"
},
"1": {
"then": "Este desfibrilador está en exterior"
}
}
},
"2": {
"question": "¿Está el desfibrilador accesible libremente?",
"render": "El acceso es {access}",
"mappings": {
"0": {
"then": "Acceso libre"
},
"1": {
"then": "Publicament accesible"
},
"2": {
"then": "Sólo accesible a clientes"
},
"3": {
"then": "No accesible al público en general (ex. sólo accesible a trabajadores, propietarios, ...)"
}
}
},
"4": {
"question": "¿En qué planta se encuentra el defibrilador localizado?",
"render": "El desfibrilador se encuentra en la planta {level}"
},
"5": {
"question": "Da detalles de dónde se puede encontrar el desfibrilador (en el idioma local)"
},
"6": {
"question": "Da detalles de dónde se puede encontrar el desfibrilador (en ingles)"
},
"7": {
"question": "Da detalles de dónde se puede encontrar el desfibrilador (en frances)"
}
}
}
}

853
langs/layers/fr.json Normal file
View file

@ -0,0 +1,853 @@
{
"bench": {
"name": "Bancs",
"title": {
"render": "Banc"
},
"tagRenderings": {
"1": {
"render": "Dossier",
"mappings": {
"0": {
"then": "Dossier: Oui"
},
"1": {
"then": "Dossier: Non"
}
},
"question": "Ce banc dispose-t-il d'un dossier ?"
},
"2": {
"render": "{seats} places",
"question": "De combien de places dispose ce banc ?"
},
"3": {
"render": "Matériau : {material}",
"mappings": {
"0": {
"then": "Matériau : bois"
},
"1": {
"then": "Matériau : métal"
},
"2": {
"then": "Matériau: pierre"
},
"3": {
"then": "Matériau : béton"
},
"4": {
"then": "Matériau : plastique"
},
"5": {
"then": "Matériau : acier"
}
},
"question": "De quel matériau ce banc est-il fait ?"
},
"5": {
"render": "Couleur : {colour}",
"question": "Quelle est la couleur de ce banc ?",
"mappings": {
"0": {
"then": "Couleur : marron"
},
"1": {
"then": "Couleur : verte"
},
"2": {
"then": "Couleur : gris"
},
"3": {
"then": "Couleur : blanc"
},
"4": {
"then": "Couleur : rouge"
},
"5": {
"then": "Couleur : noire"
},
"6": {
"then": "Couleur : bleu"
},
"7": {
"then": "Couleur : jaune"
}
}
}
},
"presets": {
"0": {
"title": "Banc",
"description": "Ajouter un nouveau banc"
}
}
},
"bench_at_pt": {
"name": "Bancs des arrêts de transport en commun",
"title": {
"render": "Banc",
"mappings": {
"0": {
"then": "Banc d'un arrêt de transport en commun"
},
"1": {
"then": "Banc dans un abri"
}
}
},
"tagRenderings": {
"1": {
"render": "{name}"
},
"2": {
"render": "Banc assis debout"
}
}
},
"bike_cafe": {
"name": "Café vélo",
"title": {
"render": "Café Vélo",
"mappings": {
"0": {
"then": "Café Vélo <i>{name}</i>"
}
}
},
"tagRenderings": {
"1": {
"question": "Quel est le nom de ce Café vélo",
"render": "Ce Café vélo s'appelle {name}"
},
"2": {
"question": "Est-ce que ce Café vélo propose une pompe en libre accès",
"mappings": {
"0": {
"then": "Ce Café vélo offre une pompe en libre accès"
},
"1": {
"then": "Ce Café vélo n'offre pas de pompe en libre accès"
}
}
},
"3": {
"question": "Est-ce qu'il y a des outils pour réparer soi-même son vélo?",
"mappings": {
"0": {
"then": "Ce Café vélo propose des outils pour réparer son vélo soi-même"
},
"1": {
"then": "Ce Café vélo ne propose pas d'outils pour réparer son vélo soi-même"
}
}
},
"4": {
"question": "Est-ce que ce Café vélo répare les vélos?",
"mappings": {
"0": {
"then": "Ce Café vélo répare les vélos"
},
"1": {
"then": "Ce Café vélo ne répare pas les vélos"
}
}
},
"5": {
"question": "Quel est le site internet de {name}?"
},
"6": {
"question": "Quel est le nom de {name}?"
},
"7": {
"question": "Quel est l'adresse email de {name}?"
}
},
"presets": {
"0": {
"title": "Café Vélo"
}
}
},
"bike_parking": {
"name": "Parking à vélo",
"presets": {
"0": {
"title": "Parking à vélo"
}
},
"title": {
"render": "Parking à vélo"
},
"tagRenderings": {
"1": {
"question": "Quelle type de parking s'agit il?",
"render": "Ceci est un parking à vélo de type {bicycle_parking}",
"mappings": {
"0": {
"then": "Arceaux <img style='width: 25%'' src='./assets/layers/bike_parking/staple.svg'>"
},
"1": {
"then": "Pinces-roues <img style='width: 25%'' src='./assets/layers/bike_parking/wall_loops.svg'>"
},
"2": {
"then": "Support guidon <img style='width: 25%'' src='./assets/layers/bike_parking/handlebar_holder.svg'>"
},
"3": {
"then": "Râtelier <img style='width: 25%'' src='./assets/layers/bike_parking/rack.svg'>"
},
"4": {
"then": "Superposé <img style='width: 25%'' src='./assets/layers/bike_parking/two_tier.svg'>"
},
"5": {
"then": "Abri <img style='width: 25%'' src='./assets/layers/bike_parking/shed.svg'>"
}
}
},
"4": {
"question": "Combien de vélos entrent dans ce parking à vélos (y compris les éventuels vélos de transport) ?",
"render": "Place pour {capacity} vélos"
},
"7": {
"question": "Combien de vélos de transport entrent dans ce parking à vélos ?",
"render": "Ce parking a de la place pour {capacity:cargo_bike} vélos de transport."
}
}
},
"bike_repair_station": {
"name": "Station velo (réparation, pompe à vélo)",
"title": {
"render": "Point station velo avec pompe",
"mappings": {
"0": {
"then": "Point de réparation velo"
},
"1": {
"then": "Point de réparation"
},
"2": {
"then": "Pompe cassée"
},
"3": {
"then": "Pompe de vélo <i>{name}</i>"
},
"4": {
"then": "Pompe de vélo"
}
}
},
"tagRenderings": {
"1": {
"question": "Quels services sont valables à cette station vélo?",
"mappings": {
"0": {
"then": "Il y a seulement une pompe"
},
"1": {
"then": "Il y a seulement des outils (tournevis, pinces...)"
},
"2": {
"then": "Il y a des outils et une pompe"
}
}
},
"4": {
"question": "Est-ce que cette station vélo a un outils specifique pour réparer la chaîne du velo?",
"mappings": {
"0": {
"then": "Il y a un outil pour réparer la chaine"
},
"1": {
"then": "Il n'y a pas d'outil pour réparer la chaine"
}
}
},
"5": {
"question": "Est-ce que cette station vélo à un crochet pour suspendre son velo ou une accroche pour l'élevé?",
"mappings": {
"0": {
"then": "Il y a un crochet ou une accroche"
},
"1": {
"then": "Il n'y pas de crochet ou d'accroche"
}
}
},
"6": {
"question": "Est-ce que cette pompe marche t'elle toujours?",
"mappings": {
"0": {
"then": "La pompe est cassé"
},
"1": {
"then": "La pompe est opérationnelle"
}
}
},
"7": {
"question": "Quelles valves sont compatibles?",
"render": "Cette pompe est compatible avec les valves suivantes: {valves}",
"mappings": {
"0": {
"then": "Sclaverand (aussi appelé Presta)"
},
"1": {
"then": "Dunlop"
},
"2": {
"then": "Schrader (les valves de voitures)"
}
}
},
"8": {
"question": "Est-ce que cette pompe est électrique?",
"mappings": {
"0": {
"then": "Pompe manuelle"
},
"1": {
"then": "Pompe électrique"
}
}
},
"9": {
"question": "Est-ce que la pompe à un manomètre integré?",
"mappings": {
"0": {
"then": "Il y a un manomètre"
},
"1": {
"then": "Il n'y a pas de manomètre"
},
"2": {
"then": "Il y a un manomètre mais il est cassé"
}
}
}
},
"presets": {
"0": {
"title": "Pompe à vélo"
},
"1": {
"title": "Point de réparation vélo avec pompe"
},
"2": {
"title": "Point de réparation vélo sans pompe"
}
}
},
"bike_shop": {
"name": "Magasin ou réparateur de vélo",
"title": {
"render": "Magasin ou réparateur de vélo",
"mappings": {
"0": {
"then": "Magasin de sport <i>{name}</i>"
},
"3": {
"then": "Réparateur de vélo <i>{name}</i>"
},
"4": {
"then": "Magasin de vélo <i>{name}</i>"
},
"5": {
"then": "Magasin ou réparateur de vélo <i>{name}</i>"
}
}
},
"tagRenderings": {
"2": {
"question": "Quel est le nom du magasin de vélo?",
"render": "Ce magasin s'appelle {name}"
},
"3": {
"question": "Quel est le site internet de {name}?"
},
"4": {
"question": "Quel est le nom de {name}?"
},
"5": {
"question": "Quel est l'adresse email de {name}?"
},
"9": {
"question": "Est-ce que ce magasin vend des vélos?",
"mappings": {
"0": {
"then": "Ce magasin vend des vélos"
},
"1": {
"then": "Ce magasin ne vend pas de vélo"
}
}
},
"10": {
"question": "Est-ce que ce magasin répare des vélos?",
"mappings": {
"0": {
"then": "Ce magasin répare des vélos"
},
"1": {
"then": "Ce magasin ne répare pas les vélos"
},
"2": {
"then": "Ce magasin ne répare seulement les vélos achetés là-bas"
},
"3": {
"then": "Ce magasin ne répare seulement des marques spécifiques"
}
}
},
"11": {
"question": "Est-ce ce magasin loue des vélos?",
"mappings": {
"0": {
"then": "Ce magasin loue des vélos"
},
"1": {
"then": "Ce magasin ne loue pas de vélos"
}
}
},
"12": {
"question": "Est-ce ce magasin vend des vélos d'occasion",
"mappings": {
"0": {
"then": "Ce magasin vend des vélos d'occasion"
},
"1": {
"then": "Ce magasin ne vend pas de vélos d'occasion"
},
"2": {
"then": "Ce magasin vend seulement des vélos d'occasion"
}
}
},
"13": {
"question": "Est-ce que ce magasin offre une pompe en accès libre?",
"mappings": {
"0": {
"then": "Ce magasin offre une pompe en acces libre"
},
"1": {
"then": "Ce magasin n'offre pas de pompe en libre accès"
}
}
},
"14": {
"question": "Est-ce qu'il y a des outils pour réparer son vélo dans ce magasin?",
"mappings": {
"0": {
"then": "Ce magasin offre des outils pour réparer son vélo soi-même"
},
"1": {
"then": "Ce magasin n'offre pas des outils pour réparer son vélo soi-même"
}
}
}
},
"presets": {
"0": {
"title": "Magasin et réparateur de vélo"
}
}
},
"bike_themed_object": {
"name": "Objet cycliste",
"title": {
"render": "Objet cycliste"
}
},
"defibrillator": {
"name": "Défibrillateurs",
"title": {
"render": "Défibrillateur"
},
"presets": {
"0": {
"title": "Défibrillateur"
}
},
"tagRenderings": {
"1": {
"question": "Ce défibrillateur est-il disposé en intérieur ?",
"mappings": {
"0": {
"then": "Ce défibrillateur est en intérieur (dans un batiment)"
},
"1": {
"then": "Ce défibrillateur est situé en extérieur"
}
}
},
"2": {
"question": "Ce défibrillateur est-il librement accessible ?",
"render": "{access} accessible",
"mappings": {
"0": {
"then": "Librement accessible"
},
"1": {
"then": "Librement accessible"
},
"2": {
"then": "Réservé aux clients du lieu"
},
"3": {
"then": "Non accessible au public (par exemple réservé au personnel, au propriétaire, ...)"
}
}
},
"4": {
"question": "À quel étage est situé ce défibrillateur ?",
"render": "Ce défibrillateur est à l'étage {level}"
},
"5": {
"question": "Veuillez indiquez plus précisément où se situe le défibrillateur (dans la langue local)"
},
"6": {
"question": "Veuillez indiquez plus précisément où se situe le défibrillateur (en englais)"
},
"7": {
"question": "Veuillez indiquez plus précisément où se situe le défibrillateur (en français)"
},
"11": {
"render": "Numéro de téléphone pour questions sur le défibrillateur: <a href='tel:{phone}'>{phone}</a>",
"question": "Quel est le numéro de téléphone pour questions sur le défibrillateur?"
}
}
},
"drinking_water": {
"name": "Eau potable",
"title": {
"render": "Eau potable"
},
"presets": {
"0": {
"title": "Eau potable"
}
}
},
"public_bookcase": {
"name": "Microbibliothèque",
"description": "Une armoire ou une boite contenant des livres en libre accès",
"title": {
"render": "Microbibliothèque",
"mappings": {
"0": {
"then": "Microbibliothèque <i>{name}</i>"
}
}
},
"presets": {
"0": {
"title": "Microbibliothèque"
}
},
"tagRenderings": {
"1": {
"render": "Le nom de cette microbibliothèque est {name}",
"question": "Quel est le nom de cette microbibliothèque ?",
"mappings": {
"0": {
"then": "Cette microbibliothèque n'a pas de nom"
}
}
},
"2": {
"render": "{capacity} livres rentrent dans cette microbibliothèque",
"question": "Combien de livre rentrent dans cette microbibliothèque ?"
},
"3": {
"question": "Quel type de livres peuvent être trouvés dans cette microbibliothèque ?",
"mappings": {
"0": {
"then": "Livres pour enfants"
},
"1": {
"then": "Livres pour les adultes"
},
"2": {
"then": "Livres pour enfants et adultes également"
}
}
},
"4": {
"question": "Cette microbiliothèque est-elle en extérieur ?",
"mappings": {
"0": {
"then": "Cette microbibliothèque est en intérieur"
},
"1": {
"then": "Cette microbibliothèque est en extérieur"
},
"2": {
"then": "Cette microbibliothèque est en extérieur"
}
}
},
"5": {
"question": "Cette microbibliothèque est-elle librement accèssible ?",
"mappings": {
"0": {
"then": "Accèssible au public"
},
"1": {
"then": "Accèssible aux clients"
}
}
},
"6": {
"question": "Qui entretien cette microbibliothèque",
"render": "Entretenue par {operator}"
},
"7": {
"question": "Cette microbibliothèque fait-elle partie d'un réseau/groupe ?",
"render": "Cette microbibliothèque fait partie du groupe {brand}",
"mappings": {
"0": {
"then": "Fait partie du réseau 'Little Free Library'"
},
"1": {
"then": "Cette microbibliothèque ne fait pas partie d'un réseau/groupe"
}
}
},
"8": {
"render": "Cette microbibliothèque du réseau {brand} possède le numéro {ref}",
"question": "Quelle est le numéro de référence de cette microbibliothèque ?",
"mappings": {
"0": {
"then": "Cette microbibliothèque ne fait pas partie d'un réseau/groupe"
}
}
},
"9": {
"question": "Quand a été installée cette microbibliothèque ?",
"render": "Installée le {start_date}"
},
"10": {
"render": "Plus d'info sur <a href='{website} target='_blank'>le site web</a>",
"question": "Existe-t-il un site web avec plus d'information sur cette microbibliothèque ?"
}
}
},
"sport_pitch": {
"name": "Terrains de sport",
"title": {
"render": "Terrain de sport"
},
"description": "Un terrain de sport",
"tagRenderings": {
"1": {
"render": "Ici on joue au {sport}",
"question": "À quel sport peut-on jouer ici ?",
"mappings": {
"0": {
"then": "Ici on peut jouer au basket"
},
"1": {
"then": "Ici on joue au foot"
},
"2": {
"then": "C'est une table de ping-pong"
},
"3": {
"then": "Ici on peut jouer au tennis"
},
"4": {
"then": "Ici on peut jouer au korfbal"
},
"5": {
"then": "Ici on peut jouer au basket"
}
}
},
"2": {
"question": "De quelle surface est fait ce terrain de sport ?",
"render": "La surface est <b>{surface}</b>",
"mappings": {
"0": {
"then": "La surface est de l'<b>herbe</b>"
},
"1": {
"then": "La surface est du <b>sable</b>"
},
"2": {
"then": "La surface est des <b>pavés</b>"
},
"3": {
"then": "La surface est de l'<b>asphalte</b>"
},
"4": {
"then": "La surface est du <b>béton</b>"
}
}
},
"3": {
"question": "Est-ce que ce terrain de sport est accessible au public ?",
"mappings": {
"0": {
"then": "Accessible au public"
},
"1": {
"then": "Accès limité (par exemple uniquement sur réservation, à certains horaires, ...)"
},
"2": {
"then": "Accessible uniquement aux membres du club"
},
"3": {
"then": "Privé - Pas accessible au public"
}
}
},
"4": {
"question": "Doit-on réserver pour utiliser ce terrain de sport ?",
"mappings": {
"0": {
"then": "Il est obligatoire de réserver pour utiliser ce terrain de sport"
},
"1": {
"then": "Il est recommendé de réserver pour utiliser ce terrain de sport"
},
"2": {
"then": "Il est possible de réserver, mais ce n'est pas nécéssaire pour utiliser ce terrain de sport"
},
"3": {
"then": "On ne peux pas réserver"
}
}
},
"5": {
"question": "Quel est le numéro de téléphone du gérant ?"
},
"6": {
"question": "Quel est l'adresse courriel du gérant ?"
},
"7": {
"question": "Quand ce terrain est-il accessible ?",
"mappings": {
"1": {
"then": "Accessible en permanence"
}
}
}
},
"presets": {
"0": {
"title": "Table de ping-pong"
},
"1": {
"title": "Terrain de sport"
}
}
},
"toilet": {
"name": "Toilettes",
"title": {
"render": "Toilettes"
},
"presets": {
"0": {
"title": "Toilettes",
"description": "Des toilettes"
},
"1": {
"title": "Toilettes accessible aux personnes à mobilité réduite",
"description": "Toilettes avec au moins un WC accessible aux personnes à mobilité réduite"
}
},
"tagRenderings": {
"1": {
"question": "Ces toilettes sont-elles accessibles publiquement ?",
"render": "L'accès est {access}",
"mappings": {
"0": {
"then": "Accès publique"
},
"1": {
"then": "Accès réservé aux clients"
},
"2": {
"then": "WC privés"
},
"3": {
"then": "Accessible, mais vous devez demander la clé"
}
}
},
"2": {
"question": "Ces toilettes sont-elles payantes",
"mappings": {
"0": {
"then": "Toilettes payantes"
},
"1": {
"then": "Toilettes gratuites"
}
}
},
"3": {
"question": "Quel est le prix d'accès de ces toilettes ?",
"render": "Le prix est {charge}"
},
"4": {
"question": "Un WC réservé aux personnes à mobilité réduite est-il présent ?",
"mappings": {
"0": {
"then": "Il y a un WC réservé pour les personnes à mobilité réduite"
},
"1": {
"then": "Non accessible aux personnes à mobilité réduite"
}
}
},
"5": {
"question": "De quel type sont ces toilettes ?",
"mappings": {
"0": {
"then": "Il y a uniquement des WC assis"
},
"1": {
"then": "Il y a uniquement des urinoirs"
},
"2": {
"then": "Il y a uniquement des WC turques"
},
"3": {
"then": "Il y a des WC assis et des urinoirs"
}
}
},
"6": {
"question": "Ces WC disposent-ils d'une table à langer ?",
"mappings": {
"0": {
"then": "Une table à langer est disponible"
},
"1": {
"then": "Aucune table à langer"
}
}
},
"7": {
"question": "Où se situe la table à langer ?",
"render": "Emplacement de la table à langer : {changing_table:location}",
"mappings": {
"0": {
"then": "La table à langer se situe dans les WC pour femmes. "
},
"1": {
"then": "La table à langer se situe dans les WC pour hommes. "
},
"2": {
"then": "La table à langer se situe dans les WC pour personnes à mobilité réduite. "
},
"3": {
"then": "La table à langer se situe dans un espace dédié. "
}
}
}
}
}
}

382
langs/layers/gl.json Normal file
View file

@ -0,0 +1,382 @@
{
"bike_cafe": {
"name": "Café de ciclistas",
"title": {
"render": "Café de ciclistas",
"mappings": {
"0": {
"then": "Café de ciclistas <i>{name}</i>"
}
}
},
"tagRenderings": {
"1": {
"question": "Cal é o nome deste café de ciclistas?",
"render": "Este café de ciclistas chámase {name}"
},
"2": {
"question": "Este café de ciclistas ofrece unha bomba de ar para que calquera persoa poida usala?",
"mappings": {
"0": {
"then": "Este café de ciclistas ofrece unha bomba de ar"
},
"1": {
"then": "Este café de ciclistas non ofrece unha bomba de ar"
}
}
},
"3": {
"question": "Hai ferramentas aquí para arranxar a túa propia bicicleta?",
"mappings": {
"0": {
"then": "Hai ferramentas aquí para arranxar a túa propia bicicleta"
},
"1": {
"then": "Non hai ferramentas aquí para arranxar a túa propia bicicleta"
}
}
},
"4": {
"question": "Este café de ciclistas arranxa bicicletas?",
"mappings": {
"0": {
"then": "Este café de ciclistas arranxa bicicletas"
},
"1": {
"then": "Este café de ciclistas non arranxa bicicletas"
}
}
},
"5": {
"question": "Cal é a páxina web de {name}?"
},
"6": {
"question": "Cal é o número de teléfono de {name}?"
},
"7": {
"question": "Cal é o enderezo de correo electrónico de {name}?"
}
},
"presets": {
"0": {
"title": "Café de ciclistas"
}
}
},
"bike_parking": {
"name": "Aparcadoiro de bicicletas",
"presets": {
"0": {
"title": "Aparcadoiro de bicicletas"
}
},
"title": {
"render": "Aparcadoiro de bicicletas"
},
"tagRenderings": {
"1": {
"question": "Que tipo de aparcadoiro de bicicletas é?",
"render": "Este é un aparcadoiro de bicicletas do tipo: {bicycle_parking}",
"mappings": {
"0": {
"then": "De roda (Stands) <img style='width: 25%'' src='./assets/layers/bike_parking/staple.svg'>"
},
"1": {
"then": "Aros <img style='width: 25%'' src='./assets/layers/bike_parking/wall_loops.svg'>"
},
"2": {
"then": "Cadeado para guiador <img style='width: 25%'' src='./assets/layers/bike_parking/handlebar_holder.svg'>"
},
"3": {
"then": "Cremalleira <img style='width: 25%'' src='./assets/layers/bike_parking/rack.svg'>"
},
"4": {
"then": "Dobre cremalleira <img style='width: 25%'' src='./assets/layers/bike_parking/two_tier.svg'>"
},
"5": {
"then": "Abeiro <img style='width: 25%'' src='./assets/layers/bike_parking/shed.svg'>"
}
}
},
"3": {
"question": "Este aparcadoiro está cuberto? Tamén escolle \"cuberto\" para aparcadoiros interiores.",
"mappings": {
"0": {
"then": "Este aparcadoiro está cuberto (ten un teito)"
},
"1": {
"then": "Este aparcadoiro non está cuberto"
}
}
},
"4": {
"question": "Cantas bicicletas caben neste aparcadoiro de bicicletas (incluídas as posíbeis bicicletas de carga)?",
"render": "Lugar para {capacity} bicicletas"
},
"6": {
"question": "Este aparcadoiro de bicicletas ten espazo para bicicletas de carga?",
"mappings": {
"0": {
"then": "Este aparcadoiro ten espazo para bicicletas de carga."
},
"1": {
"then": "Este aparcadoiro ten espazos designados (oficiais) para bicicletas de carga."
},
"2": {
"then": "Non está permitido aparcar bicicletas de carga"
}
}
},
"7": {
"question": "Cantas bicicletas de carga caben neste aparcadoiro de bicicletas?",
"render": "Neste aparcadoiro caben {capacity:cargo_bike} bicicletas de carga"
}
}
},
"bike_repair_station": {
"name": "Estación de bicicletas (arranxo, bomba de ar ou ambos)",
"title": {
"render": "Estación de bicicletas (arranxo e bomba de ar)",
"mappings": {
"0": {
"then": "Estación de arranxo de bicicletas"
},
"1": {
"then": "Estación de arranxo de bicicletas"
},
"2": {
"then": "Bomba de ar estragada"
},
"3": {
"then": "Bomba de ar <i>{name}</i>"
},
"4": {
"then": "Bomba de ar"
}
}
},
"tagRenderings": {
"1": {
"question": "Que servizos están dispoñíbeis nesta estación de bicicletas?",
"mappings": {
"0": {
"then": "Só hai unha bomba de ar presente"
},
"1": {
"then": "Só hai ferramentas (desaparafusadores, alicates...) presentes"
},
"2": {
"then": "Hai ferramentas e unha bomba de ar presentes"
}
}
},
"4": {
"question": "Esta estación de arranxo de bicicletas ten unha ferramenta especial para arranxar a cadea da túa bicicleta?",
"mappings": {
"0": {
"then": "Hai unha ferramenta para a cadea"
},
"1": {
"then": "Non hai unha ferramenta para a cadea"
}
}
},
"5": {
"question": "Esta estación de bicicletas ten un guindastre para pendurar a túa bicicleta ou un soporte para elevala?",
"mappings": {
"0": {
"then": "Hai un guindastre ou soporte"
},
"1": {
"then": "Non hai un guindastre ou soporte"
}
}
},
"6": {
"question": "Segue a funcionar a bomba de ar?",
"mappings": {
"0": {
"then": "A bomba de ar está estragada"
},
"1": {
"then": "A bomba de ar está operativa"
}
}
},
"7": {
"question": "Que válvulas son compatíbeis?",
"render": "Esta bomba de ar admite as seguintes válvulas: {valves}",
"mappings": {
"0": {
"then": "Sclaverand (tamén coñecido como Presta)"
},
"1": {
"then": "Dunlop"
},
"2": {
"then": "Schrader (para automóbiles)"
}
}
},
"8": {
"question": "Esta é unha bomba de ar eléctrica?",
"mappings": {
"0": {
"then": "Bomba de ar manual"
},
"1": {
"then": "Bomba de ar eléctrica"
}
}
},
"9": {
"question": "Ten a bomba de ar un indicador de presión ou un manómetro?",
"mappings": {
"0": {
"then": "Hai manómetro"
},
"1": {
"then": "Non hai manómetro"
},
"2": {
"then": "Hai manómetro pero está estragado"
}
}
}
},
"presets": {
"0": {
"title": "Bomba de ar"
},
"1": {
"title": "Estación de arranxo de bicicletas con bomba de ar"
},
"2": {
"title": "Estación de arranxo de bicicletas sin bomba de ar"
}
}
},
"bike_shop": {
"name": "Tenda/arranxo de bicicletas",
"title": {
"render": "Tenda/arranxo de bicicletas",
"mappings": {
"3": {
"then": "Arranxo de bicicletas <i>{name}</i>"
},
"4": {
"then": "Tenda de bicicletas <i>{name}</i>"
},
"5": {
"then": "Tenda/arranxo de bicicletas <i>{name}</i>"
}
}
},
"tagRenderings": {
"2": {
"question": "Cal é o nome desta tenda de bicicletas?",
"render": "Esta tenda de bicicletas chámase {name}"
},
"3": {
"question": "Cal é a páxina web de {name}?"
},
"4": {
"question": "Cal é o número de teléfono de {name}?"
},
"5": {
"question": "Cal é o enderezo de correo electrónico de {name}?"
},
"9": {
"question": "Esta tenda vende bicicletas?",
"mappings": {
"0": {
"then": "Esta tenda vende bicicletas"
},
"1": {
"then": "Esta tenda non vende bicicletas"
}
}
},
"10": {
"question": "Esta tenda arranxa bicicletas?",
"mappings": {
"0": {
"then": "Esta tenda arranxa bicicletas"
},
"1": {
"then": "Esta tenda non arranxa bicicletas"
},
"2": {
"then": "Esta tenda só arranxa bicicletas mercadas aquí"
},
"3": {
"then": "Esta tenda só arranxa bicicletas dunha certa marca"
}
}
},
"11": {
"question": "Esta tenda aluga bicicletas?",
"mappings": {
"0": {
"then": "Esta tenda aluga bicicletas"
},
"1": {
"then": "Esta tenda non aluga bicicletas"
}
}
},
"12": {
"question": "Esta tenda vende bicicletas de segunda man?",
"mappings": {
"0": {
"then": "Esta tenda vende bicicletas de segunda man"
},
"1": {
"then": "Esta tenda non vende bicicletas de segunda man"
},
"2": {
"then": "Esta tenda só vende bicicletas de segunda man"
}
}
},
"13": {
"question": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa?",
"mappings": {
"0": {
"then": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa"
},
"1": {
"then": "Esta tenda non ofrece unha bomba de ar para uso de calquera persoa"
}
}
},
"14": {
"question": "Hai ferramentas aquí para arranxar a túa propia bicicleta?",
"mappings": {
"0": {
"then": "Hai ferramentas aquí para arranxar a túa propia bicicleta"
},
"1": {
"then": "Non hai ferramentas aquí para arranxar a túa propia bicicleta"
}
}
}
},
"presets": {
"0": {
"title": "Tenda/arranxo de bicicletas"
}
}
},
"drinking_water": {
"name": "Auga potábel",
"title": {
"render": "Auga potábel"
},
"presets": {
"0": {
"title": "Auga potábel"
}
}
}
}

1732
langs/layers/nl.json Normal file

File diff suppressed because it is too large Load diff

View file

@ -12,230 +12,248 @@ import {Translation} from "../UI/i18n/Translation";
// It spits out an overview of those to be used to load them
interface LayersAndThemes {
themes: any[] , layers: {parsed: any, path: string}[]
themes: any[],
layers: { parsed: any, path: string }[]
}
function loadThemesAndLayers():LayersAndThemes{
const layerFiles = ScriptUtils.readDirRecSync("./assets/layers")
.filter(path => path.indexOf(".json") > 0)
.filter(path => path.indexOf("license_info.json") < 0)
.map(path => {
try {
const parsed = JSON.parse(readFileSync(path, "UTF8"));
return {parsed: parsed, path: path}
} catch (e) {
console.error("Could not parse file ", "./assets/layers/" + path, "due to ", e)
}
})
const themeFiles: any[] = ScriptUtils.readDirRecSync("./assets/themes")
.filter(path => path.endsWith(".json"))
.filter(path => path.indexOf("license_info.json") < 0)
.map(path => {
try{
return JSON.parse(readFileSync(path, "UTF8"));
}catch(e){
console.error("Could not read file ", path, "due to ", e)
throw e
}
});
console.log("Discovered", layerFiles.length, "layers and", themeFiles.length, "themes\n")
return {
layers: layerFiles,
themes: themeFiles
}
}
function writeFiles(lt: LayersAndThemes){
writeFileSync("./assets/generated/known_layers_and_themes.json", JSON.stringify({
"layers": lt.layers.map(l => l.parsed),
"themes": lt.themes
}))
}
function validateLayer(layerJson: LayerConfigJson, path: string, knownPaths: Set<string>, context?: string): string[] {
let errorCount = [];
if (layerJson["overpassTags"] !== undefined) {
errorCount.push("Layer " + layerJson.id + "still uses the old 'overpassTags'-format. Please use \"source\": {\"osmTags\": <tags>}' instead of \"overpassTags\": <tags> (note: this isn't your fault, the custom theme generator still spits out the old format)")
}
try {
const layer = new LayerConfig(layerJson, "test", true)
const images = Array.from(layer.ExtractImages())
const remoteImages = images.filter(img => img.indexOf("http") == 0)
for (const remoteImage of remoteImages) {
errorCount.push("Found a remote image: " + remoteImage + " in layer " + layer.id + ", please download it. You can use the fixTheme script to automate this")
}
const expected: string = `assets/layers/${layer.id}/${layer.id}.json`
if (path != undefined && path.indexOf(expected) < 0) {
errorCount.push("Layer is in an incorrect place. The path is " + path + ", but expected " + expected)
}
for (const image of images) {
if(image.indexOf("{") >= 0){
console.warn("Ignoring image with { in the path: ", image)
continue
}
if (!knownPaths.has(image)) {
const ctx = context === undefined ? "" : ` in a layer defined in the theme ${context}`
errorCount.push(`Image with path ${image} not found or not attributed; it is used in ${layer.id}${ctx}`)
}
}
} catch (e) {
console.error(e)
return [`Layer ${layerJson.id}` ?? JSON.stringify(layerJson).substring(0, 50) + " is invalid: " + e]
}
return errorCount
}
function validateTranslationCompletenessOfObject(object: any, expectedLanguages: string[], context: string) {
const missingTranlations = []
const translations: {tr: Translation, context: string}[] = [];
const queue: {object: any, context: string}[] = [{object: object, context: context}]
while (queue.length > 0) {
const item = queue.pop();
const o = item.object
for (const key in o) {
const v = o[key];
if (v === undefined) {
continue;
}
if (v instanceof Translation || v?.translations !== undefined) {
translations.push({tr: v, context: item.context});
} else if (
["string", "function", "boolean", "number"].indexOf(typeof (v)) < 0) {
queue.push({object: v, context: item.context + "." + key})
}
}
}
const missing = {}
const present = {}
for (const ln of expectedLanguages) {
missing[ln] = 0;
present[ln] = 0;
for (const translation of translations) {
if (translation.tr.translations["*"] !== undefined) {
continue;
}
const txt = translation.tr.translations[ln];
const isMissing = txt === undefined || txt === "" || txt.toLowerCase().indexOf("todo") >= 0;
if (isMissing) {
missingTranlations.push(`${translation.context},${ln},${translation.tr.txt}`)
missing[ln]++
} else {
present[ln]++;
}
}
}
let message = `Translation completeness for ${context}`
let isComplete = true;
for (const ln of expectedLanguages) {
const amiss = missing[ln];
const ok = present[ln];
const total = amiss + ok;
message += ` ${ln}: ${ok}/${total}`
if (ok !== total) {
isComplete = false;
}
}
return missingTranlations
}
function main(args: string[]) {
const lt = loadThemesAndLayers();
const layerFiles = lt.layers;
const themeFiles = lt.themes;
console.log(" ---------- VALIDATING ---------")
const licensePaths = []
for (const i in licenses) {
licensePaths.push(licenses[i].path)
}
const knownPaths = new Set<string>(licensePaths)
let layerErrorCount = []
const knownLayerIds = new Map<string, LayerConfig>();
for (const layerFile of layerFiles) {
layerErrorCount.push(...validateLayer(layerFile.parsed, layerFile.path, knownPaths))
knownLayerIds.set(layerFile.parsed.id, new LayerConfig(layerFile.parsed))
}
let themeErrorCount = []
let missingTranslations = []
for (const themeFile of themeFiles) {
if (typeof themeFile.language === "string") {
themeErrorCount.push("The theme " + themeFile.id + " has a string as language. Please use a list of strings")
}
for (const layer of themeFile.layers) {
if (typeof layer === "string") {
if (!knownLayerIds.has(layer)) {
themeErrorCount.push(`Unknown layer id: ${layer} in theme ${themeFile.id}`)
} else {
const layerConfig = knownLayerIds.get(layer);
missingTranslations.push(...validateTranslationCompletenessOfObject(layerConfig, themeFile.language, "Layer " + layer))
export default class LayerOverviewUtils {
getLayerFiles(): {parsed: LayerConfigJson, path: string}[] {
return ScriptUtils.readDirRecSync("./assets/layers")
.filter(path => path.indexOf(".json") > 0)
.filter(path => path.indexOf("license_info.json") < 0)
.map(path => {
try {
const parsed = JSON.parse(readFileSync(path, "UTF8"));
return {parsed: parsed, path: path}
} catch (e) {
console.error("Could not parse file ", "./assets/layers/" + path, "due to ", e)
}
} else {
if (layer.builtin !== undefined) {
if (!knownLayerIds.has(layer.builtin)) {
themeErrorCount.push("Unknown layer id: " + layer.builtin + "(which uses inheritance)")
})
}
getThemeFiles() {
return ScriptUtils.readDirRecSync("./assets/themes")
.filter(path => path.endsWith(".json"))
.filter(path => path.indexOf("license_info.json") < 0)
.map(path => {
try {
return JSON.parse(readFileSync(path, "UTF8"));
} catch (e) {
console.error("Could not read file ", path, "due to ", e)
throw e
}
});
}
loadThemesAndLayers(): LayersAndThemes {
const layerFiles = this.getLayerFiles();
const themeFiles: any[] = this.getThemeFiles();
console.log("Discovered", layerFiles.length, "layers and", themeFiles.length, "themes\n")
return {
layers: layerFiles,
themes: themeFiles
}
}
writeFiles(lt: LayersAndThemes) {
writeFileSync("./assets/generated/known_layers_and_themes.json", JSON.stringify({
"layers": lt.layers.map(l => l.parsed),
"themes": lt.themes
}))
}
validateLayer(layerJson: LayerConfigJson, path: string, knownPaths: Set<string>, context?: string): string[] {
let errorCount = [];
if (layerJson["overpassTags"] !== undefined) {
errorCount.push("Layer " + layerJson.id + "still uses the old 'overpassTags'-format. Please use \"source\": {\"osmTags\": <tags>}' instead of \"overpassTags\": <tags> (note: this isn't your fault, the custom theme generator still spits out the old format)")
}
try {
const layer = new LayerConfig(layerJson, "test", true)
const images = Array.from(layer.ExtractImages())
const remoteImages = images.filter(img => img.indexOf("http") == 0)
for (const remoteImage of remoteImages) {
errorCount.push("Found a remote image: " + remoteImage + " in layer " + layer.id + ", please download it. You can use the fixTheme script to automate this")
}
const expected: string = `assets/layers/${layer.id}/${layer.id}.json`
if (path != undefined && path.indexOf(expected) < 0) {
errorCount.push("Layer is in an incorrect place. The path is " + path + ", but expected " + expected)
}
for (const image of images) {
if (image.indexOf("{") >= 0) {
console.warn("Ignoring image with { in the path: ", image)
continue
}
if (!knownPaths.has(image)) {
const ctx = context === undefined ? "" : ` in a layer defined in the theme ${context}`
errorCount.push(`Image with path ${image} not found or not attributed; it is used in ${layer.id}${ctx}`)
}
}
} catch (e) {
console.error(e)
return [`Layer ${layerJson.id}` ?? JSON.stringify(layerJson).substring(0, 50) + " is invalid: " + e]
}
return errorCount
}
validateTranslationCompletenessOfObject(object: any, expectedLanguages: string[], context: string) {
const missingTranlations = []
const translations: { tr: Translation, context: string }[] = [];
const queue: { object: any, context: string }[] = [{object: object, context: context}]
while (queue.length > 0) {
const item = queue.pop();
const o = item.object
for (const key in o) {
const v = o[key];
if (v === undefined) {
continue;
}
if (v instanceof Translation || v?.translations !== undefined) {
translations.push({tr: v, context: item.context});
} else if (
["string", "function", "boolean", "number"].indexOf(typeof (v)) < 0) {
queue.push({object: v, context: item.context + "." + key})
}
}
}
const missing = {}
const present = {}
for (const ln of expectedLanguages) {
missing[ln] = 0;
present[ln] = 0;
for (const translation of translations) {
if (translation.tr.translations["*"] !== undefined) {
continue;
}
const txt = translation.tr.translations[ln];
const isMissing = txt === undefined || txt === "" || txt.toLowerCase().indexOf("todo") >= 0;
if (isMissing) {
missingTranlations.push(`${translation.context},${ln},${translation.tr.txt}`)
missing[ln]++
} else {
present[ln]++;
}
}
}
let message = `Translation completeness for ${context}`
let isComplete = true;
for (const ln of expectedLanguages) {
const amiss = missing[ln];
const ok = present[ln];
const total = amiss + ok;
message += ` ${ln}: ${ok}/${total}`
if (ok !== total) {
isComplete = false;
}
}
return missingTranlations
}
main(args: string[]) {
const lt = this.loadThemesAndLayers();
const layerFiles = lt.layers;
const themeFiles = lt.themes;
console.log(" ---------- VALIDATING ---------")
const licensePaths = []
for (const i in licenses) {
licensePaths.push(licenses[i].path)
}
const knownPaths = new Set<string>(licensePaths)
let layerErrorCount = []
const knownLayerIds = new Map<string, LayerConfig>();
for (const layerFile of layerFiles) {
layerErrorCount.push(...this.validateLayer(layerFile.parsed, layerFile.path, knownPaths))
knownLayerIds.set(layerFile.parsed.id, new LayerConfig(layerFile.parsed))
}
let themeErrorCount = []
let missingTranslations = []
for (const themeFile of themeFiles) {
if (typeof themeFile.language === "string") {
themeErrorCount.push("The theme " + themeFile.id + " has a string as language. Please use a list of strings")
}
for (const layer of themeFile.layers) {
if (typeof layer === "string") {
if (!knownLayerIds.has(layer)) {
themeErrorCount.push(`Unknown layer id: ${layer} in theme ${themeFile.id}`)
} else {
const layerConfig = knownLayerIds.get(layer);
missingTranslations.push(...this.validateTranslationCompletenessOfObject(layerConfig, themeFile.language, "Layer " + layer))
}
} else {
// layer.builtin contains layer overrides - we can skip those
layerErrorCount.push(...validateLayer(layer, undefined, knownPaths, themeFile.id))
if (layer.builtin !== undefined) {
if (!knownLayerIds.has(layer.builtin)) {
themeErrorCount.push("Unknown layer id: " + layer.builtin + "(which uses inheritance)")
}
} else {
// layer.builtin contains layer overrides - we can skip those
layerErrorCount.push(...this.validateLayer(layer, undefined, knownPaths, themeFile.id))
}
}
}
}
themeFile.layers = themeFile.layers
.filter(l => typeof l != "string") // We remove all the builtin layer references as they don't work with ts-node for some weird reason
.filter(l => l.builtin === undefined)
themeFile.layers = themeFile.layers
.filter(l => typeof l != "string") // We remove all the builtin layer references as they don't work with ts-node for some weird reason
.filter(l => l.builtin === undefined)
missingTranslations.push(...validateTranslationCompletenessOfObject(themeFile, themeFile.language, "Theme " + themeFile.id))
missingTranslations.push(...this.validateTranslationCompletenessOfObject(themeFile, themeFile.language, "Theme " + themeFile.id))
try {
const theme = new LayoutConfig(themeFile, true, "test")
if (theme.id !== theme.id.toLowerCase()) {
themeErrorCount.push("Theme ids should be in lowercase, but it is " + theme.id)
try {
const theme = new LayoutConfig(themeFile, true, "test")
if (theme.id !== theme.id.toLowerCase()) {
themeErrorCount.push("Theme ids should be in lowercase, but it is " + theme.id)
}
} catch (e) {
themeErrorCount.push("Could not parse theme " + themeFile["id"] + "due to", e)
}
} catch (e) {
themeErrorCount.push("Could not parse theme " + themeFile["id"] + "due to", e)
}
}
if(missingTranslations.length > 0){
console.log(missingTranslations.length, "missing translations")
writeFileSync("missing_translations.txt", missingTranslations.join("\n"))
}
if (layerErrorCount.length + themeErrorCount.length == 0) {
console.log("All good!")
// We load again from disc, as modifications were made above
const lt = loadThemesAndLayers();
writeFiles(lt);
} else {
const errors = layerErrorCount.concat(themeErrorCount).join("\n")
console.log(errors)
const msg = (`Found ${layerErrorCount.length} errors in the layers; ${themeErrorCount.length} errors in the themes`)
console.log(msg)
if (process.argv.indexOf("--report") >= 0) {
console.log("Writing report!")
writeFileSync("layer_report.txt", errors)
}
if (process.argv.indexOf("--no-fail") < 0) {
throw msg;
if (missingTranslations.length > 0) {
console.log(missingTranslations.length, "missing translations")
writeFileSync("missing_translations.txt", missingTranslations.join("\n"))
}
if (layerErrorCount.length + themeErrorCount.length == 0) {
console.log("All good!")
// We load again from disc, as modifications were made above
const lt = this.loadThemesAndLayers();
this.writeFiles(lt);
} else {
const errors = layerErrorCount.concat(themeErrorCount).join("\n")
console.log(errors)
const msg = (`Found ${layerErrorCount.length} errors in the layers; ${themeErrorCount.length} errors in the themes`)
console.log(msg)
if (process.argv.indexOf("--report") >= 0) {
console.log("Writing report!")
writeFileSync("layer_report.txt", errors)
}
if (process.argv.indexOf("--no-fail") < 0) {
throw msg;
}
}
}
}
main(process.argv)
new LayerOverviewUtils().main(process.argv)

View file

@ -2,40 +2,130 @@ import * as fs from "fs";
import {Utils} from "../Utils";
import ScriptUtils from "./ScriptUtils";
import {readFileSync, writeFileSync} from "fs";
import LayerConfig from "../Customizations/JSON/LayerConfig";
import {LayerConfigJson} from "../Customizations/JSON/LayerConfigJson";
import * as bookcases from "../assets/layers/public_bookcase/public_bookcase.json"
import LayerOverviewUtils from "./generateLayerOverview";
const knownLanguages = ["en", "nl", "de", "fr", "es", "gl", "ca"];
class TranslationPart {
contents: Map<string, TranslationPart | string> = new Map<string, TranslationPart | string>()
add(language: string, obj: any){
add(language: string, obj: any) {
for (const key in obj) {
const v = obj[key]
if(!this.contents.has(key)){
if (!this.contents.has(key)) {
this.contents.set(key, new TranslationPart())
}
const subpart = this.contents.get(key) as TranslationPart
if(typeof v === "string"){
if (typeof v === "string") {
subpart.contents.set(language, v)
}else{
} else {
subpart.add(language, v)
}
}
}
toJson(): string{
const parts = []
for (let key of Array.from(this.contents.keys()) ){
const value = this.contents.get(key);
addTranslationObject(translations: any, context?: string) {
for (const translationsKey in translations) {
if (!translations.hasOwnProperty(translationsKey)) {
continue;
}
const v = translations[translationsKey]
if (typeof (v) != "string") {
console.error("Non-string object in translation: ", translations[translationsKey])
throw "Error in an object depicting a translation: a non-string object was found. (" + context + ")\n You probably put some other section accidentally in the translation"
}
this.contents.set(translationsKey, v)
}
}
if(typeof value === "string"){
parts.push(`\"${key}\": \"${value}\"`)
}else{
parts.push(`\"${key}\": ${(value as TranslationPart).toJson()}`);
isLeaf() {
for (let key of Array.from(this.contents.keys())) {
const value = this.contents.get(key);
if (typeof value !== "string") {
return false;
}
}
return JSON.stringify(JSON.parse(`{${parts.join(",")}}`), null, " ");
return true;
}
recursiveAdd(object: any) {
const isProbablyTranslationObject = knownLanguages.map(l => object.hasOwnProperty(l)).filter(x => x).length > 0;
if (isProbablyTranslationObject) {
this.addTranslationObject(object)
return;
}
for (const key in object) {
if (!object.hasOwnProperty(key)) {
continue;
}
const v = object[key]
if (v == null) {
console.warn("Got a null value for key ", key)
continue
}
if (typeof v !== "object") {
continue;
}
if (!this.contents.get(key)) {
this.contents.set(key, new TranslationPart())
}
(this.contents.get(key) as TranslationPart).recursiveAdd(v);
}
}
knownLanguages(): string[] {
const languages = []
for (let key of Array.from(this.contents.keys())) {
const value = this.contents.get(key);
if (typeof value === "string") {
languages.push(key)
} else {
languages.push(...(value as TranslationPart).knownLanguages())
}
}
return Utils.Dedup(languages);
}
toJson(neededLanguage?: string): string {
const parts = []
for (let key of Array.from(this.contents.keys())) {
let value = this.contents.get(key);
if (typeof value === "string") {
value = value.replace(/"/g, "\\\"")
if(neededLanguage === undefined){
parts.push(`\"${key}\": \"${value}\"`)
}else if (key === neededLanguage){
return `"${value}"`
}
} else {
const sub = (value as TranslationPart).toJson(neededLanguage)
if (sub !== "") {
parts.push(`\"${key}\": ${sub}`);
}
}
}
if (parts.length === 0) {
return "";
}
return `{${parts.join(",")}}`;
}
}
@ -57,11 +147,11 @@ function transformTranslation(obj: any, depth = 1) {
let values = ""
for (const key in obj) {
if(key === "#"){
if (key === "#") {
continue;
}
if(key.match("^[a-zA-Z0-9_]*$") === null){
throw "Invalid character in key: "+key
if (key.match("^[a-zA-Z0-9_]*$") === null) {
throw "Invalid character in key: " + key
}
values += (Utils.Times((_) => " ", depth)) + key + ": " + transformTranslation(obj[key], depth + 1) + ",\n"
}
@ -83,7 +173,7 @@ function genTranslations() {
}
// Read 'lang/*.json', writes to 'assets/generated/translations.json'
function compileTranslationsFromWeblate(){
function compileTranslationsFromWeblate() {
const translations = ScriptUtils.readDirRecSync("./langs")
.filter(path => path.indexOf(".json") > 0)
@ -92,13 +182,48 @@ function compileTranslationsFromWeblate(){
for (const translationFile of translations) {
const contents = JSON.parse(readFileSync(translationFile, "utf-8"));
let language = translationFile.substring(translationFile.lastIndexOf("/") + 1)
language = language.substring(0, language.length-5)
language = language.substring(0, language.length - 5)
allTranslations.add(language, contents)
}
writeFileSync("./assets/generated/translations.json", allTranslations.toJson())
writeFileSync("./assets/generated/translations.json", JSON.stringify(JSON.parse(allTranslations.toJson()), null, " "))
}
function generateTranslationFromLayerConfig(layerConfig: LayerConfigJson): TranslationPart {
const tr = new TranslationPart();
tr.recursiveAdd(layerConfig)
return tr;
}
function generateLayerTranslationsObject() {
const layerFiles = new LayerOverviewUtils().getLayerFiles();
const tr = new TranslationPart();
for (const layerFile of layerFiles) {
const config: LayerConfigJson = layerFile.parsed;
const layerTr = generateTranslationFromLayerConfig(config)
tr.contents.set(config.id, layerTr)
}
const langs = tr.knownLanguages();
for (const lang of langs) {
console.log("Exporting ", lang)
let json = tr.toJson(lang)
try{
json = JSON.stringify(JSON.parse(json), null, " ");
}catch (e) {
console.error(e)
}
writeFileSync("langs/layers/" + lang + ".json", json)
}
}
generateLayerTranslationsObject()
compileTranslationsFromWeblate();
genTranslations()