diff --git a/agents/agent-translations.json b/agents/agent-translations.json
new file mode 100644
index 00000000..44e0f94a
--- /dev/null
+++ b/agents/agent-translations.json
@@ -0,0 +1,263 @@
+{
+ "en": {
+ "agent": "Agent",
+ "agentVersion": "New Agent Version",
+ "group": "Device Group",
+ "url": "Server URL",
+ "meshName": "Mesh Name",
+ "meshId": "Mesh Identifier",
+ "serverId": "Server Identifier",
+ "setup": "Setup",
+ "update": "Update",
+ "install": "Install",
+ "uninstall": "Uninstall",
+ "connect": "Connect",
+ "disconnect": "Disconnect",
+ "cancel": "Cancel",
+ "pressok": "Press OK to disconnect",
+ "elevation": "Elevated permissions is required to install/uninstall the agent.",
+ "sudo": "Please try again with sudo.",
+ "ctrlc": "Press Ctrl-C to exit.",
+ "commands": "You can run the text version from the command line with the following command(s)",
+ "graphicalerror": "The graphical version of this installer canot run on this system",
+ "zenity": "Try installing/updating Zenity, and run again",
+ "status": [
+ "NOT INSTALLED",
+ "RUNNING",
+ "NOT RUNNING"
+ ],
+ "statusDescription": "Current Agent Status",
+ "description": "Click the buttons below to install or uninstall the mesh agent. When installed, this software runs in the background allowing this computer to be managed and controlled by a remote administrator."
+ },
+ "cs": {
+ "agent": "Agent",
+ "group": "Skupina zařízení",
+ "install": "Instalace",
+ "uninstall": "Odinstalace",
+ "connect": "Připojit",
+ "disconnect": "Odpojit",
+ "cancel": "Storno"
+ },
+ "de": {
+ "agent": "Agent",
+ "group": "Gerätegruppe",
+ "install": "Installieren",
+ "uninstall": "Deinstallation",
+ "connect": "Verbinden",
+ "disconnect": "Trennen",
+ "cancel": "Abbrechen"
+ },
+ "es": {
+ "agent": "Agente",
+ "group": "Grupo de Dispositivos",
+ "install": "Instalar",
+ "uninstall": "Desinstalar",
+ "connect": "Conectar",
+ "disconnect": "Desconectar",
+ "cancel": "Cancelar"
+ },
+ "fi": {
+ "agent": "Agentti",
+ "group": "Laiteryhmä",
+ "install": "Asenna",
+ "uninstall": "Asennuksen poistaminen",
+ "connect": "Yhdistä",
+ "disconnect": "Katkaise yhteys",
+ "cancel": "Peruuta"
+ },
+ "fr": {
+ "agent": "Agent",
+ "group": "Groupe d'appareils",
+ "setup": "Configuration",
+ "install": "Installer",
+ "uninstall": "Désinstaller",
+ "connect": "Se connecter",
+ "disconnect": "Déconnecter",
+ "cancel": "Annuler"
+ },
+ "hi": {
+ "agent": "एजेंट",
+ "group": "डिवाइस समूह",
+ "install": "इंस्टॉल",
+ "uninstall": "स्थापना रद्द करें",
+ "connect": "जुडिये",
+ "disconnect": "डिस्कनेक्ट",
+ "cancel": "रद्द करना"
+ },
+ "ja": {
+ "agent": "エージェント",
+ "group": "デバイスグループ",
+ "install": "インストール",
+ "uninstall": "アンインストール",
+ "connect": "つなぐ",
+ "disconnect": "切断する",
+ "cancel": "キャンセル"
+ },
+ "ko": {
+ "agent": "에이전트",
+ "agentVersion": "새에이전트 버전",
+ "group": "장치 그룹",
+ "url": "서버의 위치",
+ "meshName": "메시의 이름",
+ "meshId": "메시의 식별자",
+ "serverId": "서버의 식별자",
+ "setup": "설정하다",
+ "update": "개조하다",
+ "install": "설치",
+ "uninstall": "설치 제거",
+ "connect": "연결",
+ "disconnect": "연결 해제",
+ "cancel": "취소",
+ "pressok": "연결을 끊으려면 \"OK\"를 누르십시오",
+ "elevation": "관리자 권한은 에이전트 제거 / 설치하는 데 필요",
+ "sudo": "\"sudo\"로 다시 시도하십시오",
+ "ctrlc": "종료하려면 \"Ctrl-C\"를 누르십시오.",
+ "commands": "다음 명령을 사용하여 콘솔에서 텍스트 버전을 실행할 수 있습니다",
+ "graphicalerror": "이 프로그램의 그래픽 버전이 시스템에서 실행할 수 없습니다",
+ "zenity": "\"Zenity\"를 설치 또는 업데이트하고 다시 시도하십시오",
+ "status": [
+ "없다",
+ "운영",
+ "중지됨"
+ ],
+ "statusDescription": "에이전트 상태",
+ "description": "메시 에이전트를 설치 또는 제거하려면 아래 버튼을 클릭하십시오. 이 프로그램은 설치하면 백그라운드에서 실행되므로 원격 관리자가이 컴퓨터를 관리하고 제어 할 수 있습니다."
+ },
+ "nl": {
+ "agent": "Agent",
+ "group": "Apparaat groep",
+ "setup": "Setup",
+ "install": "Installeren",
+ "uninstall": "Deïnstallatie",
+ "connect": "Verbinden",
+ "disconnect": "Verbreken",
+ "cancel": "Annuleren"
+ },
+ "pt": {
+ "agent": "Agente",
+ "group": "Grupo de dispositivos",
+ "install": "Instalar",
+ "uninstall": "Desinstalar",
+ "connect": "Conectar",
+ "disconnect": "Desconectar",
+ "cancel": "Cancelar"
+ },
+ "ru": {
+ "agent": "Агент",
+ "group": "Группа устройства",
+ "install": "Установка",
+ "uninstall": "Удаление",
+ "connect": "Подключиться",
+ "disconnect": "Разъединить",
+ "cancel": "Отмена"
+ },
+ "tr": {
+ "agent": "Ajan",
+ "group": "Cihaz Grubu",
+ "install": "Yüklemek",
+ "uninstall": "Kaldır",
+ "connect": "Bağlan",
+ "disconnect": "Bağlantıyı kes",
+ "cancel": "İptal etmek"
+ },
+ "zh-chs": {
+ "agent": "代理",
+ "group": "设备组",
+ "install": "安装",
+ "uninstall": "卸载",
+ "connect": "连接",
+ "disconnect": "断线",
+ "cancel": "取消"
+ },
+ "zh-cht": {
+ "agent": "代理",
+ "group": "裝置群",
+ "install": "安裝",
+ "uninstall": "卸載",
+ "connect": "連接",
+ "disconnect": "斷線",
+ "cancel": "取消"
+ },
+ "xloc": {
+ "agent": [
+ "agent-translations.json"
+ ],
+ "agentVersion": [
+ "agent-translations.json"
+ ],
+ "group": [
+ "agent-translations.json"
+ ],
+ "url": [
+ "agent-translations.json"
+ ],
+ "meshName": [
+ "agent-translations.json"
+ ],
+ "meshId": [
+ "agent-translations.json"
+ ],
+ "serverId": [
+ "agent-translations.json"
+ ],
+ "setup": [
+ "agent-translations.json"
+ ],
+ "update": [
+ "agent-translations.json"
+ ],
+ "install": [
+ "agent-translations.json"
+ ],
+ "uninstall": [
+ "agent-translations.json"
+ ],
+ "connect": [
+ "agent-translations.json"
+ ],
+ "disconnect": [
+ "agent-translations.json"
+ ],
+ "cancel": [
+ "agent-translations.json"
+ ],
+ "pressok": [
+ "agent-translations.json"
+ ],
+ "elevation": [
+ "agent-translations.json"
+ ],
+ "sudo": [
+ "agent-translations.json"
+ ],
+ "ctrlc": [
+ "agent-translations.json"
+ ],
+ "commands": [
+ "agent-translations.json"
+ ],
+ "graphicalerror": [
+ "agent-translations.json"
+ ],
+ "zenity": [
+ "agent-translations.json"
+ ],
+ "status": [
+ [
+ "agent-translations.json"
+ ],
+ [
+ "agent-translations.json"
+ ],
+ [
+ "agent-translations.json"
+ ]
+ ],
+ "statusDescription": [
+ "agent-translations.json"
+ ],
+ "description": [
+ "agent-translations.json"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/translate/translate.js b/translate/translate.js
index e0115fc0..4dfc42cd 100644
--- a/translate/translate.js
+++ b/translate/translate.js
@@ -49,7 +49,8 @@ var meshCentralSourceFiles = [
"../emails/account-login.txt",
"../emails/account-reset.txt",
"../emails/mesh-invite.txt",
- "../emails/sms-messages.txt"
+ "../emails/sms-messages.txt",
+ '../agents/agent-translations.json'
];
var minifyMeshCentralSourceFiles = [
@@ -577,6 +578,9 @@ function translate(lang, langFile, sources, createSubDir) {
// Single threaded translation
translateSingleThreaded(lang, langFile, sources, createSubDir);
}
+
+ // Translate any JSON files
+ for (var i = 0; i < sources.length; i++) { if (sources[i].endsWith('.json')) { translateAllInJson(lang, langFile, sources[i]); } }
}
function translateSingleThreaded(lang, langFile, sources, createSubDir) {
@@ -627,6 +631,7 @@ function extract(langFile, sources) {
for (var i = 0; i < sources.length; i++) {
if (sources[i].endsWith('.html') || sources[i].endsWith('.htm') || sources[i].endsWith('.handlebars')) { extractFromHtml(sources[i]); }
else if (sources[i].endsWith('.txt')) { extractFromTxt(sources[i]); }
+ else if (sources[i].endsWith('.json')) { extractFromJson(sources[i]); }
}
var count = 0, output = [];
for (var i in sourceStrings) {
@@ -653,6 +658,28 @@ function extractFromTxt(file) {
}
}
+function extractFromJson(file) {
+ log("Processing JSON: " + path.basename(file));
+ var json = JSON.parse(fs.readFileSync(file).toString());
+ var name = path.basename(file);
+ if (json.en == null) return;
+ for (var i in json.en) {
+ if (typeof json.en[i] == 'string') {
+ const str = json.en[i]
+ if (sourceStrings[str] == null) {
+ sourceStrings[str] = { en: str, xloc: [name] };
+ } else { if (sourceStrings[str].xloc == null) { sourceStrings[str].xloc = []; } sourceStrings[str].xloc.push(name); }
+ } else if (Array.isArray(json.en[i])) {
+ for (var k in json.en[i]) {
+ if (typeof json.en[i][k] == 'string') {
+ const str = json.en[i][k];
+ if (sourceStrings[str] == null) { sourceStrings[str] = { en: str, xloc: [name] }; } else { if (sourceStrings[str].xloc == null) { sourceStrings[str].xloc = []; } sourceStrings[str].xloc.push(name); }
+ }
+ }
+ }
+ }
+}
+
function extractFromHtml(file) {
var data = fs.readFileSync(file);
var { JSDOM } = jsdom;
@@ -753,7 +780,53 @@ function translateFromTxt(lang, file, createSubDir) {
fs.writeFileSync(outname, out, { flag: 'w+' });
}
+function translateAllInJson(xlang, langFile, file) {
+ log("Translating JSON (" + ((xlang == null)?'All':xlang) + "): " + path.basename(file));
+ // Load the language file
+ var langFileData = null;
+ try { langFileData = JSON.parse(fs.readFileSync(langFile)); } catch (ex) { console.log(ex); }
+ if ((langFileData == null) || (langFileData.strings == null)) { log("Invalid language file."); process.exit(); return; }
+ var languages = [];
+
+ // Build translation table, simple source->target for the given language.
+ var xtranslationTable = {};
+ for (var i in langFileData.strings) {
+ var entry = langFileData.strings[i];
+ for (var lang in entry) {
+ if (lang == 'en') continue;
+ if ((xlang != null) && (lang != xlang)) continue;
+ if (languages.indexOf(lang) == -1) { languages.push(lang); xtranslationTable[lang] = {}; }
+ if ((entry['en'] != null) && (entry[lang] != null)) { xtranslationTable[lang][entry['en']] = entry[lang]; }
+ }
+ }
+
+ // Load and translate
+ var json = JSON.parse(fs.readFileSync(file).toString());
+ if (json.en != null) {
+ for (var j in languages) {
+ var lang = languages[j];
+ for (var i in json.en) {
+ if ((typeof json.en[i] == 'string') && (xtranslationTable[lang][json.en[i]] != null)) {
+ // Translate a string
+ if (json[lang] == null) { json[lang] = {}; }
+ json[lang][i] = xtranslationTable[lang][json.en[i]];
+ } else if (Array.isArray(json.en[i])) {
+ // Translate an array of strings
+ var r = [], translateCount = 0;
+ for (var k in json.en[i]) {
+ var str = json.en[i][k];
+ if (xtranslationTable[lang][str] != null) { r.push(xtranslationTable[lang][str]); translateCount++; } else { r.push(str); }
+ }
+ if (translateCount > 0) { json[lang][i] = r; }
+ }
+ }
+ }
+ }
+
+ // Save the results
+ fs.writeFileSync(file, JSON.stringify(json, null, 2), { flag: 'w+' });
+}
function translateFromHtml(lang, file, createSubDir) {
var data = fs.readFileSync(file);
diff --git a/translate/translate.json b/translate/translate.json
index 869a2dc3..a34b8fb5 100644
--- a/translate/translate.json
+++ b/translate/translate.json
@@ -4062,6 +4062,7 @@
"zh-chs": "代理",
"zh-cht": "代理",
"xloc": [
+ "agent-translations.json",
"default-mobile.handlebars->9->203",
"default-mobile.handlebars->9->228",
"default-mobile.handlebars->9->250",
@@ -6602,6 +6603,7 @@
"zh-chs": "取消",
"zh-cht": "取消",
"xloc": [
+ "agent-translations.json",
"default-mobile.handlebars->9->82",
"default-mobile.handlebars->dialog->idx_dlgButtonBar",
"default.handlebars->29->1327",
@@ -7780,6 +7782,13 @@
"default.handlebars->29->1278"
]
},
+ {
+ "en": "Click the buttons below to install or uninstall the mesh agent. When installed, this software runs in the background allowing this computer to be managed and controlled by a remote administrator.",
+ "ko": "메시 에이전트를 설치 또는 제거하려면 아래 버튼을 클릭하십시오. 이 프로그램은 설치하면 백그라운드에서 실행되므로 원격 관리자가이 컴퓨터를 관리하고 제어 할 수 있습니다.",
+ "xloc": [
+ "agent-translations.json"
+ ]
+ },
{
"cs": "Klikněte pro zobrazení aktuálních upozornění",
"de": "Hier klicken, um aktuelle Benachrichtigungen anzuzeigen",
@@ -8686,6 +8695,7 @@
"zh-chs": "连接",
"zh-cht": "連接",
"xloc": [
+ "agent-translations.json",
"default-mobile.handlebars->9->301",
"default-mobile.handlebars->container->page_content->column_l->p10->p10desktop->deskarea1->1->3",
"default-mobile.handlebars->container->page_content->column_l->p10->p10files->p13toolbar->1->0->1->3",
@@ -10084,6 +10094,13 @@
"desktop.handlebars->p11->deskarea0->deskarea4->3->deskkeys->19"
]
},
+ {
+ "en": "Current Agent Status",
+ "ko": "에이전트 상태",
+ "xloc": [
+ "agent-translations.json"
+ ]
+ },
{
"cs": "Nainstalovaná verze",
"de": "Aktuelle Version",
@@ -11266,6 +11283,7 @@
"zh-chs": "设备组",
"zh-cht": "裝置群",
"xloc": [
+ "agent-translations.json",
"default.handlebars->29->1454",
"default.handlebars->29->1457",
"default.handlebars->29->1458",
@@ -12111,6 +12129,7 @@
"zh-chs": "断线",
"zh-cht": "斷線",
"xloc": [
+ "agent-translations.json",
"default-mobile.handlebars->9->302",
"default-mobile.handlebars->container->page_content->column_l->p10->p10desktop->deskarea1->1->3",
"default.handlebars->29->1367",
@@ -13809,6 +13828,13 @@
"default.handlebars->29->447"
]
},
+ {
+ "en": "Elevated permissions is required to install/uninstall the agent.",
+ "ko": "관리자 권한은 에이전트 제거 / 설치하는 데 필요",
+ "xloc": [
+ "agent-translations.json"
+ ]
+ },
{
"cs": "E-mail",
"de": "E-Mail",
@@ -18160,7 +18186,10 @@
"ru": "Установка",
"tr": "Yüklemek",
"zh-chs": "安装",
- "zh-cht": "安裝"
+ "zh-cht": "安裝",
+ "xloc": [
+ "agent-translations.json"
+ ]
},
{
"cs": "Nainstalujte si Google Authenticator nebo kompatibilní aplikaci a naskenujte kód, použijte tento odkaz nebo vložte tajemství. Pak vložte aktuální 6 číselný token pro aktivaci 2-faktorového přihlašování.",
@@ -22914,6 +22943,20 @@
"default.handlebars->29->1473"
]
},
+ {
+ "en": "Mesh Identifier",
+ "ko": "메시의 식별자",
+ "xloc": [
+ "agent-translations.json"
+ ]
+ },
+ {
+ "en": "Mesh Name",
+ "ko": "메시의 이름",
+ "xloc": [
+ "agent-translations.json"
+ ]
+ },
{
"cs": "Mesh předávání (relay)",
"de": "Netzrelais",
@@ -24168,6 +24211,20 @@
"default.handlebars->29->1062"
]
},
+ {
+ "en": "NOT INSTALLED",
+ "ko": "없다",
+ "xloc": [
+ "agent-translations.json"
+ ]
+ },
+ {
+ "en": "NOT RUNNING",
+ "ko": "중지됨",
+ "xloc": [
+ "agent-translations.json"
+ ]
+ },
{
"cs": "Přejděte na níže uvedenou adresu URL, udělejte přístup a zkopírujte kód tokenu zpět.",
"de": "Nagivieren Sie auf die unten stehende URL, gewähren Sie Zugriff und kopieren Sie den Token-Code zurück.",
@@ -24451,6 +24508,13 @@
"default.handlebars->container->column_l->p4->3->1->0->3->3"
]
},
+ {
+ "en": "New Agent Version",
+ "ko": "새에이전트 버전",
+ "xloc": [
+ "agent-translations.json"
+ ]
+ },
{
"cs": "Nová skupina zařízení",
"de": "Neue Gerätegruppe",
@@ -27620,6 +27684,13 @@
"terms.handlebars->container->column_l->3"
]
},
+ {
+ "en": "Please try again with sudo.",
+ "ko": "\"sudo\"로 다시 시도하십시오",
+ "xloc": [
+ "agent-translations.json"
+ ]
+ },
{
"cs": "Počkejte pár minut než dojde k ověření.",
"de": "Bitte warten Sie einige Minuten, um die Bestätigung zu erhalten.",
@@ -28065,6 +28136,20 @@
"default.handlebars->29->2060"
]
},
+ {
+ "en": "Press Ctrl-C to exit.",
+ "ko": "종료하려면 \"Ctrl-C\"를 누르십시오.",
+ "xloc": [
+ "agent-translations.json"
+ ]
+ },
+ {
+ "en": "Press OK to disconnect",
+ "ko": "연결을 끊으려면 \"OK\"를 누르십시오",
+ "xloc": [
+ "agent-translations.json"
+ ]
+ },
{
"cs": "Pro pokračování/pozastavení stiskněte [mezerník].",
"de": "Für Abspielen/Pause [Leertaste] drücken,",
@@ -28658,6 +28743,13 @@
"default.handlebars->29->2124"
]
},
+ {
+ "en": "RUNNING",
+ "ko": "운영",
+ "xloc": [
+ "agent-translations.json"
+ ]
+ },
{
"en": "Randomize password",
"fr": "Randomiser le mot de passe",
@@ -32329,6 +32421,13 @@
"default.handlebars->29->710"
]
},
+ {
+ "en": "Server Identifier",
+ "ko": "서버의 식별자",
+ "xloc": [
+ "agent-translations.json"
+ ]
+ },
{
"cs": "Oprávnění serveru",
"de": "Server-Berechtigungen",
@@ -32470,6 +32569,13 @@
"default.handlebars->29->2145"
]
},
+ {
+ "en": "Server URL",
+ "ko": "서버의 위치",
+ "xloc": [
+ "agent-translations.json"
+ ]
+ },
{
"en": "Server Under Maintenance",
"nl": "Onderhoud aan de server",
@@ -32904,7 +33010,9 @@
"en": "Setup",
"nl": "Setup",
"fr": "Configuration",
+ "ko": "설정하다",
"xloc": [
+ "agent-translations.json",
"default.handlebars->29->1385",
"default.handlebars->29->285"
]
@@ -35956,6 +36064,13 @@
"terms.handlebars->container->column_l->7"
]
},
+ {
+ "en": "The graphical version of this installer canot run on this system",
+ "ko": "이 프로그램의 그래픽 버전이 시스템에서 실행할 수 없습니다",
+ "xloc": [
+ "agent-translations.json"
+ ]
+ },
{
"cs": "Název skupiny zařízení, do které tento počítač patří",
"de": "Der Name der Gerätegruppe zu der dieser Rechner gehört",
@@ -37169,6 +37284,13 @@
"default.handlebars->29->134"
]
},
+ {
+ "en": "Try installing/updating Zenity, and run again",
+ "ko": "\"Zenity\"를 설치 또는 업데이트하고 다시 시도하십시오",
+ "xloc": [
+ "agent-translations.json"
+ ]
+ },
{
"cs": "Tsonga",
"de": "Tsonga",
@@ -37613,6 +37735,7 @@
"zh-chs": "卸载",
"zh-cht": "卸載",
"xloc": [
+ "agent-translations.json",
"default-mobile.handlebars->9->458",
"default.handlebars->29->1515",
"default.handlebars->29->694",
@@ -37987,6 +38110,13 @@
"default.handlebars->29->2154"
]
},
+ {
+ "en": "Update",
+ "ko": "개조하다",
+ "xloc": [
+ "agent-translations.json"
+ ]
+ },
{
"cs": "Nahrát",
"de": "Hochladen",
@@ -40777,6 +40907,13 @@
"default.handlebars->29->132"
]
},
+ {
+ "en": "You can run the text version from the command line with the following command(s)",
+ "ko": "다음 명령을 사용하여 콘솔에서 텍스트 버전을 실행할 수 있습니다",
+ "xloc": [
+ "agent-translations.json"
+ ]
+ },
{
"cs": "Můžete nastavit MeshCentral tak, aby automaticky odesílal zálohu serveru na Disk Google. Začněte zadáním desktopového Google API ClientID a ClientSecret pro váš účet.",
"de": "Sie können MeshCentral so einrichten, dass automatisch eine Serversicherung an Google Drive gesendet wird. Geben Sie zunächst eine Desktop-Google API-Client-ID und ClientSecret für Ihr Konto ein.",