all: imp translations script

This commit is contained in:
Eugene Burkov
2025-11-10 18:03:23 +03:00
parent c930dcff36
commit c2e1b8edee
40 changed files with 1592 additions and 591 deletions

View File

@@ -43,5 +43,50 @@
"zh-hk": "繁體中文(香港)",
"zh-tw": "正體中文(台灣)"
}
},
{
"project_id": "hostlists-registry",
"base_locale": "en",
"localizable_files": [
"client/src/__locales-services/services.json"
],
"languages": {
"ar": "العربية",
"be": "Беларуская",
"bg": "Български",
"cs": "Český",
"da": "Dansk",
"de": "Deutsch",
"en": "English",
"es": "Español",
"fa": "فارسی",
"fi": "Suomi",
"fr": "Français",
"hr": "Hrvatski",
"hu": "Magyar",
"id": "Indonesian",
"it": "Italiano",
"ja": "日本語",
"ko": "한국어",
"nl": "Nederlands",
"no": "Norsk",
"pl": "Polski",
"pt-br": "Português (BR)",
"pt-pt": "Português (PT)",
"ro": "Română",
"ru": "Русский",
"si-lk": "සිංහල",
"sk": "Slovenčina",
"sl": "Slovenščina",
"sr-cs": "Srpski",
"sv": "Svenska",
"th": "ภาษาไทย",
"tr": "Türkçe",
"uk": "Українська",
"vi": "Tiếng Việt",
"zh-cn": "简体中文",
"zh-hk": "繁體中文(香港)",
"zh-tw": "正體中文(台灣)"
}
}
]

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "الذكاء الاصطناعي",
"servicesgroup.cdn.name": "شبكات توصيل المحتوى (CDN)",
"servicesgroup.dating.name": "خدمات المواعدة",
"servicesgroup.gambling.name": "القمار والمراهنة",
"servicesgroup.gaming.name": "الألعاب الرقمية",
"servicesgroup.hosting.name": "استضافة الويب",
"servicesgroup.messenger.name": "خدمات المراسلة",
"servicesgroup.privacy.name": "أدوات الخصوصية",
"servicesgroup.shopping.name": "التسوق",
"servicesgroup.social_network.name": "شبكات التواصل الإجتماعية",
"servicesgroup.software.name": "تطوير البرمجيات",
"servicesgroup.streaming.name": "خدمات البث المباشر"
}
"servicesgroup.ai.name": {
"message": "الذكاء الاصطناعي"
},
"servicesgroup.cdn.name": {
"message": "شبكات توصيل المحتوى (CDN)"
},
"servicesgroup.dating.name": {
"message": "خدمات المواعدة"
},
"servicesgroup.gambling.name": {
"message": "القمار والمراهنة"
},
"servicesgroup.gaming.name": {
"message": "الألعاب الرقمية"
},
"servicesgroup.hosting.name": {
"message": "استضافة الويب"
},
"servicesgroup.messenger.name": {
"message": "خدمات المراسلة"
},
"servicesgroup.privacy.name": {
"message": "أدوات الخصوصية"
},
"servicesgroup.shopping.name": {
"message": "التسوق"
},
"servicesgroup.social_network.name": {
"message": "شبكات التواصل الإجتماعية"
},
"servicesgroup.software.name": {
"message": "تطوير البرمجيات"
},
"servicesgroup.streaming.name": {
"message": "خدمات البث المباشر"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Штучны інтэлект",
"servicesgroup.cdn.name": "Сеткі дастаўкі кантэнту (CDN)",
"servicesgroup.dating.name": "Сэрвісы знаёмстваў",
"servicesgroup.gambling.name": "Азартныя гульні і стаўкі",
"servicesgroup.gaming.name": "Гэймінг",
"servicesgroup.hosting.name": "Вэб-хостынг",
"servicesgroup.messenger.name": "Сэрвісы паведамленняў",
"servicesgroup.privacy.name": "Інструменты прыватнасці",
"servicesgroup.shopping.name": "Крамы",
"servicesgroup.social_network.name": "Сацыяльныя сеткі",
"servicesgroup.software.name": "Распрацоўка праграмнага забеспячэння",
"servicesgroup.streaming.name": "Стрымінгавыя сэрвісы"
}
"servicesgroup.ai.name": {
"message": "Штучны інтэлект"
},
"servicesgroup.cdn.name": {
"message": "Сеткі дастаўкі кантэнту (CDN)"
},
"servicesgroup.dating.name": {
"message": "Сэрвісы знаёмстваў"
},
"servicesgroup.gambling.name": {
"message": "Азартныя гульні і стаўкі"
},
"servicesgroup.gaming.name": {
"message": "Гэймінг"
},
"servicesgroup.hosting.name": {
"message": "Вэб-хостынг"
},
"servicesgroup.messenger.name": {
"message": "Сэрвісы паведамленняў"
},
"servicesgroup.privacy.name": {
"message": "Інструменты прыватнасці"
},
"servicesgroup.shopping.name": {
"message": "Крамы"
},
"servicesgroup.social_network.name": {
"message": "Сацыяльныя сеткі"
},
"servicesgroup.software.name": {
"message": "Распрацоўка праграмнага забеспячэння"
},
"servicesgroup.streaming.name": {
"message": "Стрымінгавыя сэрвісы"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Изкуствен интелект",
"servicesgroup.cdn.name": "Мрежи за доставяне на съдържание (CDN)",
"servicesgroup.dating.name": "Служби за запознанства",
"servicesgroup.gambling.name": "Хазарт и залагания",
"servicesgroup.gaming.name": "Гейминг",
"servicesgroup.hosting.name": "Уеб хостинг",
"servicesgroup.messenger.name": "Услуги за съобщения",
"servicesgroup.privacy.name": "Инструменти за поверителност",
"servicesgroup.shopping.name": "Пазаруване",
"servicesgroup.social_network.name": "Социални мрежи",
"servicesgroup.software.name": "Разработка на софтуер",
"servicesgroup.streaming.name": "Стрийминг услуги"
}
"servicesgroup.ai.name": {
"message": "Изкуствен интелект"
},
"servicesgroup.cdn.name": {
"message": "Мрежи за доставяне на съдържание (CDN)"
},
"servicesgroup.dating.name": {
"message": "Служби за запознанства"
},
"servicesgroup.gambling.name": {
"message": "Хазарт и залагания"
},
"servicesgroup.gaming.name": {
"message": "Гейминг"
},
"servicesgroup.hosting.name": {
"message": "Уеб хостинг"
},
"servicesgroup.messenger.name": {
"message": "Услуги за съобщения"
},
"servicesgroup.privacy.name": {
"message": "Инструменти за поверителност"
},
"servicesgroup.shopping.name": {
"message": "Пазаруване"
},
"servicesgroup.social_network.name": {
"message": "Социални мрежи"
},
"servicesgroup.software.name": {
"message": "Разработка на софтуер"
},
"servicesgroup.streaming.name": {
"message": "Стрийминг услуги"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Umělá inteligence",
"servicesgroup.cdn.name": "Sítě pro doručování obsahu (CDN)",
"servicesgroup.dating.name": "Seznamovací služby",
"servicesgroup.gambling.name": "Hazardní hry a sázení",
"servicesgroup.gaming.name": "Hraní",
"servicesgroup.hosting.name": "Webhosting",
"servicesgroup.messenger.name": "Služby pro zasílání zpráv",
"servicesgroup.privacy.name": "Nástroje pro ochranu soukromí",
"servicesgroup.shopping.name": "Nakupování",
"servicesgroup.social_network.name": "Sociální sítě",
"servicesgroup.software.name": "Vývoj softwaru",
"servicesgroup.streaming.name": "Streamovací služby"
}
"servicesgroup.ai.name": {
"message": "Umělá inteligence"
},
"servicesgroup.cdn.name": {
"message": "Sítě pro doručování obsahu (CDN)"
},
"servicesgroup.dating.name": {
"message": "Seznamovací služby"
},
"servicesgroup.gambling.name": {
"message": "Hazardní hry a sázení"
},
"servicesgroup.gaming.name": {
"message": "Hraní"
},
"servicesgroup.hosting.name": {
"message": "Webhosting"
},
"servicesgroup.messenger.name": {
"message": "Služby pro zasílání zpráv"
},
"servicesgroup.privacy.name": {
"message": "Nástroje pro ochranu soukromí"
},
"servicesgroup.shopping.name": {
"message": "Nakupování"
},
"servicesgroup.social_network.name": {
"message": "Sociální sítě"
},
"servicesgroup.software.name": {
"message": "Vývoj softwaru"
},
"servicesgroup.streaming.name": {
"message": "Streamovací služby"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Kunstig intelligens",
"servicesgroup.cdn.name": "Indholdsleveringsnetværk (CDN)",
"servicesgroup.dating.name": "Dating-tjenester",
"servicesgroup.gambling.name": "Spil og væddemål",
"servicesgroup.gaming.name": "Gaming",
"servicesgroup.hosting.name": "Webhosting",
"servicesgroup.messenger.name": "Beskedtjenester",
"servicesgroup.privacy.name": "Fortrolighedsværktøjer",
"servicesgroup.shopping.name": "Shopping",
"servicesgroup.social_network.name": "Sociale netværk",
"servicesgroup.software.name": "Softwareudvikling",
"servicesgroup.streaming.name": "Streamingtjenester"
}
"servicesgroup.ai.name": {
"message": "Kunstig intelligens"
},
"servicesgroup.cdn.name": {
"message": "Indholdsleveringsnetværk (CDN)"
},
"servicesgroup.dating.name": {
"message": "Dating-tjenester"
},
"servicesgroup.gambling.name": {
"message": "Spil og væddemål"
},
"servicesgroup.gaming.name": {
"message": "Gaming"
},
"servicesgroup.hosting.name": {
"message": "Webhosting"
},
"servicesgroup.messenger.name": {
"message": "Beskedtjenester"
},
"servicesgroup.privacy.name": {
"message": "Fortrolighedsværktøjer"
},
"servicesgroup.shopping.name": {
"message": "Shopping"
},
"servicesgroup.social_network.name": {
"message": "Sociale netværk"
},
"servicesgroup.software.name": {
"message": "Softwareudvikling"
},
"servicesgroup.streaming.name": {
"message": "Streamingtjenester"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Künstliche Intelligenz",
"servicesgroup.cdn.name": "Content-Delivery-Netzwerke (CDN)",
"servicesgroup.dating.name": "Dating-Dienste",
"servicesgroup.gambling.name": "Glücksspiel und Wetten",
"servicesgroup.gaming.name": "Spiele",
"servicesgroup.hosting.name": "Webhosting",
"servicesgroup.messenger.name": "Messaging-Dienste",
"servicesgroup.privacy.name": "Datenschutz-Tools",
"servicesgroup.shopping.name": "Einkaufen",
"servicesgroup.social_network.name": "Soziale Netzwerke",
"servicesgroup.software.name": "Softwareentwicklung",
"servicesgroup.streaming.name": "Streaming-Dienste"
}
"servicesgroup.ai.name": {
"message": "Künstliche Intelligenz"
},
"servicesgroup.cdn.name": {
"message": "Content-Delivery-Netzwerke (CDN)"
},
"servicesgroup.dating.name": {
"message": "Dating-Dienste"
},
"servicesgroup.gambling.name": {
"message": "Glücksspiel und Wetten"
},
"servicesgroup.gaming.name": {
"message": "Spiele"
},
"servicesgroup.hosting.name": {
"message": "Webhosting"
},
"servicesgroup.messenger.name": {
"message": "Messaging-Dienste"
},
"servicesgroup.privacy.name": {
"message": "Datenschutz-Tools"
},
"servicesgroup.shopping.name": {
"message": "Einkaufen"
},
"servicesgroup.social_network.name": {
"message": "Soziale Netzwerke"
},
"servicesgroup.software.name": {
"message": "Softwareentwicklung"
},
"servicesgroup.streaming.name": {
"message": "Streaming-Dienste"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Artificial intelligence",
"servicesgroup.cdn.name": "Content delivery networks (CDN)",
"servicesgroup.dating.name": "Dating services",
"servicesgroup.gambling.name": "Gambling and betting",
"servicesgroup.gaming.name": "Gaming",
"servicesgroup.hosting.name": "Web hosting",
"servicesgroup.messenger.name": "Messaging services",
"servicesgroup.privacy.name": "Privacy tools",
"servicesgroup.shopping.name": "Shopping",
"servicesgroup.social_network.name": "Social networks",
"servicesgroup.software.name": "Software development",
"servicesgroup.streaming.name": "Streaming services"
}
"servicesgroup.ai.name": {
"message": "Artificial intelligence"
},
"servicesgroup.cdn.name": {
"message": "Content delivery networks (CDN)"
},
"servicesgroup.dating.name": {
"message": "Dating services"
},
"servicesgroup.gambling.name": {
"message": "Gambling and betting"
},
"servicesgroup.gaming.name": {
"message": "Gaming"
},
"servicesgroup.hosting.name": {
"message": "Web hosting"
},
"servicesgroup.messenger.name": {
"message": "Messaging services"
},
"servicesgroup.privacy.name": {
"message": "Privacy tools"
},
"servicesgroup.shopping.name": {
"message": "Shopping"
},
"servicesgroup.social_network.name": {
"message": "Social networks"
},
"servicesgroup.software.name": {
"message": "Software development"
},
"servicesgroup.streaming.name": {
"message": "Streaming services"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Inteligencia artificial",
"servicesgroup.cdn.name": "Redes de entrega de contenido (CDN)",
"servicesgroup.dating.name": "Servicios de citas",
"servicesgroup.gambling.name": "Juegos de azar y apuestas",
"servicesgroup.gaming.name": "Juegos",
"servicesgroup.hosting.name": "Web hosting",
"servicesgroup.messenger.name": "Servicios de mensajería",
"servicesgroup.privacy.name": "Herramientas de privacidad",
"servicesgroup.shopping.name": "Compras",
"servicesgroup.social_network.name": "Redes sociales",
"servicesgroup.software.name": "Desarrollo de software",
"servicesgroup.streaming.name": "Servicios de streaming"
}
"servicesgroup.ai.name": {
"message": "Inteligencia artificial"
},
"servicesgroup.cdn.name": {
"message": "Redes de entrega de contenido (CDN)"
},
"servicesgroup.dating.name": {
"message": "Servicios de citas"
},
"servicesgroup.gambling.name": {
"message": "Juegos de azar y apuestas"
},
"servicesgroup.gaming.name": {
"message": "Juegos"
},
"servicesgroup.hosting.name": {
"message": "Web hosting"
},
"servicesgroup.messenger.name": {
"message": "Servicios de mensajería"
},
"servicesgroup.privacy.name": {
"message": "Herramientas de privacidad"
},
"servicesgroup.shopping.name": {
"message": "Compras"
},
"servicesgroup.social_network.name": {
"message": "Redes sociales"
},
"servicesgroup.software.name": {
"message": "Desarrollo de software"
},
"servicesgroup.streaming.name": {
"message": "Servicios de streaming"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "هوش مصنوعی",
"servicesgroup.cdn.name": "شبکه‌های تحویل محتوا (CDN)",
"servicesgroup.dating.name": "خدمات دوستیابی",
"servicesgroup.gambling.name": "قمار و شرط‌بندی",
"servicesgroup.gaming.name": "بازی",
"servicesgroup.hosting.name": "میزبانی وب",
"servicesgroup.messenger.name": "خدمات پیام رسان",
"servicesgroup.privacy.name": "ابزارهای حریم خصوصی",
"servicesgroup.shopping.name": "خرید",
"servicesgroup.social_network.name": "شبکه اجتماعی",
"servicesgroup.software.name": "توسعه نرمافزار",
"servicesgroup.streaming.name": "خدمات استریم"
}
"servicesgroup.ai.name": {
"message": "هوش مصنوعی"
},
"servicesgroup.cdn.name": {
"message": "شبکه‌های تحویل محتوا (CDN)"
},
"servicesgroup.dating.name": {
"message": "خدمات دوستیابی"
},
"servicesgroup.gambling.name": {
"message": "قمار و شرط‌بندی"
},
"servicesgroup.gaming.name": {
"message": "بازی"
},
"servicesgroup.hosting.name": {
"message": "میزبانی وب"
},
"servicesgroup.messenger.name": {
"message": "خدمات پیام رسان"
},
"servicesgroup.privacy.name": {
"message": "ابزارهای حریم خصوصی"
},
"servicesgroup.shopping.name": {
"message": "خرید"
},
"servicesgroup.social_network.name": {
"message": "شبکه اجتماعی"
},
"servicesgroup.software.name": {
"message": "توسعه نرمافزار"
},
"servicesgroup.streaming.name": {
"message": "خدمات استریم"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Tekoäly",
"servicesgroup.cdn.name": "Sisällönjakeluverkot (CDN)",
"servicesgroup.dating.name": "Deittipalvelut",
"servicesgroup.gambling.name": "Uhkapelit ja vedonlyönti",
"servicesgroup.gaming.name": "Pelaaminen",
"servicesgroup.hosting.name": "Web-hosting",
"servicesgroup.messenger.name": "Viestipalvelut",
"servicesgroup.privacy.name": "Yksityisyyden työkalut",
"servicesgroup.shopping.name": "Verkkokaupat",
"servicesgroup.social_network.name": "Sosiaaliset verkostot",
"servicesgroup.software.name": "Ohjelmistokehitys",
"servicesgroup.streaming.name": "Suoratoistopalvelut"
}
"servicesgroup.ai.name": {
"message": "Tekoäly"
},
"servicesgroup.cdn.name": {
"message": "Sisällönjakeluverkot (CDN)"
},
"servicesgroup.dating.name": {
"message": "Deittipalvelut"
},
"servicesgroup.gambling.name": {
"message": "Uhkapelit ja vedonlyönti"
},
"servicesgroup.gaming.name": {
"message": "Pelaaminen"
},
"servicesgroup.hosting.name": {
"message": "Web-hosting"
},
"servicesgroup.messenger.name": {
"message": "Viestipalvelut"
},
"servicesgroup.privacy.name": {
"message": "Yksityisyyden työkalut"
},
"servicesgroup.shopping.name": {
"message": "Verkkokaupat"
},
"servicesgroup.social_network.name": {
"message": "Sosiaaliset verkostot"
},
"servicesgroup.software.name": {
"message": "Ohjelmistokehitys"
},
"servicesgroup.streaming.name": {
"message": "Suoratoistopalvelut"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Intelligence artificielle",
"servicesgroup.cdn.name": "Réseaux de distribution de contenu (CDN)",
"servicesgroup.dating.name": "Services de rencontres",
"servicesgroup.gambling.name": "Jeux de hasard et paris sportifs",
"servicesgroup.gaming.name": "Jeux vidéo",
"servicesgroup.hosting.name": "Hébergement Web",
"servicesgroup.messenger.name": "Services de messagerie",
"servicesgroup.privacy.name": "Outils de confidentialité",
"servicesgroup.shopping.name": "Shopping",
"servicesgroup.social_network.name": "Réseaux sociaux",
"servicesgroup.software.name": "Développement de logiciels",
"servicesgroup.streaming.name": "Services de streaming"
}
"servicesgroup.ai.name": {
"message": "Intelligence artificielle"
},
"servicesgroup.cdn.name": {
"message": "Réseaux de distribution de contenu (CDN)"
},
"servicesgroup.dating.name": {
"message": "Services de rencontres"
},
"servicesgroup.gambling.name": {
"message": "Jeux de hasard et paris sportifs"
},
"servicesgroup.gaming.name": {
"message": "Jeux vidéo"
},
"servicesgroup.hosting.name": {
"message": "Hébergement Web"
},
"servicesgroup.messenger.name": {
"message": "Services de messagerie"
},
"servicesgroup.privacy.name": {
"message": "Outils de confidentialité"
},
"servicesgroup.shopping.name": {
"message": "Shopping"
},
"servicesgroup.social_network.name": {
"message": "Réseaux sociaux"
},
"servicesgroup.software.name": {
"message": "Développement de logiciels"
},
"servicesgroup.streaming.name": {
"message": "Services de streaming"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Umjetna inteligencija",
"servicesgroup.cdn.name": "Mreže za isporuku sadržaja (CDN)",
"servicesgroup.dating.name": "Usluge za upoznavanje",
"servicesgroup.gambling.name": "Kockanje i klađenje",
"servicesgroup.gaming.name": "Igre",
"servicesgroup.hosting.name": "Web hosting",
"servicesgroup.messenger.name": "Usluge razmjene poruka",
"servicesgroup.privacy.name": "Alati za privatnost",
"servicesgroup.shopping.name": "Kupovina",
"servicesgroup.social_network.name": "Društvene mreže",
"servicesgroup.software.name": "Razvoj softwarea",
"servicesgroup.streaming.name": "Usluge streaminga"
}
"servicesgroup.ai.name": {
"message": "Umjetna inteligencija"
},
"servicesgroup.cdn.name": {
"message": "Mreže za isporuku sadržaja (CDN)"
},
"servicesgroup.dating.name": {
"message": "Usluge za upoznavanje"
},
"servicesgroup.gambling.name": {
"message": "Kockanje i klađenje"
},
"servicesgroup.gaming.name": {
"message": "Igre"
},
"servicesgroup.hosting.name": {
"message": "Web hosting"
},
"servicesgroup.messenger.name": {
"message": "Usluge razmjene poruka"
},
"servicesgroup.privacy.name": {
"message": "Alati za privatnost"
},
"servicesgroup.shopping.name": {
"message": "Kupovina"
},
"servicesgroup.social_network.name": {
"message": "Društvene mreže"
},
"servicesgroup.software.name": {
"message": "Razvoj softwarea"
},
"servicesgroup.streaming.name": {
"message": "Usluge streaminga"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Mesterséges intelligencia",
"servicesgroup.cdn.name": "Tartalomszolgáltató hálózatok (CDN)",
"servicesgroup.dating.name": "Társkereső szolgáltatások",
"servicesgroup.gambling.name": "Szerencsejáték és fogadás",
"servicesgroup.gaming.name": "Játék",
"servicesgroup.hosting.name": "Webtárhely",
"servicesgroup.messenger.name": "Üzenetküldő szolgáltatások",
"servicesgroup.privacy.name": "Adatvédelmi eszközök",
"servicesgroup.shopping.name": "Vásárlás",
"servicesgroup.social_network.name": "Közösségi háló",
"servicesgroup.software.name": "Szoftverfejlesztés",
"servicesgroup.streaming.name": "Streaming szolgáltatások"
}
"servicesgroup.ai.name": {
"message": "Mesterséges intelligencia"
},
"servicesgroup.cdn.name": {
"message": "Tartalomszolgáltató hálózatok (CDN)"
},
"servicesgroup.dating.name": {
"message": "Társkereső szolgáltatások"
},
"servicesgroup.gambling.name": {
"message": "Szerencsejáték és fogadás"
},
"servicesgroup.gaming.name": {
"message": "Játék"
},
"servicesgroup.hosting.name": {
"message": "Webtárhely"
},
"servicesgroup.messenger.name": {
"message": "Üzenetküldő szolgáltatások"
},
"servicesgroup.privacy.name": {
"message": "Adatvédelmi eszközök"
},
"servicesgroup.shopping.name": {
"message": "Vásárlás"
},
"servicesgroup.social_network.name": {
"message": "Közösségi háló"
},
"servicesgroup.software.name": {
"message": "Szoftverfejlesztés"
},
"servicesgroup.streaming.name": {
"message": "Streaming szolgáltatások"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Kecerdasan buatan",
"servicesgroup.cdn.name": "Jaringan pengiriman konten (CDN)",
"servicesgroup.dating.name": "Layanan kencan",
"servicesgroup.gambling.name": "Perjudian dan taruhan",
"servicesgroup.gaming.name": "Permainan",
"servicesgroup.hosting.name": "Hosting web",
"servicesgroup.messenger.name": "Layanan pesan",
"servicesgroup.privacy.name": "Alat privasi",
"servicesgroup.shopping.name": "Belanja",
"servicesgroup.social_network.name": "Jaringan sosial",
"servicesgroup.software.name": "Pengembangan software",
"servicesgroup.streaming.name": "Layanan siar"
}
"servicesgroup.ai.name": {
"message": "Kecerdasan buatan"
},
"servicesgroup.cdn.name": {
"message": "Jaringan pengiriman konten (CDN)"
},
"servicesgroup.dating.name": {
"message": "Layanan kencan"
},
"servicesgroup.gambling.name": {
"message": "Perjudian dan taruhan"
},
"servicesgroup.gaming.name": {
"message": "Permainan"
},
"servicesgroup.hosting.name": {
"message": "Hosting web"
},
"servicesgroup.messenger.name": {
"message": "Layanan pesan"
},
"servicesgroup.privacy.name": {
"message": "Alat privasi"
},
"servicesgroup.shopping.name": {
"message": "Belanja"
},
"servicesgroup.social_network.name": {
"message": "Jaringan sosial"
},
"servicesgroup.software.name": {
"message": "Pengembangan software"
},
"servicesgroup.streaming.name": {
"message": "Layanan siar"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Intelligenza artificiale",
"servicesgroup.cdn.name": "Reti dedicate alla distribuzione dei contenuti (CDN)",
"servicesgroup.dating.name": "Servizi di incontri",
"servicesgroup.gambling.name": "Giochi d'azzardo e scommesse",
"servicesgroup.gaming.name": "Giochi",
"servicesgroup.hosting.name": "Hosting web",
"servicesgroup.messenger.name": "Servizi di messaggistica",
"servicesgroup.privacy.name": "Strumenti per riservatezza",
"servicesgroup.shopping.name": "Compere",
"servicesgroup.social_network.name": "Reti sociali",
"servicesgroup.software.name": "Sviluppo di programmi",
"servicesgroup.streaming.name": "Servizi di streaming"
}
"servicesgroup.ai.name": {
"message": "Intelligenza artificiale"
},
"servicesgroup.cdn.name": {
"message": "Reti dedicate alla distribuzione dei contenuti (CDN)"
},
"servicesgroup.dating.name": {
"message": "Servizi di incontri"
},
"servicesgroup.gambling.name": {
"message": "Giochi d'azzardo e scommesse"
},
"servicesgroup.gaming.name": {
"message": "Giochi"
},
"servicesgroup.hosting.name": {
"message": "Hosting web"
},
"servicesgroup.messenger.name": {
"message": "Servizi di messaggistica"
},
"servicesgroup.privacy.name": {
"message": "Strumenti per riservatezza"
},
"servicesgroup.shopping.name": {
"message": "Compere"
},
"servicesgroup.social_network.name": {
"message": "Reti sociali"
},
"servicesgroup.software.name": {
"message": "Sviluppo di programmi"
},
"servicesgroup.streaming.name": {
"message": "Servizi di streaming"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "人工知能AI",
"servicesgroup.cdn.name": "コンテンツ配信ネットワークCDN",
"servicesgroup.dating.name": "出会い系サービス",
"servicesgroup.gambling.name": "ギャンブルおよび賭博",
"servicesgroup.gaming.name": "ゲーム",
"servicesgroup.hosting.name": "ウェブホスティング",
"servicesgroup.messenger.name": "メッセージサービス",
"servicesgroup.privacy.name": "プライバシーツール",
"servicesgroup.shopping.name": "ショッピング",
"servicesgroup.social_network.name": "SNS",
"servicesgroup.software.name": "ソフトウェア開発",
"servicesgroup.streaming.name": "ストリーミングサービス"
}
"servicesgroup.ai.name": {
"message": "人工知能AI"
},
"servicesgroup.cdn.name": {
"message": "コンテンツ配信ネットワークCDN"
},
"servicesgroup.dating.name": {
"message": "出会い系サービス"
},
"servicesgroup.gambling.name": {
"message": "ギャンブルおよび賭博"
},
"servicesgroup.gaming.name": {
"message": "ゲーム"
},
"servicesgroup.hosting.name": {
"message": "ウェブホスティング"
},
"servicesgroup.messenger.name": {
"message": "メッセージサービス"
},
"servicesgroup.privacy.name": {
"message": "プライバシーツール"
},
"servicesgroup.shopping.name": {
"message": "ショッピング"
},
"servicesgroup.social_network.name": {
"message": "SNS"
},
"servicesgroup.software.name": {
"message": "ソフトウェア開発"
},
"servicesgroup.streaming.name": {
"message": "ストリーミングサービス"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "인공지능",
"servicesgroup.cdn.name": "콘텐츠 전송 네트워크(CDN)",
"servicesgroup.dating.name": "데이트 서비스",
"servicesgroup.gambling.name": "도박 및 베팅",
"servicesgroup.gaming.name": "게임",
"servicesgroup.hosting.name": "웹 호스팅",
"servicesgroup.messenger.name": "메시징 서비스",
"servicesgroup.privacy.name": "개인정보 보호 도구",
"servicesgroup.shopping.name": "쇼핑",
"servicesgroup.social_network.name": "소셜 네트워크",
"servicesgroup.software.name": "소프트웨어 개발",
"servicesgroup.streaming.name": "스트리밍 서비스"
}
"servicesgroup.ai.name": {
"message": "인공지능"
},
"servicesgroup.cdn.name": {
"message": "콘텐츠 전송 네트워크(CDN)"
},
"servicesgroup.dating.name": {
"message": "데이트 서비스"
},
"servicesgroup.gambling.name": {
"message": "도박 및 베팅"
},
"servicesgroup.gaming.name": {
"message": "게임"
},
"servicesgroup.hosting.name": {
"message": "웹 호스팅"
},
"servicesgroup.messenger.name": {
"message": "메시징 서비스"
},
"servicesgroup.privacy.name": {
"message": "개인정보 보호 도구"
},
"servicesgroup.shopping.name": {
"message": "쇼핑"
},
"servicesgroup.social_network.name": {
"message": "소셜 네트워크"
},
"servicesgroup.software.name": {
"message": "소프트웨어 개발"
},
"servicesgroup.streaming.name": {
"message": "스트리밍 서비스"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Kunstmatige intelligentie",
"servicesgroup.cdn.name": "Content Delivery Networks (CDN)",
"servicesgroup.dating.name": "Datingdiensten",
"servicesgroup.gambling.name": "Gokken en wedden",
"servicesgroup.gaming.name": "Gamen",
"servicesgroup.hosting.name": "Webhosting",
"servicesgroup.messenger.name": "Berichtendiensten",
"servicesgroup.privacy.name": "Privacyhulpmiddelen",
"servicesgroup.shopping.name": "Winkelen",
"servicesgroup.social_network.name": "Sociale netwerken",
"servicesgroup.software.name": "Softwareontwikkeling",
"servicesgroup.streaming.name": "Streamingdiensten"
}
"servicesgroup.ai.name": {
"message": "Kunstmatige intelligentie"
},
"servicesgroup.cdn.name": {
"message": "Content Delivery Networks (CDN)"
},
"servicesgroup.dating.name": {
"message": "Datingdiensten"
},
"servicesgroup.gambling.name": {
"message": "Gokken en wedden"
},
"servicesgroup.gaming.name": {
"message": "Gamen"
},
"servicesgroup.hosting.name": {
"message": "Webhosting"
},
"servicesgroup.messenger.name": {
"message": "Berichtendiensten"
},
"servicesgroup.privacy.name": {
"message": "Privacyhulpmiddelen"
},
"servicesgroup.shopping.name": {
"message": "Winkelen"
},
"servicesgroup.social_network.name": {
"message": "Sociale netwerken"
},
"servicesgroup.software.name": {
"message": "Softwareontwikkeling"
},
"servicesgroup.streaming.name": {
"message": "Streamingdiensten"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Kunstig intelligens",
"servicesgroup.cdn.name": "Nettverk for innholdslevering (CDN)",
"servicesgroup.dating.name": "Datingtjenester",
"servicesgroup.gambling.name": "Gambling og tipping",
"servicesgroup.gaming.name": "Spilling",
"servicesgroup.hosting.name": "Webhotell",
"servicesgroup.messenger.name": "Meldingstjenester",
"servicesgroup.privacy.name": "Personvernverktøy",
"servicesgroup.shopping.name": "Handling",
"servicesgroup.social_network.name": "Sosiale nettverk",
"servicesgroup.software.name": "Programvareutvikling",
"servicesgroup.streaming.name": "Strømmetjenester"
}
"servicesgroup.ai.name": {
"message": "Kunstig intelligens"
},
"servicesgroup.cdn.name": {
"message": "Nettverk for innholdslevering (CDN)"
},
"servicesgroup.dating.name": {
"message": "Datingtjenester"
},
"servicesgroup.gambling.name": {
"message": "Gambling og tipping"
},
"servicesgroup.gaming.name": {
"message": "Spilling"
},
"servicesgroup.hosting.name": {
"message": "Webhotell"
},
"servicesgroup.messenger.name": {
"message": "Meldingstjenester"
},
"servicesgroup.privacy.name": {
"message": "Personvernverktøy"
},
"servicesgroup.shopping.name": {
"message": "Handling"
},
"servicesgroup.social_network.name": {
"message": "Sosiale nettverk"
},
"servicesgroup.software.name": {
"message": "Programvareutvikling"
},
"servicesgroup.streaming.name": {
"message": "Strømmetjenester"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Sztuczna inteligencja",
"servicesgroup.cdn.name": "Sieci dostarczania treści (CDN)",
"servicesgroup.dating.name": "Serwisy randkowe",
"servicesgroup.gambling.name": "Hazard i zakłady",
"servicesgroup.gaming.name": "Gier",
"servicesgroup.hosting.name": "Hosting web",
"servicesgroup.messenger.name": "Usługi przesyłania wiadomości",
"servicesgroup.privacy.name": "Narzędzia prywatności",
"servicesgroup.shopping.name": "Zakupy",
"servicesgroup.social_network.name": "Portale społecznościowe",
"servicesgroup.software.name": "Rozwój oprogramowania",
"servicesgroup.streaming.name": "Serwisy streamingowe"
}
"servicesgroup.ai.name": {
"message": "Sztuczna inteligencja"
},
"servicesgroup.cdn.name": {
"message": "Sieci dostarczania treści (CDN)"
},
"servicesgroup.dating.name": {
"message": "Serwisy randkowe"
},
"servicesgroup.gambling.name": {
"message": "Hazard i zakłady"
},
"servicesgroup.gaming.name": {
"message": "Gier"
},
"servicesgroup.hosting.name": {
"message": "Hosting web"
},
"servicesgroup.messenger.name": {
"message": "Usługi przesyłania wiadomości"
},
"servicesgroup.privacy.name": {
"message": "Narzędzia prywatności"
},
"servicesgroup.shopping.name": {
"message": "Zakupy"
},
"servicesgroup.social_network.name": {
"message": "Portale społecznościowe"
},
"servicesgroup.software.name": {
"message": "Rozwój oprogramowania"
},
"servicesgroup.streaming.name": {
"message": "Serwisy streamingowe"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Inteligência artificial",
"servicesgroup.cdn.name": "Redes de entrega de conteúdo (CDN)",
"servicesgroup.dating.name": "Serviços de namoro",
"servicesgroup.gambling.name": "Jogos de azar e apostas",
"servicesgroup.gaming.name": "Jogos digitais",
"servicesgroup.hosting.name": "Hospedagem web",
"servicesgroup.messenger.name": "Serviços de mensagens",
"servicesgroup.privacy.name": "Ferramentas de privacidade",
"servicesgroup.shopping.name": "Compras",
"servicesgroup.social_network.name": "Redes sociais",
"servicesgroup.software.name": "Desenvolvimento de software",
"servicesgroup.streaming.name": "Serviços de streaming"
}
"servicesgroup.ai.name": {
"message": "Inteligência artificial"
},
"servicesgroup.cdn.name": {
"message": "Redes de entrega de conteúdo (CDN)"
},
"servicesgroup.dating.name": {
"message": "Serviços de namoro"
},
"servicesgroup.gambling.name": {
"message": "Jogos de azar e apostas"
},
"servicesgroup.gaming.name": {
"message": "Jogos digitais"
},
"servicesgroup.hosting.name": {
"message": "Hospedagem web"
},
"servicesgroup.messenger.name": {
"message": "Serviços de mensagens"
},
"servicesgroup.privacy.name": {
"message": "Ferramentas de privacidade"
},
"servicesgroup.shopping.name": {
"message": "Compras"
},
"servicesgroup.social_network.name": {
"message": "Redes sociais"
},
"servicesgroup.software.name": {
"message": "Desenvolvimento de software"
},
"servicesgroup.streaming.name": {
"message": "Serviços de streaming"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Inteligência artificial",
"servicesgroup.cdn.name": "Redes de distribuição de conteúdos (CDN)",
"servicesgroup.dating.name": "Serviços de encontros",
"servicesgroup.gambling.name": "Jogos de azar e apostas",
"servicesgroup.gaming.name": "Jogos",
"servicesgroup.hosting.name": "Alojamento web",
"servicesgroup.messenger.name": "Serviços de mensagens",
"servicesgroup.privacy.name": "Ferramentas de privacidade",
"servicesgroup.shopping.name": "Compras",
"servicesgroup.social_network.name": "Redes sociais",
"servicesgroup.software.name": "Desenvolvimento de software",
"servicesgroup.streaming.name": "Serviços de streaming"
}
"servicesgroup.ai.name": {
"message": "Inteligência artificial"
},
"servicesgroup.cdn.name": {
"message": "Redes de distribuição de conteúdos (CDN)"
},
"servicesgroup.dating.name": {
"message": "Serviços de encontros"
},
"servicesgroup.gambling.name": {
"message": "Jogos de azar e apostas"
},
"servicesgroup.gaming.name": {
"message": "Jogos"
},
"servicesgroup.hosting.name": {
"message": "Alojamento web"
},
"servicesgroup.messenger.name": {
"message": "Serviços de mensagens"
},
"servicesgroup.privacy.name": {
"message": "Ferramentas de privacidade"
},
"servicesgroup.shopping.name": {
"message": "Compras"
},
"servicesgroup.social_network.name": {
"message": "Redes sociais"
},
"servicesgroup.software.name": {
"message": "Desenvolvimento de software"
},
"servicesgroup.streaming.name": {
"message": "Serviços de streaming"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Inteligenţă artificială",
"servicesgroup.cdn.name": "Rețele de livrare a conținutului (CDN)",
"servicesgroup.dating.name": "Servicii de întâlniri",
"servicesgroup.gambling.name": "Jocuri de noroc și pariuri",
"servicesgroup.gaming.name": "Jocuri",
"servicesgroup.hosting.name": "Găzduire web",
"servicesgroup.messenger.name": "Servicii de mesagerie",
"servicesgroup.privacy.name": "Instrumente de confidențialitate",
"servicesgroup.shopping.name": "Cumpărături",
"servicesgroup.social_network.name": "Rețele sociale",
"servicesgroup.software.name": "Dezvoltare de program",
"servicesgroup.streaming.name": "Servicii de streaming"
}
"servicesgroup.ai.name": {
"message": "Inteligenţă artificială"
},
"servicesgroup.cdn.name": {
"message": "Rețele de livrare a conținutului (CDN)"
},
"servicesgroup.dating.name": {
"message": "Servicii de întâlniri"
},
"servicesgroup.gambling.name": {
"message": "Jocuri de noroc și pariuri"
},
"servicesgroup.gaming.name": {
"message": "Jocuri"
},
"servicesgroup.hosting.name": {
"message": "Găzduire web"
},
"servicesgroup.messenger.name": {
"message": "Servicii de mesagerie"
},
"servicesgroup.privacy.name": {
"message": "Instrumente de confidențialitate"
},
"servicesgroup.shopping.name": {
"message": "Cumpărături"
},
"servicesgroup.social_network.name": {
"message": "Rețele sociale"
},
"servicesgroup.software.name": {
"message": "Dezvoltare de program"
},
"servicesgroup.streaming.name": {
"message": "Servicii de streaming"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Искусственный интеллект",
"servicesgroup.cdn.name": "Сети доставки контента (CDN)",
"servicesgroup.dating.name": "Сервисы знакомств",
"servicesgroup.gambling.name": "Азартные игры и ставки",
"servicesgroup.gaming.name": "Игры",
"servicesgroup.hosting.name": "Веб-хостинг",
"servicesgroup.messenger.name": "Сервисы обмена сообщениями",
"servicesgroup.privacy.name": "Инструменты конфиденциальности",
"servicesgroup.shopping.name": "Шопинг",
"servicesgroup.social_network.name": "Социальные сети",
"servicesgroup.software.name": "Разработка программного обеспечения",
"servicesgroup.streaming.name": "Стриминговые сервисы"
}
"servicesgroup.ai.name": {
"message": "Искусственный интеллект"
},
"servicesgroup.cdn.name": {
"message": "Сети доставки контента (CDN)"
},
"servicesgroup.dating.name": {
"message": "Сервисы знакомств"
},
"servicesgroup.gambling.name": {
"message": "Азартные игры и ставки"
},
"servicesgroup.gaming.name": {
"message": "Игры"
},
"servicesgroup.hosting.name": {
"message": "Веб-хостинг"
},
"servicesgroup.messenger.name": {
"message": "Сервисы обмена сообщениями"
},
"servicesgroup.privacy.name": {
"message": "Инструменты конфиденциальности"
},
"servicesgroup.shopping.name": {
"message": "Шопинг"
},
"servicesgroup.social_network.name": {
"message": "Социальные сети"
},
"servicesgroup.software.name": {
"message": "Разработка программного обеспечения"
},
"servicesgroup.streaming.name": {
"message": "Стриминговые сервисы"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "කෘතිම බුද්ධිය",
"servicesgroup.cdn.name": "අන්තර්ගත බෙදාහැරීමේ ජාල (CDN)",
"servicesgroup.dating.name": "ආලය සේවා",
"servicesgroup.gambling.name": "සූදුව සහ ඔට්ටු ඇල්ලීම",
"servicesgroup.gaming.name": "ක්‍රීඩා කිරීම",
"servicesgroup.hosting.name": "වෙබ් සත්කාරකත්වය",
"servicesgroup.messenger.name": "පණිවිඩ සේවා",
"servicesgroup.privacy.name": "රහස්‍යතා මෙවලම්",
"servicesgroup.shopping.name": "සාප්පුයාම",
"servicesgroup.social_network.name": "සමාජ ජාල",
"servicesgroup.software.name": "මෘදුකාංග සංවර්ධනය",
"servicesgroup.streaming.name": "ප්‍රවාහ සේවා"
}
"servicesgroup.ai.name": {
"message": "කෘතිම බුද්ධිය"
},
"servicesgroup.cdn.name": {
"message": "අන්තර්ගත බෙදාහැරීමේ ජාල (CDN)"
},
"servicesgroup.dating.name": {
"message": "ආලය සේවා"
},
"servicesgroup.gambling.name": {
"message": "සූදුව සහ ඔට්ටු ඇල්ලීම"
},
"servicesgroup.gaming.name": {
"message": "ක්‍රීඩා කිරීම"
},
"servicesgroup.hosting.name": {
"message": "වෙබ් සත්කාරකත්වය"
},
"servicesgroup.messenger.name": {
"message": "පණිවිඩ සේවා"
},
"servicesgroup.privacy.name": {
"message": "රහස්‍යතා මෙවලම්"
},
"servicesgroup.shopping.name": {
"message": "සාප්පුයාම"
},
"servicesgroup.social_network.name": {
"message": "සමාජ ජාල"
},
"servicesgroup.software.name": {
"message": "මෘදුකාංග සංවර්ධනය"
},
"servicesgroup.streaming.name": {
"message": "ප්‍රවාහ සේවා"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Umelá inteligencia",
"servicesgroup.cdn.name": "Siete na doručovanie obsahu (CDN)",
"servicesgroup.dating.name": "Zoznamovacie služby",
"servicesgroup.gambling.name": "Hazardné hry a stávkovanie",
"servicesgroup.gaming.name": "Hranie hier",
"servicesgroup.hosting.name": "Webhosting",
"servicesgroup.messenger.name": "Služby zasielania správ",
"servicesgroup.privacy.name": "Nástroje na ochranu súkromia",
"servicesgroup.shopping.name": "Nakupovanie",
"servicesgroup.social_network.name": "Sociálne siete",
"servicesgroup.software.name": "Vývoj softvéru",
"servicesgroup.streaming.name": "Streamovacie služby"
}
"servicesgroup.ai.name": {
"message": "Umelá inteligencia"
},
"servicesgroup.cdn.name": {
"message": "Siete na doručovanie obsahu (CDN)"
},
"servicesgroup.dating.name": {
"message": "Zoznamovacie služby"
},
"servicesgroup.gambling.name": {
"message": "Hazardné hry a stávkovanie"
},
"servicesgroup.gaming.name": {
"message": "Hranie hier"
},
"servicesgroup.hosting.name": {
"message": "Webhosting"
},
"servicesgroup.messenger.name": {
"message": "Služby zasielania správ"
},
"servicesgroup.privacy.name": {
"message": "Nástroje na ochranu súkromia"
},
"servicesgroup.shopping.name": {
"message": "Nakupovanie"
},
"servicesgroup.social_network.name": {
"message": "Sociálne siete"
},
"servicesgroup.software.name": {
"message": "Vývoj softvéru"
},
"servicesgroup.streaming.name": {
"message": "Streamovacie služby"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Umetna inteligenca",
"servicesgroup.cdn.name": "Omrežja za dostavo vsebin (CDN)",
"servicesgroup.dating.name": "Storitve za zmenke",
"servicesgroup.gambling.name": "Igre na srečo in stave",
"servicesgroup.gaming.name": "Igre",
"servicesgroup.hosting.name": "Spletno gostovanje",
"servicesgroup.messenger.name": "Storitve sporočanja",
"servicesgroup.privacy.name": "Orodja za zasebnost",
"servicesgroup.shopping.name": "Nakupi",
"servicesgroup.social_network.name": "Družbeno omrežje",
"servicesgroup.software.name": "Razvoj programske opreme",
"servicesgroup.streaming.name": "Storitve pretakanja"
}
"servicesgroup.ai.name": {
"message": "Umetna inteligenca"
},
"servicesgroup.cdn.name": {
"message": "Omrežja za dostavo vsebin (CDN)"
},
"servicesgroup.dating.name": {
"message": "Storitve za zmenke"
},
"servicesgroup.gambling.name": {
"message": "Igre na srečo in stave"
},
"servicesgroup.gaming.name": {
"message": "Igre"
},
"servicesgroup.hosting.name": {
"message": "Spletno gostovanje"
},
"servicesgroup.messenger.name": {
"message": "Storitve sporočanja"
},
"servicesgroup.privacy.name": {
"message": "Orodja za zasebnost"
},
"servicesgroup.shopping.name": {
"message": "Nakupi"
},
"servicesgroup.social_network.name": {
"message": "Družbeno omrežje"
},
"servicesgroup.software.name": {
"message": "Razvoj programske opreme"
},
"servicesgroup.streaming.name": {
"message": "Storitve pretakanja"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Veštačka inteligencija",
"servicesgroup.cdn.name": "Mreže za isporuku sadržaja (CDN)",
"servicesgroup.dating.name": "Servisi za upoznavanje",
"servicesgroup.gambling.name": "Kockanje i klađenje",
"servicesgroup.gaming.name": "Igre",
"servicesgroup.hosting.name": "Veb hosting",
"servicesgroup.messenger.name": "Servisi za razmenu poruka",
"servicesgroup.privacy.name": "Alati za privatnost",
"servicesgroup.shopping.name": "Kupovina",
"servicesgroup.social_network.name": "Društvene mreže",
"servicesgroup.software.name": "Razvoj softvera",
"servicesgroup.streaming.name": "Streaming servisi"
}
"servicesgroup.ai.name": {
"message": "Veštačka inteligencija"
},
"servicesgroup.cdn.name": {
"message": "Mreže za isporuku sadržaja (CDN)"
},
"servicesgroup.dating.name": {
"message": "Servisi za upoznavanje"
},
"servicesgroup.gambling.name": {
"message": "Kockanje i klađenje"
},
"servicesgroup.gaming.name": {
"message": "Igre"
},
"servicesgroup.hosting.name": {
"message": "Veb hosting"
},
"servicesgroup.messenger.name": {
"message": "Servisi za razmenu poruka"
},
"servicesgroup.privacy.name": {
"message": "Alati za privatnost"
},
"servicesgroup.shopping.name": {
"message": "Kupovina"
},
"servicesgroup.social_network.name": {
"message": "Društvene mreže"
},
"servicesgroup.software.name": {
"message": "Razvoj softvera"
},
"servicesgroup.streaming.name": {
"message": "Streaming servisi"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Artificiell intelligens",
"servicesgroup.cdn.name": "Innehållsleveransnätverk (CDN)",
"servicesgroup.dating.name": "Dejtingtjänster",
"servicesgroup.gambling.name": "Spel och vadslagning",
"servicesgroup.gaming.name": "Gaming",
"servicesgroup.hosting.name": "Webbhotell",
"servicesgroup.messenger.name": "Meddelandetjänster",
"servicesgroup.privacy.name": "Integritetsverktyg",
"servicesgroup.shopping.name": "Shopping",
"servicesgroup.social_network.name": "Sociala nätverk",
"servicesgroup.software.name": "Programvaruutveckling",
"servicesgroup.streaming.name": "Streamingtjänster"
}
"servicesgroup.ai.name": {
"message": "Artificiell intelligens"
},
"servicesgroup.cdn.name": {
"message": "Innehållsleveransnätverk (CDN)"
},
"servicesgroup.dating.name": {
"message": "Dejtingtjänster"
},
"servicesgroup.gambling.name": {
"message": "Spel och vadslagning"
},
"servicesgroup.gaming.name": {
"message": "Gaming"
},
"servicesgroup.hosting.name": {
"message": "Webbhotell"
},
"servicesgroup.messenger.name": {
"message": "Meddelandetjänster"
},
"servicesgroup.privacy.name": {
"message": "Integritetsverktyg"
},
"servicesgroup.shopping.name": {
"message": "Shopping"
},
"servicesgroup.social_network.name": {
"message": "Sociala nätverk"
},
"servicesgroup.software.name": {
"message": "Programvaruutveckling"
},
"servicesgroup.streaming.name": {
"message": "Streamingtjänster"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "ปัญญาประดิษฐ์",
"servicesgroup.cdn.name": "เครือข่ายการจัดส่งเนื้อหา (CDN)",
"servicesgroup.dating.name": "บริการหาคู่",
"servicesgroup.gambling.name": "การพนันและการเดิมพัน",
"servicesgroup.gaming.name": "การเล่นเกม",
"servicesgroup.hosting.name": "เว็บโฮสติ้ง",
"servicesgroup.messenger.name": "บริการส่งข้อความ",
"servicesgroup.privacy.name": "เครื่องมือความเป็นส่วนตัว",
"servicesgroup.shopping.name": "ช้อปปิ้ง",
"servicesgroup.social_network.name": "สังคมออนไลน์",
"servicesgroup.software.name": "การพัฒนาซอฟต์แวร์",
"servicesgroup.streaming.name": "บริการสตรีมมิ่ง"
}
"servicesgroup.ai.name": {
"message": "ปัญญาประดิษฐ์"
},
"servicesgroup.cdn.name": {
"message": "เครือข่ายการจัดส่งเนื้อหา (CDN)"
},
"servicesgroup.dating.name": {
"message": "บริการหาคู่"
},
"servicesgroup.gambling.name": {
"message": "การพนันและการเดิมพัน"
},
"servicesgroup.gaming.name": {
"message": "การเล่นเกม"
},
"servicesgroup.hosting.name": {
"message": "เว็บโฮสติ้ง"
},
"servicesgroup.messenger.name": {
"message": "บริการส่งข้อความ"
},
"servicesgroup.privacy.name": {
"message": "เครื่องมือความเป็นส่วนตัว"
},
"servicesgroup.shopping.name": {
"message": "ช้อปปิ้ง"
},
"servicesgroup.social_network.name": {
"message": "สังคมออนไลน์"
},
"servicesgroup.software.name": {
"message": "การพัฒนาซอฟต์แวร์"
},
"servicesgroup.streaming.name": {
"message": "บริการสตรีมมิ่ง"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Yapay zekâ",
"servicesgroup.cdn.name": "İçerik dağıtım ağları (CDN)",
"servicesgroup.dating.name": "Flört hizmetleri",
"servicesgroup.gambling.name": "Kumar ve bahis",
"servicesgroup.gaming.name": "Oyun",
"servicesgroup.hosting.name": "Web barındırma",
"servicesgroup.messenger.name": "Mesajlaşma hizmetleri",
"servicesgroup.privacy.name": "Gizlilik araçları",
"servicesgroup.shopping.name": "Alışveriş",
"servicesgroup.social_network.name": "Sosyal ağlar",
"servicesgroup.software.name": "Yazılım geliştirme",
"servicesgroup.streaming.name": "Canlı yayın akışı hizmetleri"
}
"servicesgroup.ai.name": {
"message": "Yapay zekâ"
},
"servicesgroup.cdn.name": {
"message": "İçerik dağıtım ağları (CDN)"
},
"servicesgroup.dating.name": {
"message": "Flört hizmetleri"
},
"servicesgroup.gambling.name": {
"message": "Kumar ve bahis"
},
"servicesgroup.gaming.name": {
"message": "Oyun"
},
"servicesgroup.hosting.name": {
"message": "Web barındırma"
},
"servicesgroup.messenger.name": {
"message": "Mesajlaşma hizmetleri"
},
"servicesgroup.privacy.name": {
"message": "Gizlilik araçları"
},
"servicesgroup.shopping.name": {
"message": "Alışveriş"
},
"servicesgroup.social_network.name": {
"message": "Sosyal ağlar"
},
"servicesgroup.software.name": {
"message": "Yazılım geliştirme"
},
"servicesgroup.streaming.name": {
"message": "Canlı yayın akışı hizmetleri"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Штучний інтелект",
"servicesgroup.cdn.name": "Мережі доставки контенту (CDN)",
"servicesgroup.dating.name": "Сервіси знайомств",
"servicesgroup.gambling.name": "Азартні ігри та ставки",
"servicesgroup.gaming.name": "Геймінг",
"servicesgroup.hosting.name": "Вебхостинг",
"servicesgroup.messenger.name": "Сервіси обміну повідомленнями",
"servicesgroup.privacy.name": "Інструменти конфіденційності",
"servicesgroup.shopping.name": "Магазини",
"servicesgroup.social_network.name": "Соціальні мережі",
"servicesgroup.software.name": "Розробка програмного забезпечення",
"servicesgroup.streaming.name": "Стримінги"
}
"servicesgroup.ai.name": {
"message": "Штучний інтелект"
},
"servicesgroup.cdn.name": {
"message": "Мережі доставки контенту (CDN)"
},
"servicesgroup.dating.name": {
"message": "Сервіси знайомств"
},
"servicesgroup.gambling.name": {
"message": "Азартні ігри та ставки"
},
"servicesgroup.gaming.name": {
"message": "Геймінг"
},
"servicesgroup.hosting.name": {
"message": "Вебхостинг"
},
"servicesgroup.messenger.name": {
"message": "Сервіси обміну повідомленнями"
},
"servicesgroup.privacy.name": {
"message": "Інструменти конфіденційності"
},
"servicesgroup.shopping.name": {
"message": "Магазини"
},
"servicesgroup.social_network.name": {
"message": "Соціальні мережі"
},
"servicesgroup.software.name": {
"message": "Розробка програмного забезпечення"
},
"servicesgroup.streaming.name": {
"message": "Стримінги"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "Trí tuệ nhân tạo",
"servicesgroup.cdn.name": "Mạng phân phối nội dung (CDN)",
"servicesgroup.dating.name": "Dịch vụ hẹn hò",
"servicesgroup.gambling.name": "Cờ bạc và cá cược",
"servicesgroup.gaming.name": "Chơi game",
"servicesgroup.hosting.name": "Lưu trữ web",
"servicesgroup.messenger.name": "Dịch vụ nhắn tin",
"servicesgroup.privacy.name": "Công cụ bảo mật",
"servicesgroup.shopping.name": "Mua sắm",
"servicesgroup.social_network.name": "Mạng xã hội",
"servicesgroup.software.name": "Phát triển phần mềm",
"servicesgroup.streaming.name": "Dịch vụ phát trực tuyến"
}
"servicesgroup.ai.name": {
"message": "Trí tuệ nhân tạo"
},
"servicesgroup.cdn.name": {
"message": "Mạng phân phối nội dung (CDN)"
},
"servicesgroup.dating.name": {
"message": "Dịch vụ hẹn hò"
},
"servicesgroup.gambling.name": {
"message": "Cờ bạc và cá cược"
},
"servicesgroup.gaming.name": {
"message": "Chơi game"
},
"servicesgroup.hosting.name": {
"message": "Lưu trữ web"
},
"servicesgroup.messenger.name": {
"message": "Dịch vụ nhắn tin"
},
"servicesgroup.privacy.name": {
"message": "Công cụ bảo mật"
},
"servicesgroup.shopping.name": {
"message": "Mua sắm"
},
"servicesgroup.social_network.name": {
"message": "Mạng xã hội"
},
"servicesgroup.software.name": {
"message": "Phát triển phần mềm"
},
"servicesgroup.streaming.name": {
"message": "Dịch vụ phát trực tuyến"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "人工智能",
"servicesgroup.cdn.name": "内容分发网络CDN",
"servicesgroup.dating.name": "交友服务",
"servicesgroup.gambling.name": "赌博和博彩",
"servicesgroup.gaming.name": "游戏",
"servicesgroup.hosting.name": "网站托管",
"servicesgroup.messenger.name": "消息服务",
"servicesgroup.privacy.name": "隐私工具",
"servicesgroup.shopping.name": "购物",
"servicesgroup.social_network.name": "社交网络",
"servicesgroup.software.name": "软件开发",
"servicesgroup.streaming.name": "串流服务"
}
"servicesgroup.ai.name": {
"message": "人工智能"
},
"servicesgroup.cdn.name": {
"message": "内容分发网络CDN"
},
"servicesgroup.dating.name": {
"message": "交友服务"
},
"servicesgroup.gambling.name": {
"message": "赌博和博彩"
},
"servicesgroup.gaming.name": {
"message": "游戏"
},
"servicesgroup.hosting.name": {
"message": "网站托管"
},
"servicesgroup.messenger.name": {
"message": "消息服务"
},
"servicesgroup.privacy.name": {
"message": "隐私工具"
},
"servicesgroup.shopping.name": {
"message": "购物"
},
"servicesgroup.social_network.name": {
"message": "社交网络"
},
"servicesgroup.software.name": {
"message": "软件开发"
},
"servicesgroup.streaming.name": {
"message": "串流服务"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "人工智能",
"servicesgroup.cdn.name": "內容傳遞網路 (CDN)",
"servicesgroup.dating.name": "約會服務",
"servicesgroup.gambling.name": "賭博和投注",
"servicesgroup.gaming.name": "遊戲",
"servicesgroup.hosting.name": "網頁寄存",
"servicesgroup.messenger.name": "訊息傳送服務",
"servicesgroup.privacy.name": "隱私權工具",
"servicesgroup.shopping.name": "購物",
"servicesgroup.social_network.name": "社交媒體",
"servicesgroup.software.name": "軟體開發",
"servicesgroup.streaming.name": "串流服務"
}
"servicesgroup.ai.name": {
"message": "人工智能"
},
"servicesgroup.cdn.name": {
"message": "內容傳遞網路 (CDN)"
},
"servicesgroup.dating.name": {
"message": "約會服務"
},
"servicesgroup.gambling.name": {
"message": "賭博和投注"
},
"servicesgroup.gaming.name": {
"message": "遊戲"
},
"servicesgroup.hosting.name": {
"message": "網頁寄存"
},
"servicesgroup.messenger.name": {
"message": "訊息傳送服務"
},
"servicesgroup.privacy.name": {
"message": "隱私權工具"
},
"servicesgroup.shopping.name": {
"message": "購物"
},
"servicesgroup.social_network.name": {
"message": "社交媒體"
},
"servicesgroup.software.name": {
"message": "軟體開發"
},
"servicesgroup.streaming.name": {
"message": "串流服務"
}
}

View File

@@ -1,14 +1,38 @@
{
"servicesgroup.ai.name": "人工智慧",
"servicesgroup.cdn.name": "內容傳遞網路CDN",
"servicesgroup.dating.name": "約會服務",
"servicesgroup.gambling.name": "博弈與賭博",
"servicesgroup.gaming.name": "遊戲",
"servicesgroup.hosting.name": "Web 主機服務",
"servicesgroup.messenger.name": "訊息服務",
"servicesgroup.privacy.name": "隱私工具",
"servicesgroup.shopping.name": "購物",
"servicesgroup.social_network.name": "社群網路",
"servicesgroup.software.name": "軟體開發",
"servicesgroup.streaming.name": "串流服務"
}
"servicesgroup.ai.name": {
"message": "人工智慧"
},
"servicesgroup.cdn.name": {
"message": "內容傳遞網路CDN"
},
"servicesgroup.dating.name": {
"message": "約會服務"
},
"servicesgroup.gambling.name": {
"message": "博弈與賭博"
},
"servicesgroup.gaming.name": {
"message": "遊戲"
},
"servicesgroup.hosting.name": {
"message": "Web 主機服務"
},
"servicesgroup.messenger.name": {
"message": "訊息服務"
},
"servicesgroup.privacy.name": {
"message": "隱私工具"
},
"servicesgroup.shopping.name": {
"message": "購物"
},
"servicesgroup.social_network.name": {
"message": "社群網路"
},
"servicesgroup.software.name": {
"message": "軟體開發"
},
"servicesgroup.streaming.name": {
"message": "串流服務"
}
}

View File

@@ -1,6 +1,7 @@
package main
import (
"bytes"
"context"
"flag"
"fmt"
@@ -17,6 +18,7 @@ import (
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/ioutil"
"github.com/AdguardTeam/golibs/logutil/slogutil"
"github.com/AdguardTeam/golibs/netutil"
"github.com/AdguardTeam/golibs/syncutil"
)
@@ -43,7 +45,7 @@ func (c *twoskyClient) download(ctx context.Context, l *slog.Logger) (err error)
downloadURI := c.uri.JoinPath("download")
wg := &sync.WaitGroup{}
uriCh := make(chan *url.URL, len(c.langs))
reqCh := make(chan downloadRequest, numWorker)
dw := &downloadWorker{
ctx: ctx,
@@ -52,20 +54,28 @@ func (c *twoskyClient) download(ctx context.Context, l *slog.Logger) (err error)
client: &http.Client{
Timeout: 10 * time.Second,
},
uriCh: uriCh,
reqCh: reqCh,
}
for range numWorker {
wg.Go(dw.run)
}
for _, lang := range c.langs {
uri := translationURL(downloadURI, defaultBaseFile, c.projectID, lang)
for _, baseFile := range c.localizableFiles {
file := filepath.Base(baseFile)
dir := filepath.Dir(baseFile)
uriCh <- uri
for _, lang := range c.langs {
uri := translationURL(downloadURI, file, c.projectID, lang)
reqCh <- downloadRequest{
uri: uri,
dir: dir,
}
}
}
close(uriCh)
close(reqCh)
wg.Wait()
printFailedLocales(ctx, l, dw.failed)
@@ -102,17 +112,24 @@ type downloadWorker struct {
l *slog.Logger
failed *syncutil.Map[string, struct{}]
client *http.Client
uriCh <-chan *url.URL
reqCh <-chan downloadRequest
}
// downloadRequest is a request to download a translation. All fields must not
// be empty.
type downloadRequest struct {
uri *url.URL
dir string
}
// run handles the channel of URLs, one by one. It returns when the channel is
// closed. It's used to be run in a separate goroutine.
func (w *downloadWorker) run() {
for uri := range w.uriCh {
q := uri.Query()
for req := range w.reqCh {
q := req.uri.Query()
code := q.Get("language")
err := saveToFile(w.ctx, w.l, w.client, uri, code)
err := saveToFile(w.ctx, w.l, w.client, req.uri, code, req.dir)
if err != nil {
w.l.ErrorContext(w.ctx, "download worker", slogutil.KeyError, err)
w.failed.Store(code, struct{}{})
@@ -120,6 +137,9 @@ func (w *downloadWorker) run() {
}
}
// newLineSuffix is the suffix required for each text file.
var newLineSuffix = []byte("\n")
// saveToFile downloads translation by url and saves it to a file, or returns
// error.
func saveToFile(
@@ -128,12 +148,17 @@ func saveToFile(
client *http.Client,
uri *url.URL,
code string,
localesDir string,
) (err error) {
data, err := getTranslation(ctx, l, client, uri.String())
if err != nil {
return fmt.Errorf("getting translation %q: %s", code, err)
}
if !bytes.HasSuffix(data, newLineSuffix) {
data = append(data, newLineSuffix...)
}
name := filepath.Join(localesDir, code+".json")
err = os.WriteFile(name, data, 0o664)
if err != nil {
@@ -174,9 +199,8 @@ func getTranslation(
}
// translationURL returns a new url.URL with provided query parameters.
func translationURL(oldURL *url.URL, baseFile, projectID string, lang langCode) (uri *url.URL) {
uri = &url.URL{}
*uri = *oldURL
func translationURL(baseURL *url.URL, baseFile, projectID string, lang langCode) (uri *url.URL) {
uri = netutil.CloneURL(baseURL)
q := uri.Query()
q.Set("format", "json")

View File

@@ -5,13 +5,11 @@ package main
import (
"bufio"
"bytes"
"cmp"
"context"
"encoding/json"
"fmt"
"log/slog"
"maps"
"net/url"
"os"
"path/filepath"
"slices"
@@ -77,26 +75,28 @@ func main() {
usage("")
}
conf := errors.Must(readTwoskyConfig())
homeConf, servicesConf, err := readTwoskyConfig()
errors.Check(err)
var cli *twoskyClient
switch os.Args[1] {
case "summary":
errors.Check(summary(conf.Languages))
errors.Check(summary(homeConf.Languages))
case "download":
cli = errors.Must(conf.toClient())
cli = errors.Must(homeConf.toClient())
errors.Check(cli.download(ctx, l))
cli = errors.Must(servicesConf.toClient())
errors.Check(cli.download(ctx, l))
case "unused":
err := unused(ctx, l, conf.LocalizableFiles[0])
err := unused(ctx, l, homeConf.LocalizableFiles[0])
errors.Check(err)
case "upload":
cli = errors.Must(conf.toClient())
cli = errors.Must(homeConf.toClient())
errors.Check(cli.upload())
case "auto-add":
err := autoAdd(ctx, l, conf.LocalizableFiles[0])
err := autoAdd(ctx, l, homeConf.LocalizableFiles[0])
errors.Check(err)
default:
usage("unknown command")
@@ -133,107 +133,6 @@ Commands:
os.Exit(osutil.ExitCodeSuccess)
}
// twoskyConfig is the configuration structure for localization.
type twoskyConfig struct {
Languages languages `json:"languages"`
ProjectID string `json:"project_id"`
BaseLangcode langCode `json:"base_locale"`
LocalizableFiles []string `json:"localizable_files"`
}
// readTwoskyConfig returns twosky configuration.
func readTwoskyConfig() (t *twoskyConfig, err error) {
defer func() { err = errors.Annotate(err, "parsing twosky config: %w") }()
b, err := os.ReadFile(twoskyConfFile)
if err != nil {
// Don't wrap the error since it's informative enough as is.
return nil, err
}
var tsc []twoskyConfig
err = json.Unmarshal(b, &tsc)
if err != nil {
return nil, fmt.Errorf("unmarshalling %q: %w", twoskyConfFile, err)
}
if len(tsc) == 0 {
return nil, fmt.Errorf("%q is empty", twoskyConfFile)
}
conf := tsc[0]
for _, lang := range conf.Languages {
if lang == "" {
return nil, errors.Error("language is empty")
}
}
if len(conf.LocalizableFiles) == 0 {
return nil, errors.Error("no localizable files specified")
}
return &conf, nil
}
// twoskyClient is the twosky client with methods for download and upload
// translations.
type twoskyClient struct {
// uri is the base URL.
uri *url.URL
// projectID is the name of the project.
projectID string
// baseLang is the base language code.
baseLang langCode
// langs is the list of codes of languages to download.
langs []langCode
}
// toClient reads values from environment variables or defaults, validates
// them, and returns the twosky client.
func (t *twoskyConfig) toClient() (cli *twoskyClient, err error) {
defer func() { err = errors.Annotate(err, "filling config: %w") }()
uriStr := cmp.Or(os.Getenv("TWOSKY_URI"), twoskyURI)
uri, err := url.Parse(uriStr)
if err != nil {
return nil, err
}
projectID := cmp.Or(os.Getenv("TWOSKY_PROJECT_ID"), defaultProjectID)
baseLang := t.BaseLangcode
uLangStr := os.Getenv("UPLOAD_LANGUAGE")
if uLangStr != "" {
baseLang = langCode(uLangStr)
}
langs := slices.Sorted(maps.Keys(t.Languages))
dlLangStr := os.Getenv("DOWNLOAD_LANGUAGES")
if dlLangStr == "blocker" {
langs = blockerLangCodes
} else if dlLangStr != "" {
var dlLangs []langCode
dlLangs, err = validateLanguageStr(dlLangStr, t.Languages)
if err != nil {
return nil, err
}
langs = dlLangs
}
return &twoskyClient{
uri: uri,
projectID: projectID,
baseLang: baseLang,
langs: langs,
}, nil
}
// validateLanguageStr validates languages codes that contain in the str and
// returns them or error.
func validateLanguageStr(str string, all languages) (langs []langCode, err error) {

View File

@@ -0,0 +1,169 @@
package main
import (
"cmp"
"encoding/json"
"fmt"
"maps"
"net/url"
"os"
"path/filepath"
"slices"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/validate"
)
const (
// twoskyProjectIdxHome is the index of the Home project in the localization
// configuration.
twoskyProjectIdxHome = 0
// twoskyProjectIdxServices is the index of the Services project in the
// localization configuration.
twoskyProjectIdxServices = 1
// twoskyProjectCount is the number of projects in the localization
// configuration.
twoskyProjectCount = 2
)
// twoskyConfig is the configuration structure for localization of a single
// project.
type twoskyConfig struct {
Languages languages `json:"languages"`
ProjectID string `json:"project_id"`
BaseLangcode langCode `json:"base_locale"`
LocalizableFiles []string `json:"localizable_files"`
}
// type check
var _ validate.Interface = (*twoskyConfig)(nil)
// Validate implements the [validate.Interface] interface for *twoskyConfig.
func (t *twoskyConfig) Validate() (err error) {
if t == nil {
return errors.ErrNoValue
}
errs := []error{
validate.NotEmpty("project_id", t.ProjectID),
validate.NotEmpty("base_locale", t.BaseLangcode),
validate.NotEmptySlice("localizable_files", t.LocalizableFiles),
}
if len(t.Languages) == 0 {
errs = append(errs, fmt.Errorf("languages: %w", errors.ErrEmptyValue))
}
for code, lang := range t.Languages {
err = validate.NotEmpty("languages: "+string(code), lang)
if err != nil {
errs = append(errs, err)
}
}
return errors.Join(errs...)
}
// readTwoskyConfig returns twosky configuration.
func readTwoskyConfig() (home, services *twoskyConfig, err error) {
defer func() { err = errors.Annotate(err, "parsing twosky config: %w") }()
b, err := os.ReadFile(twoskyConfFile)
if err != nil {
// Don't wrap the error since it's informative enough as is.
return nil, nil, err
}
var tsc []*twoskyConfig
err = json.Unmarshal(b, &tsc)
if err != nil {
return nil, nil, fmt.Errorf("unmarshalling %q: %w", twoskyConfFile, err)
}
err = validate.Equal("projects count", len(tsc), twoskyProjectCount)
if err != nil {
return nil, nil, err
}
err = errors.Join(validate.AppendSlice(nil, "projects", tsc)...)
if err != nil {
return nil, nil, err
}
return tsc[twoskyProjectIdxHome], tsc[twoskyProjectIdxServices], nil
}
// twoskyClient is the twosky client with methods for download and upload
// translations.
type twoskyClient struct {
// uri is the base URL.
uri *url.URL
// projectID is the name of the project.
projectID string
// baseLang is the base language code.
baseLang langCode
// langs is the list of codes of languages to download.
langs []langCode
// localizableFiles are the files to localize.
localizableFiles []string
}
// toClient reads values from environment variables or defaults, validates
// them, and returns the twosky client.
func (t *twoskyConfig) toClient() (cli *twoskyClient, err error) {
defer func() { err = errors.Annotate(err, "filling config: %w") }()
uriStr := cmp.Or(os.Getenv("TWOSKY_URI"), twoskyURI)
uri, err := url.Parse(uriStr)
if err != nil {
return nil, err
}
projectID := t.ProjectID
envProjectID := os.Getenv("PROJECT_ID")
if envProjectID != "" {
projectID = envProjectID
}
baseLang := t.BaseLangcode
uLangStr := os.Getenv("UPLOAD_LANGUAGE")
if uLangStr != "" {
baseLang = langCode(uLangStr)
}
langs := slices.Sorted(maps.Keys(t.Languages))
dlLangStr := os.Getenv("DOWNLOAD_LANGUAGES")
if dlLangStr == "blocker" {
langs = blockerLangCodes
} else if dlLangStr != "" {
var dlLangs []langCode
dlLangs, err = validateLanguageStr(dlLangStr, t.Languages)
if err != nil {
return nil, err
}
langs = dlLangs
}
localizableFiles := t.LocalizableFiles
if len(localizableFiles) == 0 {
localizableFiles = []string{
filepath.Join(localesDir, defaultBaseFile),
}
}
return &twoskyClient{
uri: uri,
projectID: projectID,
baseLang: baseLang,
langs: langs,
localizableFiles: localizableFiles,
}, nil
}